PS PrestaShop Intermediate

LLMs.txt PrestaShop — AI SEO for ChatGPT, Claude & Perplexity

Automatically generates llms.txt and llms-full.txt to expose your PrestaShop catalog to LLMs (ChatGPT, Claude, Perplexity, Gemini).

Updated Module version 1.0.0

Overview

LLMs.txt PrestaShop automatically generates the standard /llms.txt and /llms-full.txt files at the root of your store, following the llmstxt.org specification. These files expose your catalog in a structured way to LLMs (ChatGPT, Claude, Perplexity, Gemini) — think of them as sitemap.xml, but for generative AI.

Key insight: LLMs read these files to understand your store without having to crawl every product page. The better your catalog is exposed, the better it will be cited and recommended in their responses.

Two files, two purposes

  • /llms.txt — Condensed index: title + URL + short description for each entry. Markdown format, usually a few hundred KB.
  • /llms-full.txt — Cleaned full content for every entry. Enriched Markdown, can weigh several MB depending on catalog size. Optional since 1.0.0.

Installation

  1. Upload the ZIP through Modules → Module Manager → Upload a module.
  2. Click Install.
  3. Click Configure to open the dashboard.

On install, the module:

  • Creates 4 SQL tables: cache, custom sections (+ lang + shop), logs.
  • Adds 3 entries to the admin menu under a hidden parent AdminDfLlmsTxtParent.
  • Registers on catalog hooks (product/category/CMS/manufacturer/supplier create/update/delete) to automatically invalidate the cache.
  • Adds a block in PrestaShop’s root .htaccess to serve the files in UTF-8 with the proper headers.
  • Generates a random 32-character cron token.

Configuration

The configuration screen is organised in 5 sections.

1. General

  • Enable module — Global toggle. When disabled, /llms.txt and /llms-full.txt return 404 and the physical files are removed.
  • Site name (multilingual, multistore) — Appears as the main heading # Site name at the top of the file.
  • Site description (multilingual, multistore) — 1–2 sentences summarising what the store offers. Rendered as a blockquote > ... right under the name.
  • Introduction (multilingual, multistore) — Free Markdown text. Useful for giving extra context to LLMs (returns policy, shipping, brand values).
  • Output formatEnriched Markdown (recommended, supported by all major LLMs) or Plain text.
  • Also generate llms-full.txt — When disabled, only /llms.txt is generated. Saves several MB of storage and seconds of generation time on large catalogs.

2. Content sources

  • Include CMS pages — Content pages (About, FAQ, Terms, etc.).
  • Include categories — Active categories with their descriptions.
  • Include products — Active products.
  • Include manufacturers — Brands with description.
  • Include suppliers — Supplier list.
  • Include product prices — Formatted according to current locale.
  • Include product features — Key/value features.
  • Include combinations — Variants (size, colour, etc.) with price delta.
  • Include out-of-stock products — Off by default.
  • Product description field — Short, long, or both.
  • Product limit — Maximum number of product entries in the file. 500 by default, raise depending on catalog size (1000–5000 is reasonable).

3. Exclusions

Comma-separated ID lists. Lets you exclude specific content without touching the rest of the catalog.

  • Excluded category IDs — E.g. B2B products, internal categories, obsolete categories.
  • Excluded product IDs — End-of-life products, samples, gifts.
  • Excluded CMS IDs — Internal service pages, drafts.
Tip: to find IDs, head to the matching list (Catalog → Categories, etc.) ; the ID is in the first column or in the edit URL.

4. Cache & Cron

  • Cache TTL (in seconds) — 86400 (24 h) by default. The cache is served until it expires.
  • Auto-invalidation on catalog changes — When you modify/add/delete a product, category, etc., the cache is invalidated and the file will be regenerated on the next request (or next cron run).
  • Cron token — Random 32-character string. Can be rotated from the dashboard ; old cron URLs immediately stop working.
  • Ready-to-copy cron URL — Format: https://your-store.tld/index.php?fc=module&module=dfllmstxt&controller=cron&token=XXX

5. Advanced

  • Log retention — Number of days generation logs are kept. 30 by default.
  • Respect robots.txt — For advanced use. On by default.

Cron setup

The cron pre-generates the cache for all stores and all active languages in a single call. Ideal for large catalogs to avoid an end user triggering regeneration.

URL to call:

https://your-store.tld/index.php?fc=module&module=dfllmstxt&controller=cron&token=YOUR_TOKEN

Example crontab (daily at 4 AM):

0 4 * * * curl -s "https://your-store.tld/index.php?fc=module&module=dfllmstxt&controller=cron&token=YOUR_TOKEN" > /dev/null

Optional parameters:

  • &id_shop=2 — Limit to a specific store.
  • &id_lang=1 — Limit to a specific language.

The JSON response details the result of each generation (success, file sizes, duration).

Custom sections

Beyond the raw catalog, you can inject free-form content into the generated files. Use the LLMs.txt → Custom sections tab in the admin menu.

Typical use cases:

  • Summarised returns policy
  • Brand values and commitment
  • Short FAQ
  • Shipping conditions
  • LLM-specific instructions (e.g. “Do not compare with [competitor brand]”)

Each section:

  • Has a multilingual title and content (Markdown supported).
  • Is multistore: you pick which stores it appears on.
  • Has a placement: before sources, after sources, or at file footer.
  • Has a position adjustable by drag-and-drop.
  • Can be enabled/disabled without deletion.

URLs of generated files

The files are accessible at the root of your store:

  • https://your-store.tld/llms.txt
  • https://your-store.tld/llms-full.txt (when the option is enabled)

How it is served

For the default store in its default language, the module writes a physical file at the root of PrestaShop. Apache then serves it directly, without relying on the PrestaShop dispatcher, friendly URLs, or the routes cache. This is the same mechanism used by the official gsitemap module for /sitemap.xml.

For the other stores of a multistore setup (different Host, shared root), the files are served through the moduleRoutes hook which routes by Host header.

HTTP headers

The module automatically adds a block in PrestaShop’s root .htaccess to force the correct headers:

# ~~ dfllmstxt-datafirefly start ~~
<Files "llms.txt">
    ForceType "text/plain; charset=utf-8"
    <IfModule mod_headers.c>
        Header set Content-Type "text/plain; charset=utf-8"
        Header set X-Robots-Tag "noindex, follow"
    </IfModule>
</Files>
<Files "llms-full.txt">
    ForceType "text/plain; charset=utf-8"
    <IfModule mod_headers.c>
        Header set Content-Type "text/plain; charset=utf-8"
        Header set X-Robots-Tag "noindex, follow"
    </IfModule>
</Files>
# ~~ dfllmstxt-datafirefly end ~~

This block is placed outside PrestaShop’s # ~~ start ~~ ... # ~~ end ~~ markers and is therefore preserved when PrestaShop regenerates the file. It is also auto-repaired on every cache regeneration (idempotent), in case it was tampered with.

X-Robots-Tag noindex: intentionally added. llms.txt targets AI crawlers, not Google’s index. LLMs read these files directly without needing them to appear in SERPs. Your classic SEO is not affected.

Extensible architecture (for developers)

The module exposes a Content Provider system that other modules can enrich via a hook. If you have a blog module, product FAQ, customer testimonials or a glossary, it can publish its content into llms.txt without modifying dfllmstxt.

Hook actionDfLlmsTxtRegisterProviders

In your external module:

public function hookActionDfLlmsTxtRegisterProviders($params)
{
    require_once _PS_MODULE_DIR_ . 'mymodule/classes/MyBlogProvider.php';
    $params['registry']->register(new MyBlogProvider());
}

Your class must extend DfLlmsTxtAbstractContentProvider (or implement DfLlmsTxtContentProviderInterface) and provide at minimum:

  • getKey() — Unique identifier (e.g. "blog").
  • getSectionTitle() — Section title shown in the file (e.g. "Blog").
  • isEnabled() — Boolean indicating whether the provider should produce entries.
  • getShortEntries() — Entry list for llms.txt, format ['title', 'url', 'description'].
  • getFullEntries() — Entry list for llms-full.txt, format ['title', 'url', 'body'].

Generation hooks

Two hooks let you filter or enrich the content right before it is served:

  • actionDfLlmsTxtBeforeGenerate — Before generation. Lets you tweak the config or the active providers.
  • actionDfLlmsTxtAfterGenerate — After generation but before caching. Lets you transform the final content.

Compatibility

  • PrestaShop 8.0.0 — 8.99.99 (PS 9 support coming)
  • PHP 7.4 minimum, 8.1+ recommended
  • MySQL 5.7+ / MariaDB 10.4+
  • Multistore fully supported (config and cache scoped per store)
  • Multilingual fully supported (all active languages)
  • Apache 2.x with mod_mime (universal). mod_headers optional but recommended for clean HTTP headers.

Troubleshooting

The file is not appearing at the root

Three possible causes, in order of likelihood:

  1. Write permissions — PrestaShop’s root must be writable by the PHP user. Check with ls -la. If /llms.txt does not exist after a regeneration, it is almost always this.
  2. Module disabled — Check the “Enable module” toggle at the top of the config.
  3. Multistore on shared root — Only the default store writes to the root. The other stores are served via moduleRoutes (which requires Friendly URLs enabled in Preferences → Traffic & SEO).

Broken encoding (characters “é” instead of “é”)

Classic symptom of UTF-8 served without an HTTP charset. The module automatically adds the required .htaccess directives (see HTTP headers section above). If the problem persists after a regeneration:

  1. Check that the # ~~ dfllmstxt-datafirefly start ~~ block is present in PrestaShop’s root .htaccess.
  2. If missing: uninstall then reinstall the module (this forces the block to be re-inserted).
  3. Check with curl -I https://your-store.tld/llms.txt that the response contains Content-Type: text/plain; charset=utf-8.

Generation succeeded but URL returns 404

If regeneration succeeds (file sizes look correct in the logs) but the URL returns 404:

  1. Check that the physical file exists at the root: ls -la /path/to/prestashop/llms.txt.
  2. If it exists but Apache returns 404, it is most likely a .htaccess rule blocking .txt files. Check the root .htaccess rules.
  3. If it does not exist, it is a write permission issue (see above).

Cache remains stale after a product change

Auto-invalidation is disabled. Enable it in Cache & Cron → Auto-invalidation on catalog changes. You can also force a refresh with the Clear cache button on the dashboard.

llms-full.txt weighs several MB, too much

Disable the Also generate llms-full.txt option in the General config. Only /llms.txt (typically < 1 MB) will be generated. For most AI use cases this is enough: modern LLMs know how to follow URLs and fetch individual pages when needed.

Uninstallation

Uninstallation is clean:

  • The 4 SQL tables are dropped.
  • The physical /llms.txt and /llms-full.txt files at the root are removed.
  • The added .htaccess block is removed.
  • All DFLLMS_* configuration variables are cleaned up.
  • Admin tabs are removed.

Changelog

1.0.0 — May 2026

  • Initial release.
  • Generation following the llmstxt.org spec for /llms.txt and /llms-full.txt.
  • 5 native Content Providers: products, categories, CMS, manufacturers, suppliers.
  • Cache TTL with automatic invalidation.
  • Token-secured cron.
  • Multilingual, multistore custom sections.
  • Extensible architecture via hook.
  • Auto-managed root .htaccess for UTF-8 Content-Type and X-Robots-Tag.
  • Option to disable llms-full.txt generation.
Was this page helpful?

Still stuck? Contact support