PS PrestaShop Intermediate

SEO Cannibalization Detector — Complete guide for PrestaShop 8 & 9

Detect and resolve SEO cannibalization in your PrestaShop store via Google Search Console: installation, configuration, scans and 301 redirects.

Updated Module version 1.0.0

SEO Cannibalization Detector connects in read-only mode to your Google Search Console property, identifies every query where multiple URLs of your PrestaShop store cannibalize each other, and proposes a concrete action: consolidate, redirect 301, differentiate or monitor. This documentation covers installation, Google service account setup, launching your first scan, reading the report and managing redirects.

Prerequisites

  • PrestaShop 8.0 to 9.x
  • PHP 8.1 or higher, with openssl, curl and json extensions
  • A Google Cloud project (free account is enough, no credit required)
  • A Google Search Console property already verified for your store’s domain
Check OpenSSL: on most hosts (o2switch, OVH, Hetzner, Infomaniak), OpenSSL is enabled by default. To verify, temporarily add echo extension_loaded('openssl') ? 'OK' : 'KO'; to a test PHP file.

Installation

  1. Download the dfcannibalization-1.0.0.zip file from your DataFirefly customer area.
  2. In the PrestaShop back office, go to Modules → Module Manager.
  3. Click Upload a module and select the ZIP.
  4. Once installation is complete, click Configure.

The module creates 4 SQL tables (scan, query, page, action), an admin tab “DataFirefly Cannibalization” under IMPROVE, and a unique token for scheduled scans.

Create a Google service account

A service account is a Google technical account that lets your store read Search Console data without interactive authentication. It is free and limited to read-only.

1. Enable the Search Console API

  1. Open console.cloud.google.com.
  2. Create a new project (e.g. “DataFirefly SEO”) or select an existing project.
  3. In the navigation menu, go to APIs & Services → Library.
  4. Search for Google Search Console API and click Enable.

2. Create the service account

  1. In the same menu, go to APIs & Services → Credentials.
  2. Click Create Credentials → Service Account.
  3. Give it an explicit name (e.g. “datafirefly-cannibalization”) and confirm. You can skip the optional roles and user access steps.

3. Generate the JSON key

  1. Click the created service account.
  2. Keys tab → Add Key → Create new key.
  3. Select JSON format and confirm. The file downloads automatically.
Keep this file in a safe place: it contains the service account’s private key. Anyone with this JSON can read your Search Console data.

Authorize the service account in Search Console

The service account has its own email (visible in the JSON under the client_email key, e.g. datafirefly-cannibalization@project-123.iam.gserviceaccount.com). It must be granted read access on your property.

  1. Open search.google.com/search-console.
  2. Select your property (URL-prefix or domain).
  3. Click Settings → Users and permissions.
  4. Click Add user.
  5. Paste the service account’s client_email and choose the Restricted permission (read-only).
  6. Confirm.

Configure the module

Return to the PrestaShop back office, in the module configuration.

Service account and property

  • Service account JSON: open the downloaded file, copy-paste its full contents into the field.
  • Site URL (GSC property): reproduce exactly the format displayed in Search Console.
    • For a URL-prefix property: https://www.example.com/ (with trailing slash).
    • For a domain property: sc-domain:example.com (no protocol, with sc-domain: prefix).

Detection thresholds

  • Lookback period: 7 to 490 days. 90 days is a good compromise between freshness and statistical volume.
  • Minimum impressions: ignore very low queries. Default 30. Set to 10 if your store is recent.
  • Minimum clicks: click threshold per query to be analyzed. Default 1. Set to 0 to also include impression-only queries (useful for young sites).
  • Maximum position: ignore queries where the best URL is beyond this position. Default 30.

Automatic 301 redirects

Enables interception via the PrestaShop dispatcher hook. Disable if you prefer to manage redirects manually in Traffic and SEO → Redirects.

Click Save, then Test GSC connection. If the connection succeeds, the module shows a green message.

“403 User does not have sufficient permissions”: the service account has not yet been added to Search Console, or the property entered does not match exactly the one displayed in GSC. Check both sides.

Run a scan

Click Run scan now. The module:

  1. Queries the Search Console API for the configured period (pagination up to 200,000 rows).
  2. Groups rows by query.
  3. Filters according to your thresholds (impressions, clicks, position).
  4. Keeps only queries with at least 2 distinct URLs.
  5. Computes the severity score and the recommendation.
  6. Persists everything to the database.

For an average site (10,000 to 50,000 pages), a full 90-day scan takes between 30 seconds and 3 minutes.

Read the report

Once the scan is complete, open it from the Scan history tab. The report lists each cannibalized query with:

  • The keyword (the Google query).
  • The severity score as a colored badge (low / medium / high / critical).
  • The number of competing URLs.
  • The recommendation (REDIRECT 301, CONSOLIDATE, DIFFERENTIATE, MONITOR).
  • The status (pending, reviewed, resolved, ignored).

Click on a query to see the details: the list of competing URLs with clicks, impressions, average position, CTR, and page type (product, category, CMS, blog, etc.). The URL identified as “winner” is highlighted in green.

Understanding the severity score

The score is out of 100, combining 4 weighted factors:

  • Number of competing pages (25 points max) — formula: min((n-1)/3, 1) × 25. From 4 competing URLs onwards, the factor is maximal.
  • Click distribution (30 points max) — based on an inverted HHI index. 50/50 cannibalization between two URLs is worse than 95/5. Formula: ((1-HHI)/(1-1/n)) × 30.
  • Position gap (30 points max) — weighted by the best result’s position. Multiplier × 1.0 if best position ≤ 10, × 0.7 if ≤ 20, × 0.4 beyond.
  • Impression volume (15 points max) — logarithmic scale: min(log10(impr+1)/4, 1) × 15.

Levels: low < 26, medium < 51, high < 76, critical ≥ 76.

The 4 recommendations

REDIRECT 301

The module proposes this action when one URL captures at least 70% of clicks at average position ≤ 15. This is the “winning” URL: Google clearly considers it the best answer. The other URLs are redirected to it via 301. Content can be merged editorially before the redirect if needed.

CONSOLIDATE

Performance is split (no clear winner). Recommendation: merge the content of the two URLs into a single one, then 301-redirect the other. This work is editorial, not automatable. The module identifies the case but does not perform the merge for you.

DIFFERENTIATE

Pages are of different types (example: a product sheet and a blog article). Cannibalization indicates a title/meta tag targeting problem rather than a real content conflict. Recommendation: rework the tags to target distinct queries (long-tail on the blog, main query on the product).

MONITOR

Score is low (< 26). No urgent action. The module keeps the query in the report but flags it “to watch”.

Apply a 301 redirect

From the detail of a query recommended REDIRECT 301:

  1. Click the Select as source button next to the URL to be redirected (the one that is not the winner).
  2. The target URL (the winner) is pre-filled automatically.
  3. Click Apply redirect.

The rule is saved and served immediately from the actionDispatcherBefore hook. Performance: a single SELECT per PHP-FPM worker thanks to a static in-memory cache.

Verify a redirect works: open the source URL in a browser in private mode, or use curl -I https://your-store.com/old-url. You should see an HTTP/1.1 301 and a Location: header pointing to the new URL.

Manage active redirects

The Redirects 301 tab lists all redirects in place with their hit counter. You can:

  • Disable a redirect without deleting it (useful to test a rollback).
  • Delete a redirect permanently.
  • See the hit count since creation (measures effectiveness).

Scheduled scans via cron

The module exposes a token-protected front controller. The URL is shown in the module configuration as:

https://your-store.com/index.php?fc=module&module=dfcannibalization&controller=cron&token=XXXX

Standard Linux cron

On a Linux/Unix server with SSH access, edit your crontab:

crontab -e

For example, add a scan every Sunday at 11 PM:

0 23 * * 0 curl -s "https://your-store.com/index.php?fc=module&module=dfcannibalization&controller=cron&token=XXXX" > /dev/null

Scheduled tasks OVH / o2switch / Infomaniak

All these hosts offer a scheduler in their back office. Enter the full URL and the desired frequency. For most stores, a weekly scan is more than enough.

Regenerate the token: uninstall then reinstall the module if you think your token has leaked. A new token will be generated at install.

Multi-shop

All tables include an id_shop column. Scans are scoped to the active shop in the back office selector. Each shop has its own configuration (service account, GSC URL, thresholds) and its own scan history.

If you manage multiple domains from a single back office, create a distinct service account per property, or authorize the same service account on all your Search Console properties.

Troubleshooting

“OpenSSL extension required”

Ask your host to enable the PHP OpenSSL extension. On 99% of modern hosts, it is enabled by default.

“Invalid service account JSON”

The pasted JSON is incomplete or corrupted. Re-download the key from Google Cloud Console and paste it whole, unmodified.

“Site URL must match exactly the GSC property”

Check the format in Search Console. A URL-prefix property is written https://www.example.com/ (trailing slash). A domain property is written sc-domain:example.com (no protocol, no slash).

“403 User does not have sufficient permissions”

The service account has not been authorized in Search Console, or has been authorized on another property. Check Settings → Users and permissions.

The scan runs but finds no cannibalization

Your thresholds might be too high for your volume. Try lowering minimum impressions to 5 and minimum clicks to 0.

A 301 redirect does not trigger

Check that (1) the “Automatic 301 redirects” option is enabled in the configuration, (2) the rule is marked as active in the Redirects 301 tab, (3) the PrestaShop cache has been cleared after activating the module.

Going further

  • Review policy: on critical queries, intervene within 7 days. On high, within 30 days. On medium, as part of a quarterly review.
  • 301 strategy versus consolidation: the 301 redirect transfers PageRank but loses the ability to have two indexed pages. Prefer differentiation for distinct search intents.
  • Product sheet edge case: if two very close variants cannibalize each other, merge them into a product with variants rather than two separate products.
Was this page helpful?

Still stuck? Contact support