PS PrestaShop Intermediate

DataFirefly All in One SEO — Complete documentation

Premium all-in-one SEO module for PrestaShop 8 and 9: dynamic meta, JSON-LD schemas, multilingual sitemap, redirects, 404s, intelligent robots.txt, tracking and content analyzer.

Updated Module version 1.0.2

Premium all-in-one SEO suite for PrestaShop 8 and 9: dynamic meta templates, full JSON-LD schemas, multilingual XML sitemap, redirects, 404 monitoring, Open Graph and Twitter Cards, GA4 and GTM, intelligent robots.txt with AI crawler blocking and content analyzer — all in a single module.

Requirements

  • PrestaShop: 8.0 to 9.x
  • PHP: 8.1 or higher (8.2 and 8.3 recommended)
  • MySQL: 5.7+ or MariaDB 10.3+
  • productcomments module (official PrestaShop): optional, required only for AggregateRating on products
  • mod_rewrite enabled on Apache (or Nginx equivalent) for rewritten URLs
The module is multi-shop aware natively: all tables are scoped by id_shop. You can have completely different configurations per shop.

Installation

  1. Download dfallinoneseo-vX.Y.Z.zip from your DataFirefly client area.
  2. Log in to your PrestaShop back-office.
  3. Go to Modules → Module Manager.
  4. Click Upload a module in the top right.
  5. Drag-and-drop the ZIP file or click Select a file.
  6. Installation automatically creates the 11 SQL tables, registers the hooks and adds the Improve → DataFirefly SEO menu.
After installation, open the module Dashboard for an overview of the global SEO score and the priority issues to fix.

10-minute first-time setup

This quick walkthrough lets you configure the essentials before the first Google crawl.

  1. Settings → General: enable the module, set the site name and the “Home” label for the breadcrumb.
  2. Meta & templates: define at least a Product template and a Category template (see dedicated section).
  3. Schema → Organization identity: fill in logo, phone, email, address and social network URLs (sameAs).
  4. Sitemap: enable the sitemap and click Regenerate now.
  5. Tracking: add your GA4 Measurement ID and/or GTM ID.
  6. Tracking → Verifications: paste the Google Search Console verification value.
  7. Robots.txt: click Load defaults (PS + AI blocking) to start from a healthy baseline.

Meta templates

The module replaces manual meta_title and meta_description entry with dynamic templates per entity type. When a record with empty metas is saved, the matching template is applied automatically.

Supported entity types

  • Product: product pages (all types including virtual and pack)
  • Category: category pages
  • CMS Page: static content pages
  • Brand / Manufacturer: manufacturer pages
  • Supplier: supplier pages
  • Home: shop home page
  • Generic pages: /contact, /sitemap, etc.

Available tokens

Tokens are replaced with actual values at page render time. Not all tokens are available for every entity type.

  • {shop_name} — shop name
  • {sep} — separator (default |)
  • {product_name} — product name (current language)
  • {product_reference} — internal reference
  • {product_sku} — alias for reference
  • {product_ean13} — EAN13 barcode
  • {product_brand}, {brand} — manufacturer/brand
  • {category} — default category (product) or category name (category page)
  • {category_parent} — parent category name
  • {category_description} — short description (160 char max)
  • {short_description} — product short description (160 char max)
  • {price} — VAT-incl. price formatted with currency
  • {price_tax_excl} — VAT-excl. price formatted
  • {title} — CMS page title
  • {summary} — CMS content excerpt (160 char max)

Conditional blocks

To avoid rendering an empty token, use the conditional syntax:

{?product_brand}{product_brand} | {/?}{product_name} - {shop_name}

If product_brand is empty (product without brand), the entire block between {?token} and {/?} is removed. Otherwise, its content is rendered and tokens inside are replaced normally.

Product:

Title: {?product_brand}{product_brand} {/?}{product_name} - {category} | {shop_name}
Description: Discover {product_name}{?product_brand} by {product_brand}{/?}. {short_description} Fast shipping on {shop_name}.

Category:

Title: {category} - {?category_parent}{category_parent} - {/?}{shop_name}
Description: All products in the {category} category on {shop_name}. {category_description}

Home:

Title: {shop_name} - Online store
Description: Welcome to {shop_name}. Discover our catalog, fast shipping, secure payment.

Per-entity override

To override a specific page (e.g. a flagship product), click the Meta override icon from the Bulk edit menu or use the URL:

?controller=AdminDfSeoMeta&entity=product&entity_id=42

The override page lets you set meta_title, meta_description, the robots directive (e.g. noindex,follow) and a custom canonical per language.

The robots directive defined on a specific entity takes priority over global indexation settings. Use it sparingly to avoid accidentally deindexing your best pages.

JSON-LD schemas

The module generates a single @graph block aggregating all schemas for the current page, validated by Google Rich Results Test.

Automatically generated schemas

  • Organization — on all pages, company identity
  • WebSite — on the home, with SearchAction for sitelinks search box
  • LocalBusiness — if a physical address is set
  • BreadcrumbList — breadcrumb
  • Product — on product pages, with offers, priceValidUntil, gtin13/isbn/mpn
  • AggregateRating — aggregated from the official productcomments module
  • Article — on CMS pages
  • FAQPage — from product or page FAQ blocks

Organization identity

Schema → Organization identity tab. Fields to fill in:

  • Type: Organization, Corporation, LocalBusiness, Store, OnlineStore, OnlineBusiness
  • Logo: absolute URL (recommended 600×60 minimum, square or landscape ratio)
  • Phone, Email: used in contactPoint
  • Postal address: street, postal code, city, country (ISO-2)
  • sameAs: one URL per line (Facebook, Instagram, LinkedIn, Twitter/X, etc.)

Product offer validity

The Product offer validity (days) field controls the value of priceValidUntil in Product.offers. Default: 60 days. Google requires this field to display the price in rich results.

Custom schemas

Schema → Custom schemas tab. Allows adding tailored JSON-LD blocks (HowTo, Recipe, Event, JobPosting, VideoObject, Course, etc.) with a precise scope:

  • global: all pages
  • home: home only
  • product: all product pages
  • product_id: a specific product (uses the ID field)
  • category, category_id: same for categories
  • cms, cms_id: same for CMS pages

Variables available in custom JSON: {shop_name}, {base_url}, {entity_id}, {entity_type}.

Custom JSON-LD is inserted as-is in the @graph. Validate it with the Rich Results Test before publication. Invalid JSON is silently rejected.

XML sitemap

The module generates an XML sitemap compliant with the sitemaps.org specification, with hreflang on every URL and image support. Architecture: one sitemap index per shop, then one sitemap per entity type × language, split into chunks.

Configuration

Sitemap tab. Enable the sitemap then check the content to include:

  • Products (default all active products)
  • Categories
  • CMS pages
  • Brands / Manufacturers
  • Suppliers
  • Images (adds image:image to each product URL)
  • Videos (if present in pages)

Additional options:

  • Exclude out-of-stock: removes out-of-stock products
  • Gzip: also generates .xml.gz variants (reduces 5-10x the size downloaded by crawlers)
  • URLs per file: chunk size (recommended 5000-10000, max 50000 per XML spec)

Regeneration

Regeneration is manual from the admin to avoid unexpected server load. Click Regenerate now.

To automate, schedule a cron that calls the following script (every 6 or 12 hours depending on your catalog update frequency):

0 */6 * * * php /var/www/html/index.php fc=module&module=dfallinoneseo&controller=sitemap&action=rebuild

Submission to search engines

Click Ping search engines to notify Google and Bing (legacy but still active endpoints). For Google Search Console, submit the sitemap index URL once in GSC → Sitemaps. GSC will re-crawl automatically on every change.

Sitemap index URL: https://your-shop.com/sitemap.xml

Public HTML sitemap

A human-readable HTML sitemap is automatically generated at /plan-du-site. It aggregates categories (tree), CMS pages, brands, suppliers and the 200 most recent products. Useful for internal linking and accessibility.

Redirects

The module handles HTTP 301 (permanent), 302 (temporary), 307, 308 and 410 (Gone) redirects with three match types.

Match types

  • Exact: the source URL must match exactly (without query string)
  • Prefix: the source URL is a prefix of the requested URL. The suffix is kept in the destination if Keep query string is checked. Useful for migrating entire folders (/old-folder//new-folder/).
  • Regex: PHP regular expression (mode ~...~i case-sensitive/insensitive). Capture groups are available in the destination via $1, $2, etc.

Manual creation

Redirects → New redirect tab. Fields:

  • Source URL: path without domain (e.g. /old-page)
  • Destination URL: path or absolute URL. Leave empty for a 410 code.
  • Match type, HTTP code, Keep query string

CSV import / export

Expected CSV format (with header):

source,destination,type,code
/old-product,/new-product,exact,301
/old-folder/,/new-folder/,prefix,301
/old-(.*),/new-$1,regex,301

CSV export reuses the redirects currently filtered in the list.

Automatic redirect on slug change

If Settings → Monitoring → Auto 301 redirect on URL change is checked, the module creates a 301 automatically when you change the slug of a product, category, CMS page, brand or supplier. The created_by is then marked auto:urlchange for distinction.

This option avoids the majority of SEO 404s related to content refactoring. Enable it from installation.

404 monitoring

404 Monitor tab. Captures all 404 error URLs served by PrestaShop, with deduplication, hit counting, bot detection and IP hashing (PrestaShop’s COOKIE_KEY salt for GDPR compliance).

Available filters

  • Unresolved: URLs without a covering redirect (default view)
  • Resolved: URLs for which a redirect was created afterwards
  • Bots: hits from user-agents identified as bots
  • All

Create a redirect in one click

On each row, the Redirect button opens an inline form that pre-fills the source. Enter the destination, choose the HTTP code, validate. The 404 is automatically marked as resolved.

Purge and maintenance

The Settings → Monitoring menu exposes a threshold Maximum number of 404 entries kept (default 5000). Beyond, the Purge old 404s button removes the oldest unresolved entries.

Dynamic robots.txt

The module serves a /robots.txt file dynamically generated on each request, based on the rules defined in Robots.txt.

PrestaShop + AI blocking presets

The Load defaults (PS + AI blocking) button overwrites all current rules and loads a healthy preset that:

  • Blocks sensitive PrestaShop directories (/admin*/, /cache/, /classes/, etc.)
  • Blocks technical pages (/cart, /order, /my-account, etc.)
  • Blocks the main non-respectful AI crawlers: GPTBot, ClaudeBot, CCBot, Google-Extended, anthropic-ai
  • Points to the sitemap (Sitemap: /sitemap.xml)

Custom rules

Each rule has a user-agent, a directive (Allow, Disallow, Crawl-delay), a value and a position (order in the file). Enable/disable a rule without deleting it via the ON/OFF pill.

Live preview

The Generated file preview block at the bottom of the page renders the robots.txt as it will be served, before publication.

Native llms.txt file

The module serves an /llms.txt file compliant with the llmstxt.org specification. This file lists, in markdown, the main sections of the site for respectful AI crawlers that want a structured view rather than scraping the entire HTML.

No configuration is required — the module automatically generates the file from your tree of categories, CMS pages and brands.

Open Graph and Twitter Cards

Social tab. The module injects og:* and twitter:* tags on all pages.

Settings

  • Enable Open Graph and Twitter Cards: master switch
  • Automatic og:locale: computed from the context language (e.g. en_US)
  • Default OG image: absolute URL of a 1200×630 image (used when the page has no dedicated image)
  • og:site_name, default og:type
  • Twitter @handle and card type (summary or summary_large_image)
  • fb:app_id: Facebook App ID
For product pages, the module automatically uses the main image of the product. For other pages, the default OG image is used if no image is defined.

Tracking: GA4, GTM, pixels

GA4 and Enhanced Ecommerce

GA4 Measurement ID field: format G-XXXXXXXXXX. Automatic format validation.

Check Enhanced Ecommerce to enable view_item, view_item_list, add_to_cart, remove_from_cart, begin_checkout, add_payment_info, purchase events.

Check Respect Consent Mode v2 to anonymize hits until explicit consent (compatible with standard CMPs).

Google Tag Manager

GTM ID field: format GTM-XXXXXXX. The module injects the GTM snippet in the head and the noscript fallback right after the opening body.

Advertising pixels

  • Facebook Pixel ID: 15 digits
  • TikTok Pixel ID: alphanumeric

If Consent Mode v2 is active, these pixels only fire after consent.

Ownership verifications

Paste the verification tag values (without the full meta tag, only the content attribute value):

  • Google Search Console
  • Bing Webmaster Tools
  • Yandex Webmaster
  • Pinterest
  • Baidu

Custom head and body-end code

Two free fields accept arbitrary HTML/JS:

  • Code injected in head: for third-party scripts, additional meta tags
  • Code injected just before body closing: ideal for chat widgets, late retargeting, async scripts
These fields perform no validation. An HTML syntax error can break the page rendering. Test in pre-production before publication.

Content analyzer

Analyzer tab. Submit a product, a category, a CMS page or raw HTML to the analyzer to get a global SEO score and a detailed metrics breakdown.

Computed metrics

  • Global SEO score (0-100) — weighted pondering of checks
  • Flesch readability — multilingual approximation (vowel-group syllable count)
  • Word count, sentence count
  • Primary keyword density (in %)
  • Internal / external / nofollow links
  • Images without alt attribute
  • H1 to H6 heading structure
  • Presence of the keyword in slug and first paragraph

Checks

The analyzer returns a list of checks with good / warn / bad status:

  • Title length (50-60 characters)
  • Meta description length (140-160 characters)
  • Slug presence and length
  • Body length (minimum 300 words)
  • Presence of at least one image with alt
  • Keyword in title, in first paragraph, in slug
  • Keyword density between 0.5% and 2.5%
  • At least one H1 and several H2/H3
The analyzer is a guide, not an absolute truth. A score of 80+ is excellent. Below 50, review structure and wording. Never sacrifice editorial quality for a score.

Bulk edit

Bulk edit tab. Paginated grid (30 entries/page) with filters to quickly modify meta_title, meta_description and link_rewrite on products, categories or CMS pages.

Available filters

  • All
  • Without title: only entries with empty meta_title
  • Without description: only entries with empty meta_description
  • Search by name

Bulk apply templates

The Apply templates button automatically applies the template defined for the current entity type to the entries matching the filters. Check Apply only to empty fields to avoid overwriting already-filled metas.

SEO metabox on the product page

On a product edit page in the back-office, a DataFirefly SEO box is added with:

  • A live SEO score (7 checks: title length, description, slug, body, image, EAN13, brand)
  • A faithfully rendered Google SERP preview
  • The detected primary keyword

Advanced settings

Indexation

Settings → Indexation tab:

  • Multilingual hreflang: generates link rel="alternate" tags on all pages
  • x-default strategy: Default language (recommended), English, or Disabled
  • Canonical URL: injects link rel="canonical"
  • Canonical on pagination: On current page (recommended), Always on page 1, or No canonical
  • Automatic noindex: /search, cart, my account, new products, best sales, prices drop, faceted
  • Canonical to parent page on faceted: avoids duplicate content of faceted navigation

Images

  • Automatic alt attribute generation: on saving an image without alt, applies the template
  • Alt template: default {product_name} - {shop_name}
  • Native image lazyload: adds loading="lazy" and decoding="async" to all images, with IntersectionObserver fallback for data-src images

Maintenance

  • Clear cache: purges Smarty + PrestaShop caches
  • Purge old 404s: applies the configured threshold
  • Export all data (JSON): downloads a JSON file with all SEO tables of the current shop (useful for migration between environments or backup before uninstallation)

Multi-shop

All features are scoped by id_shop. By switching from one shop to another via the PrestaShop context selector, you see and modify only that shop’s data.

Special cases to know:

  • Templates: one template per (entity type, shop) pair. Define templates explicitly for each shop.
  • Sitemap: a distinct sitemap_index per shop, accessible at https://shop-1.com/sitemap.xml, https://shop-2.com/sitemap.xml, etc.
  • Robots.txt: rules per shop, served on the corresponding domain
  • Redirects: per shop
  • Custom schemas: per shop

Troubleshooting

The sitemap is not generated

  • Check that the modules/dfallinoneseo/sitemaps/ folder is writable by PHP
  • Check permissions: chmod 755 modules/dfallinoneseo/sitemaps/
  • Increase max_execution_time in php.ini if you have more than 50,000 products

JSON-LD schemas don’t appear

  • Check that the module is enabled (Settings → General)
  • Check that the relevant schema type is enabled (Schema → Generated schema types)
  • Clear the PrestaShop cache
  • Inspect the HTML source: schemas are injected in a script type="application/ld+json" block

301 redirects don’t work

  • Check that the module is installed and enabled
  • Check that redirects are marked active (ON pill)
  • For regex, test your expression on regex101.com in PCRE mode
  • Priority order is: exact → prefix → regex (by descending hit_count)

GA4 / GTM doesn’t inject

  • Check the ID format (G-XXXXXXX or GTM-XXXXXXX)
  • If Consent Mode v2 is active, the snippet is in “denied” mode by default until consent. Check the CMP layer.
  • Inspect the page head: the GA4/GTM snippet is injected just before closing

robots.txt doesn’t change

  • Check that no static robots.txt file exists at the site root (it would take priority over the module). Delete it.
  • The module serves robots.txt via a PrestaShop route — check that Friendly URL is enabled

Error creating SQL tables on installation

  • Check that the MySQL user has CREATE and ALTER rights
  • Check the encoding: MySQL must support utf8mb4 with utf8mb4_unicode_ci collation
  • If PrestaShop’s custom table prefix exceeds 5 characters, some index names may exceed MySQL’s 64-character limit. Contact support.

Technical reference

Hooks used

The module registers 18 hooks:

  • displayHeader — injection of meta tags, canonical, hreflang, OG, Twitter, JSON-LD, GA4/GTM, verifications
  • displayBeforeBodyClosingTag — GTM noscript, FB Pixel noscript, custom body-end code injection
  • displayBackOfficeHeader — back-office CSS/JS
  • displayAdminProductsExtra — SEO metabox on product page
  • actionDispatcherBefore, actionDispatcherAfter — redirect routing and 404 capture
  • actionObjectProductAddAfter, actionObjectProductUpdateAfter — meta auto-fill + auto-301
  • actionObjectCategoryAddAfter, actionObjectCategoryUpdateAfter — same for categories
  • actionObjectCmsAddAfter, actionObjectCmsUpdateAfter — same for CMS
  • actionObjectManufacturerUpdateAfter, actionObjectSupplierUpdateAfter — auto-301 on slug change
  • actionAdminControllerSetMedia, actionFrontControllerSetMedia — CSS/JS assets
  • displayProductExtraContent — reserved for future use
  • moduleRoutes/sitemap.xml, /plan-du-site, /robots.txt, /llms.txt routes

Added SQL tables

All tables use the df_seo_ prefix, utf8mb4 charset, utf8mb4_unicode_ci collation:

  • df_seo_meta, df_seo_meta_lang — meta overrides per entity
  • df_seo_template, df_seo_template_lang — templates per type
  • df_seo_redirect — 301/302/307/308/410 redirects
  • df_seo_404 — 404 journal
  • df_seo_score — score snapshots (analyzer)
  • df_seo_keyword — focus keywords
  • df_seo_robots_rule — robots.txt rules
  • df_seo_schema_custom — custom JSON-LD schemas
  • df_seo_log — internal diagnostic log

Uninstallation

Uninstallation removes the hooks and back-office tabs, but keeps the SQL tables and data. To fully purge:

DROP TABLE ps_df_seo_meta, ps_df_seo_meta_lang, ps_df_seo_template, ps_df_seo_template_lang,
           ps_df_seo_redirect, ps_df_seo_404, ps_df_seo_score, ps_df_seo_keyword,
           ps_df_seo_robots_rule, ps_df_seo_schema_custom, ps_df_seo_log;
DELETE FROM ps_configuration WHERE name LIKE 'DFSEO_%';
Before uninstallation, use Settings → Maintenance → Export all data (JSON) to keep a complete archive. The JSON format lets you re-import redirects, templates and schemas on another installation.

Updates and support

  • Updates: 12 months included from purchase. Optional annual renewal at €49.
  • Support: 12 months by email, response within 48 business hours.
  • Changelog and downloads of the latest versions on your DataFirefly client account.
Was this page helpful?

Still stuck? Contact support