Automatic Internal SEO Linker: setup and help
Quick start
- Install the ZIP in Modules > Module Manager and open Improve > Internal SEO Linker.
- Review Maximum links per page and Maximum links per group in Settings > Configuration.
- Add a Link Group with Name, Target Entity or Target URL, and Keywords.
- Choose narrow Content Zones and Page Types, set Max links from this group, and keep Active set to Yes.
- Save and open a page containing a matching phrase in the selected content zone.
- Inspect the generated anchor and verify its destination, language, attributes, and link count.
Requires PrestaShop 1.6.1 or later and PHP 7.1 or later.
Setup manual
Install and open configuration
Upload the ZIP in Modules > Module Manager > Upload a module. Install it and click Configure. Open Improve > Internal SEO Linker for Dashboard, Link Groups, and Settings > Configuration. Configure opens the configuration screen.
Its final-page processing uses actionOutputHTMLBefore on PrestaShop 1.7.1 and later, with displayHeader and a Smarty output filter on older supported cores. It skips AJAX and non-HTML responses. The final-page engine needs a body section. Verify the result on your core and theme.
For PrestaShop 1.6 and 1.7.0, the module uses a legacy fallback: displayHeader registers a Smarty output filter, which waits for an assembled page containing opening and closing body tags before applying link insertion once. On PrestaShop 1.7.1 and later, it uses the available final-output hook. The legacy path therefore needs the theme to call displayHeader. Both paths change the rendered response rather than saving edited descriptions or changing theme template files.
Configure General
| Setting | Default | What to configure |
|---|---|---|
| Maximum links per page | 5 | Limit generated links on a page. Existing links do not consume this generated-link budget. |
| Maximum links per group | 3 | Fallback when a group has no positive limit of its own. |
| Default link target | _self |
Choose the default target. Use _blank if links should open another window or tab. |
| Default link rel attribute | Empty | Optional values such as nofollow or noopener. |
| Default link CSS class | mpr-autolink |
Class used unless a group supplies its own. |
| Enable debug profiling | No | Add diagnostics in HTML comments for troubleshooting. |
| Debug IP addresses | Empty | Comma-separated visitor IPs allowed to see diagnostics. Empty does not restrict debug by IP. |
Use small positive limits for your first rule. Save and inspect output before increasing them.
Configure Rules
| Setting | Default | Current behavior |
|---|---|---|
| Prevent duplicate href | Yes | Changing this setting has no effect. Existing links to a destination always count toward the group’s positive link limit. |
| Prevent link in linked parent | No | Changing this setting has no effect. Text already inside a link is skipped, but other text in the same enclosing element can receive links. |
| Prevent multiple autolinks in same element | Yes | Limits links within each uninterrupted text segment. Nested elements and later groups can add further links within the same enclosing element. |
| Proportional global limit distribution | Yes | Allocate effective group limits when their total exceeds the positive page limit. |
| Even link distribution within text | Yes | Changing this setting has no effect. Links follow the order of content regions, groups, keywords and text matches. |
Configure Display and Exclusions
In Display, set these fallbacks. A group's selected content zones take precedence over its advanced selectors, which take precedence over global selectors.
| Setting | Default | How to use it |
|---|---|---|
| Included CSS selectors | .product-description, #description, .page-content, .post-content |
Regions eligible for processing when a group supplies no narrower scope. |
| Included HTML tags | p,div,span,blockquote,li,td |
Immediate text-parent tags eligible for insertion. A group can override this list. |
Advanced matching supports simple selectors: .class, #id, tag, tag.class, and tag#id. Do not assume a browser's full CSS selector syntax is available. Built-in zones can include additional predefined theme patterns.
In Exclusions, review:
| Setting | Default | How to use it |
|---|---|---|
| Skip current page URL | Yes | Skip a group whose target path matches the current page. |
| Exclude headings | Yes | Skip text whose immediate parent is a heading. Check nested custom heading markup separately. |
| Exclude bold/strong text | No | Skip text whose immediate parent is strong or b. |
| Excluded pages | Empty | Select CMS pages that must not be processed. |
Excluded CMS selections are stored in a shape such as {"cms":[3,4,6]}. Use the form rather than editing storage directly.
Create a link group
Open Link Groups and add one narrowly scoped group.
| Field | New-group default | What to enter |
|---|---|---|
| Name | Empty | Required internal label. |
| Target Entity | Empty | Optional single product, category, CMS page, manufacturer, or supplier destination. |
| Target URL | Empty | Required destination URL; entity selection can populate it. Use a relative or absolute URL for a manual target. |
| Target URL (language override) | Empty | Manual per-language URL fallback. Include the correct language path. |
| Keywords | Empty | Required comma-separated terms. |
| Keywords (language override) | Empty | Optional translated terms; empty falls back to base keywords. |
| Content Zones | Empty | Choose Product description (long), Product short description, Category description, CMS page content, Blog post content, Manufacturer description, or Supplier description. Empty uses selector fallbacks. |
| Page Types | Empty | Limit processing to product, category, CMS, blog, manufacturer, supplier, or home pages. Empty does not impose a group page-type filter. |
| Link Position | First occurrence | Offers first, middle, last and spread choices. Changing the choice does not change link placement. |
| Max links from this group | 0 | Use the global group default. Enter a positive value to override it. |
| Ignore case | Yes | Match without case sensitivity. |
| Add tag | No | Wrap matched anchor text in strong markup. |
| Enable overall links limit | No | Existing links to the destination count toward the group limit whether this field is on or off. |
| Link target | Empty | Use global default, or override with _self or _blank. |
| Link rel attribute | Empty | Use global default, or supply a group value. |
| Link CSS class | Empty | Use global default, or supply a group value. |
| CSS Selectors (advanced) | Empty | Override global selectors when no content zones are selected. |
| HTML Tags (advanced) | Empty | Override global tags, for example p,li. |
| Priority | 0 | Lower values process first. |
| Active | Yes | Disable a group without deleting it. |
When an entity destination resolves successfully, its current-language entity URL takes precedence over the manual URL language override. To control a destination entirely with manual language URLs, leave Target Entity empty.
For example:
Name: Shower trays
Target URL: /12-shower-trays
Keywords: shower tray, shower trays, walk-in shower tray
Content Zones: Product description (long), Product short description
Page Types: product
Max links from this group: 1
Ignore case: Yes
Active: Yes
Keyword syntax supports * within a term and | alternatives:
shower tray, walk-in shower tray, shower*, seo|search engine|SEO tool
The wildcard matches non-whitespace characters within the term. It is not a wildcard for arbitrary text across words.
Verify links and theme styling
Save the group, then open a page with a matching phrase in the selected zone. Inspect the link's destination, text, target, rel, and class. Check an excluded page and a page without the phrase.
Existing anchors are skipped. Existing links to the same target reduce that group's positive limit. Saved product, category, CMS, and blog descriptions remain unchanged because insertion happens during rendering.
A generated link can look like:
<p>Choose a <a href="/12-shower-trays" class="mpr-autolink">shower tray</a> for your bathroom.</p>
With group attributes enabled:
<a href="/12-shower-trays" target="_blank" rel="noopener" class="internal-seo-link"><strong>shower tray</strong></a>
You can style automatic links in your theme:
.mpr-autolink {
text-decoration: underline;
text-underline-offset: 2px;
}
The dashboard reports groups, keywords, zone and entity usage, recent groups, and catalog coverage. It does not verify every possible source page.
Import and export CSV
Use Import CSV or Export CSV on Link Groups. Import creates new records. It does not update existing groups by name, so importing an export again can create duplicates. Choose the intended shop context before importing.
Required columns:
name,target_url,keywords
Full exported columns:
name,target_url,keywords,link_position,max_links,ignore_case,add_strong,link_target,link_rel,link_class,content_zones,page_types,entity_type,entity_id,position,active
Example:
Shower trays,/12-shower-trays,"shower tray, shower trays, shower*",first,1,1,0,_self,,mpr-autolink,"[""product_description""]","[""product""]",category,12,10,1
Use a lowercase .csv extension and comma delimiters. Check imported and skipped counts. This export format does not include translated keyword/URL overrides or every advanced field, so keep a database backup if you need a complete restore.
Troubleshoot and uninstall
For missing links, check Active, current language, target resolution, page type, zone selectors, eligible parent tags, and both limits. Check whether the target is the current URL or already linked enough times. A keyword split across HTML elements may not match one text segment.
Enable Enable debug profiling and enter your IP in Debug IP addresses. Inspect page source near the closing body tag for MPR Internal Linking Debug v2.0, page type, existing link count, generated link count, and group matches. Debug responses are marked private and no-store. Turn debug off when finished.
Use Settings > Integrity for infrastructure checks. Refresh any relevant page cache after edits.
Disable groups or the module to stop insertion temporarily. Uninstall removes its admin menu, settings, preferences, and link-group storage. Export or back up groups first. Your saved catalog and CMS text remains unchanged.
Questions
2
Can automatic links affect navigation, breadcrumbs or JSON-LD?
The full-page pass works inside configured content regions in the page body, so the page head is excluded. The default eligible text-parent tags are p,div,span,blockquote,li,td; script is not in that list. Navigation and breadcrumbs stay outside processing when your zones or selectors exclude them. Keep the selected regions narrow and inspect the final output, including any JSON-LD embedded in those regions, rather than relying on blanket protection for custom markup.
Does automatic link insertion need a visitor tracker?
No visitor-tracking script or consent cookie is required for keyword matching. The module reads your configured link groups and processes the storefront HTML on the server before returning it.
Known Issues
12
Excluded listing pages still received links
CMS exclusions did not save consistently
CSV imports used the wrong shop context
Internal links missing on older PrestaShop releases
Administration labels remained in English
Damaged translated labels
Untouched targeting selected everything
Icons missing with combined assets
Translated pages linked to the wrong language slugs
Automatic links inserted inside existing links
Existing links outside the content used the page limit
Incorrect linking around HTML fragments
Feature Requests
5
Implemented
CMS page exclusions from automatic linking
Automatic keyword links
Page exclusions
Installation checks and repair
One-click module updates
Changelog
v3.0.92026-08-30
- AddedAdmin UI for excluded pages — checkbox grid in Exclusions tab
- Addedcomplete FR/DE/ES/IT/PL translations
- ImprovedSync fragment-aware internal linking engine
- ImprovedV3.0.0 — 19x faster link injection engine + shared package + page exclusion
- ImprovedPre-scan CSS selectors to eliminate redundant regex scans
- FixedResolve localized internal link targets
- FixedSync entity selector package
- FixedVendor prestashop-admin as module files
- FixedExisting-link counting scoped to content regions (package update)
Older releases
v2.1.02026-04-20
- Addedself-healing integrity checks for automatic diagnostics and repair
- Addedadmin menu management via MenuInstaller for streamlined module setup
- AddedLicense management tab with key management and renewal options
- Addedcomplete FR/DE/ES/IT/PL translations
- Improvedsettings form organization with tabbed layout
- FixedPrevent autolinking inside existing anchor tags
- Fixedadmin list filters — sorting, searching, and filtering now work correctly on all columns
v1.2.02025-09-10
- Addedlink group management: bundle related keyword-URL pairs and enable/disable as a set
- Improvedcase-insensitive matching with configurable per-rule override
- Fixedlinks being injected inside existing <a> tags causing nested anchor violations
- Addedmax-links-per-page limit with configurable threshold
v2.0.02025-08-01
- Addedfull compatibility with PrestaShop 9.x and Hummingbird theme
- Complete architecture rewrite: link rules now stored as a versioned JSON document for faster import/export
- AddedCSS selector targeting: apply linking rules only within specified content containers
- Improvedregex-based keyword matching with optional word boundary enforcement
- Addedper-link attribution — track click-throughs via a lightweight redirect proxy
- Fixedmemory exhaustion on pages with very long product descriptions containing repeated keywords
v1.1.02025-05-15
- Addedbulk import/export of keyword-URL rules via CSV
- Improvedexclusion list: skip linking on CMS pages, specific categories, or product IDs
- Fixedduplicate link injection when the same keyword appeared in page title and body
- Addednofollow/noopener attribute toggle per rule
v1.0.02025-01-17
- Initialrelease: automatic keyword-to-URL linking for product descriptions and CMS content
- InitialAdmin rule builder with keyword, target URL, and match-count-per-page settings
- InitialProcessed server-side using DOMDocument — no JavaScript dependency
- InitialMulti-language support for keyword sets and target URLs
Demo
Test the full module before you buy
Buy a licence later and keep your settings.
- Your 30-day demo Test it on your own shop for 30 days from the first install.
- Ready demo shop Explore a ready demo shop in your browser.
- No registration No account, email or store domain needed.
By downloading, you accept the demo terms and privacy policy.
By opening this demo you accept the demo terms and the privacy policy.