PHPackages                             mage2kishan/module-crosslinks - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. mage2kishan/module-crosslinks

ActiveMagento2-module[Utility &amp; Helpers](/categories/utility)

mage2kishan/module-crosslinks
=============================

Automatic internal crosslinks for Magento 2 (Hyva + Luma). Converts configured keywords in product, category, and CMS content into anchor links to boost internal linking and SEO. Extracted from Panth\_AdvancedSEO for independent installation.

1.0.6(1mo ago)021↓100%1proprietaryPHPPHP ~8.1.0||~8.2.0||~8.3.0||~8.4.0

Since Apr 20Pushed 1mo agoCompare

[ Source](https://github.com/mage2sk/module-crosslinks)[ Packagist](https://packagist.org/packages/mage2kishan/module-crosslinks)[ RSS](/packages/mage2kishan-module-crosslinks/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (7)Versions (8)Used By (0)

Panth Crosslinks — Automatic Internal Linking for Magento 2 (Hyva + Luma)
=========================================================================

[](#panth-crosslinks--automatic-internal-linking-for-magento-2-hyva--luma)

[![Magento 2.4.4 - 2.4.8](https://camo.githubusercontent.com/079c832211eed4f9451ebe264e3865f825b0f9f31b041cbf03676c6e254535d4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d6167656e746f2d322e342e342532302d2d253230322e342e382d6f72616e67653f6c6f676f3d6d6167656e746f266c6f676f436f6c6f723d7768697465)](https://magento.com)[![PHP 8.1 - 8.4](https://camo.githubusercontent.com/56b3cce18841623e2cbed2ebf09b06be1be8807e99e6e054a89d304ab4790b8e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532302d2d253230382e342d626c75653f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://php.net)[![Hyva Compatible](https://camo.githubusercontent.com/14365166e02048aff917dd0a015feecdae28499fbde05fa17abd4f7821ea1139/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f487976612d436f6d70617469626c652d3134623861363f6c6f676f3d616c70696e65646f746a73266c6f676f436f6c6f723d7768697465)](https://hyva.io)![Luma Compatible](https://camo.githubusercontent.com/3c1945ee121ef64870a6f3583c91ffdfb4d8ffc35809e7ce34ca549a357e1ded/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c756d612d436f6d70617469626c652d6f72616e6765)[![Packagist](https://camo.githubusercontent.com/eea108f2cad9eb0f885e54fe463f1c6346cf6594c28bae3f621bbf5a503a74d7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5061636b61676973742d6d616765326b697368616e2532466d6f64756c652d2d63726f73736c696e6b732d6f72616e67653f6c6f676f3d7061636b6167697374266c6f676f436f6c6f723d7768697465)](https://packagist.org/packages/mage2kishan/module-crosslinks)[![Upwork Top Rated Plus](https://camo.githubusercontent.com/6f72584179420c41ed90432fd2579a4ed36199d4229e8181d20f353c1c4ee4eb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5570776f726b2d546f702532305261746564253230506c75732d3134613830303f6c6f676f3d7570776f726b266c6f676f436f6c6f723d7768697465)](https://www.upwork.com/freelancers/~016dd1767321100e21)[![Website](https://camo.githubusercontent.com/f1ae86d28e2b505aee60f240d3e5508e390b0a8dc7a9b7ecf1b450fad862053f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f576562736974652d6b697368616e736176616c6979612e636f6d2d304439343838)](https://kishansavaliya.com)[![Get a Quote](https://camo.githubusercontent.com/0b6c02cc1ad00f11bf1b0164a9998734bd716473db36cc2a5c1517e3d3578d1b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4765742532306125323051756f74652d46726565253230457374696d6174652d444332363236)](https://kishansavaliya.com/get-quote)

> **Automatic internal linking for Magento 2.** Pick a keyword, pick a destination (a URL, a product by SKU, or a category by ID), and the module injects a safe anchor tag into every matching product, category, and CMS description at render time. Respects excluded tags (headings, buttons, existing anchors), per-page and per-keyword limits, optional nofollow, optional scheduled activation windows, and defends against `javascript:` / `data:` / `vbscript:` URL schemes.

Internal linking is one of the most durable on-site SEO signals a store can control, but building it by hand means editing every description whenever a new category launches. **Panth Crosslinks** replaces that manual work with a single admin grid: declare rules once, they apply everywhere.

---

Need Custom Magento 2 Development?
----------------------------------

[](#need-custom-magento-2-development)

 [ ![Get a Free Quote](https://camo.githubusercontent.com/eac8c45d21cff8b139ddc392325f3bd6c8266a6f3d7b23f15131c958f3d3c8d0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f476574253230612532304672656525323051756f74652532302545322538362539322d5265706c7925323077697468696e2532303234253230686f7572732d4443323632363f7374796c653d666f722d7468652d6261646765) ](https://kishansavaliya.com/get-quote)

### Kishan Savaliya

[](#kishan-savaliya)

**Top Rated Plus on Upwork**

[![Hire on Upwork](https://camo.githubusercontent.com/b69353d3c6e192f4d03cc36bb8883612004e32f54dd2dbcc1e700dd791acd875/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f486972652532306f6e2532305570776f726b2d546f702532305261746564253230506c75732d3134613830303f7374796c653d666f722d7468652d6261646765266c6f676f3d7570776f726b266c6f676f436f6c6f723d7768697465)](https://www.upwork.com/freelancers/~016dd1767321100e21)

### Panth Infotech Agency

[](#panth-infotech-agency)

[![Visit Agency](https://camo.githubusercontent.com/bbf04bdd2aff502082508568ec42ace3a7475c98756f596e2013056c89726ed6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f56697369742532304167656e63792d50616e7468253230496e666f746563682d3134613830303f7374796c653d666f722d7468652d6261646765266c6f676f3d7570776f726b266c6f676f436f6c6f723d7768697465)](https://www.upwork.com/agencies/1881421506131960778/)

---

Table of Contents
-----------------

[](#table-of-contents)

- [Preview](#preview)
- [Features](#features)
- [How It Works](#how-it-works)
- [Compatibility](#compatibility)
- [Installation](#installation)
- [Configuration](#configuration)
- [Managing Crosslink Rules](#managing-crosslink-rules)
- [Security](#security)
- [Troubleshooting](#troubleshooting)
- [Support](#support)

---

Preview
-------

[](#preview)

### Live walkthrough

[](#live-walkthrough)

End-to-end admin flow — configure the module, add a keyword rule, save, and see the crosslink appear on the storefront. Click to play.

[![Panth Crosslinks demo](docs/images/demo.gif)](docs/images/demo.gif)

### Admin

[](#admin)

**Global configuration** — toggle the module, cap links per page, set excluded tags, and enable time-based activation.

[![Admin configuration](docs/images/admin-config.png)](docs/images/admin-config.png)

**Rules grid** — list every crosslink rule with keyword, reference type, target URL, placement toggles, store scope, schedule, and priority. Supports filters, mass actions, and inline store column resolution (`All Store Views` / `Main Website → Default Store View`).

[![Admin grid](docs/images/admin-grid.png)](docs/images/admin-grid.png)

**Edit form — Category reference (all stores)** — link the keyword "bag" to Category by ID 4. Max Replacements = 2, Priority = 100, applies to product + category + CMS pages.

[![Admin edit form — category reference](docs/images/admin-edit-category.png)](docs/images/admin-edit-category.png)

**Edit form — Scheduled Custom URL** — Flash Sale rule active only between 01 Jan 2027 → 31 Dec 2027. Respects the store-level Time-Based Activation toggle.

[![Admin edit form — scheduled rule](docs/images/admin-edit-scheduled.png)](docs/images/admin-edit-scheduled.png)

### Storefront — Hyvä

[](#storefront--hyvä)

**Product description (Affirm Water Bottle)** — `backpack` → Endeavor Daytrip Backpack SKU, `bag` → Bags category. Injected inline with the `panth-crosslink` class.

[![Hyvä product description](docs/images/hyva-product-water-bottle.png)](docs/images/hyva-product-water-bottle.png)

**Product description (Zing Jump Rope)** — `fitness` → Fitness Equipment category.

[![Hyvä product — fitness](docs/images/hyva-product-jump-rope.png)](docs/images/hyva-product-jump-rope.png)

**Category description (Bags)** — `backpack`, `training`, `gear`, `bag`, `watch` rendered in the category intro.

[![Hyvä category — Bags](docs/images/hyva-category-bags.png)](docs/images/hyva-category-bags.png)

**CMS page (`/crosslink-test`)** — links for every seeded keyword in a single paragraph, capped by `max_links_per_page`.

[![Hyvä CMS page](docs/images/hyva-cms-test-page.png)](docs/images/hyva-cms-test-page.png)

### Storefront — Luma

[](#storefront--luma)

**Product description (Affirm Water Bottle)** — same rules render identically on Luma's default template.

[![Luma product description](docs/images/luma-product-water-bottle.png)](docs/images/luma-product-water-bottle.png)

**Product description (Zing Jump Rope)** — `fitness` → Fitness Equipment category.

[![Luma product — fitness](docs/images/luma-product-jump-rope.png)](docs/images/luma-product-jump-rope.png)

**Category description (Bags)** — `backpack`, `training`, `gear`, `bag`, `watch` rendered on the category intro.

[![Luma category — Bags](docs/images/luma-category-bags.png)](docs/images/luma-category-bags.png)

**CMS page (`/crosslink-test`)** — rules rendered via the CMS `FilterProvider` plugin on both block and page filters.

[![Luma CMS page](docs/images/luma-cms-test-page.png)](docs/images/luma-cms-test-page.png)

---

Features
--------

[](#features)

FeatureDescription**Keyword-to-anchor replacement**Case-insensitive, whole-word match. Inject into product descriptions, short descriptions, category descriptions, CMS pages, and CMS blocks.**Three reference types**`url` (direct URL), `product_sku` (resolved via `url_rewrite`), `category_id` (resolved via `url_rewrite`). SKU and category references are looked up once per request and cached.**Excluded tags**Keywords inside ``–``, ``, ``, ``, and `` are never touched. Configurable.**Per-keyword `max_replacements`**Cap how many times each rule fires across a single rendered page.**Per-page `max_links_per_page`**Global ceiling to avoid over-optimisation.**Time-based activation**Optional `active_from` / `active_to` gating per rule when the store-level toggle is enabled.**Store-scoped**`store_id = 0` rules apply everywhere; non-zero rules are scoped to a specific store view.**Priority**Higher-priority rules are processed first, so important keywords win the link budget.**Nofollow**Per-rule toggle to add `rel="nofollow"` to the rendered anchor.**URL Title**Optional `title` attribute on the rendered anchor.**Mass actions**Enable, disable, or delete many rules at once from the admin grid.**Safe rendering**Dangerous URL schemes (`javascript:`, `data:`, `vbscript:`, `file:`) are rejected at render time even if the row somehow got into the database.---

How It Works
------------

[](#how-it-works)

Six small pieces cooperate:

1. **Admin grid** at `panth_crosslinks/crosslink/index` — standard Magento 2 UI component listing backed by the `panth_seo_crosslink` table.
2. **Admin form** at `panth_crosslinks/crosslink/edit/id/` — reference-type switcher hides/shows the URL vs Reference-Value input depending on the selection.
3. **`ReplacementService`** — HTML-aware engine. Splits the incoming markup into *text segments*, *tag segments*, and *excluded-tag blocks* so keywords inside headings, anchors, buttons, scripts, and styles are never touched.
4. **`CatalogOutputPlugin`** — after-plugin on `Magento\Catalog\Helper\Output::productAttribute/categoryAttribute` — fires on `description` and `short_description` (product) and `description` (category).
5. **`CmsFilterPlugin` + `CrosslinkFilterDecorator`** — wraps the CMS template filter returned by `FilterProvider` so `filter()` runs the replacement engine *after* Magento has processed widgets and directives.
6. **Master switch + config** — admin toggles live at `panth_crosslinks/general/*` and are read per-store through a thin `Helper\Config` façade.

---

Compatibility
-------------

[](#compatibility)

RequirementSupportedMagento Open Source2.4.4, 2.4.5, 2.4.6, 2.4.7, 2.4.8Adobe Commerce2.4.4 — 2.4.8PHP8.1, 8.2, 8.3, 8.4Hyva Theme1.0+ (fully compatible)Luma ThemeNative supportPanth Core^1.0 (installed automatically)---

Installation
------------

[](#installation)

```
composer require mage2kishan/module-crosslinks
bin/magento module:enable Panth_Core Panth_Crosslinks
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
```

### Verify

[](#verify)

```
bin/magento module:status Panth_Crosslinks
# Module is enabled
```

Visit **Admin → Panth Infotech → Crosslinks** to see the empty grid.

---

Configuration
-------------

[](#configuration)

Navigate to **Stores → Configuration → Panth Infotech → Crosslinks**, or click **Panth Infotech → Crosslinks Configuration** in the admin sidebar.

SettingDefaultWhat it controls**Enable Auto Cross-Links**YesMaster switch. If No, no rules are injected regardless of grid state.**Max Links per Page**5Global ceiling on the total number of anchor tags injected into any single rendered page.**Excluded Tags**`h1,h2,h3,h4,h5,h6,a,button,script,style`Comma-separated list of HTML tags whose contents (including nested content) are never rewritten.**Enable Time-Based Activation**NoWhen Yes, each rule's `Active From` and `Active To` timestamps gate whether the rule fires. When No, those fields are ignored.Each setting is resolved at *store-view* scope, so you can have different link budgets and excluded tags per store.

---

Managing Crosslink Rules
------------------------

[](#managing-crosslink-rules)

Open **Admin → Panth Infotech → Crosslinks** to reach the grid.

### Fields

[](#fields)

FieldDescription**Keyword**Case-insensitive phrase the engine searches for. Whole-word boundaries only.**Reference Type**`Custom URL` — use the **URL** field directly. `Product by SKU` — look up the product's storefront path. `Category by ID` — look up the category's storefront path.**URL**Used only when Reference Type = Custom URL. Accepts relative paths (`/category/shoes.html`) or absolute URLs.**Reference Value**Used for SKU or category ID. Stored as a string for SKU, parsed as `int` for category IDs.**URL Title**Optional `title` attribute on the rendered anchor.**Store View**`0` applies to all stores; any non-zero value restricts the rule to that store view.**Active**Per-row enable/disable.**Active From / Active To**Only evaluated when the store-level time-activation flag is enabled.**Apply to Product / Category / CMS**Three independent checkboxes. Rules fire only in surfaces that are checked.**Max Replacements**Per-rule cap. After N hits across the current page, the rule stops matching.**Nofollow**Adds `rel="nofollow"` to the rendered anchor.**Priority**Higher values are processed first when the per-page link budget is tight.### Mass actions

[](#mass-actions)

Select rows and choose **Enable**, **Disable**, or **Delete** from the grid mass-action menu.

---

Security
--------

[](#security)

- Admin controllers extend `Magento\Backend\App\Action`. Every CRUD path declares its own `ADMIN_RESOURCE` constant and ACL is enforced via `_isAllowed()`.
- `Save` and `MassDelete` / `MassStatus` implement `HttpPostActionInterface` — GET requests are rejected. Form-key validation runs on every POST.
- All DB writes use prepared parameters (`$adapter->update($table, $row, ['id = ?' => $id])`) — no SQL concatenation.
- The anchor builder rejects dangerous URL schemes (`javascript:`, `data:`, `vbscript:`, `file:`) at render time and runs every user-supplied field (URL, title, matched text) through `htmlspecialchars(ENT_QUOTES | ENT_HTML5)`.
- The `Save` controller validates that the keyword does not contain `` to prevent admin users from stashing HTML into the pattern column.

---

Troubleshooting
---------------

[](#troubleshooting)

### No links appearing on the frontend

[](#no-links-appearing-on-the-frontend)

1. Flush caches: `bin/magento cache:flush`.
2. Confirm **Enable Auto Cross-Links** is Yes at the store-view scope you are browsing.
3. Confirm the rule's **Active** flag is Yes and its **Apply to Product / Category / CMS** checkbox matches the surface you are testing.
4. If using Time-Based Activation, check `Active From` / `Active To` cover *now*.

### A keyword is being linked inside a heading

[](#a-keyword-is-being-linked-inside-a-heading)

The headings tag list (`h1`–`h6`) is in **Excluded Tags** by default. If you removed it or misspelled a tag name, add it back.

### Too many links on one page

[](#too-many-links-on-one-page)

Lower **Max Links per Page** (config) or lower a rule's **Max Replacements**.

### A product SKU or category ID resolves to an empty link

[](#a-product-sku-or-category-id-resolves-to-an-empty-link)

Confirm the URL rewrite exists — `select request_path from url_rewrite where entity_type='product' and entity_id= and store_id in (0, )`. If no row exists, the rule's matched text is rendered as plain text (no broken anchor).

---

Support
-------

[](#support)

- **Agency:** [Panth Infotech on Upwork](https://www.upwork.com/agencies/1881421506131960778/)
- **Direct:** [kishansavaliya.com](https://kishansavaliya.com) — [Get a free quote](https://kishansavaliya.com/get-quote)

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance94

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

7

Last Release

32d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/343e344aa298f189db888b32d62f9202d31ced1a5ea23411850a63dc4a30299c?d=identicon)[kishansavaliya](/maintainers/kishansavaliya)

---

Top Contributors

[![KishanSavaliya](https://avatars.githubusercontent.com/u/16853223?v=4)](https://github.com/KishanSavaliya "KishanSavaliya (9 commits)")

---

Tags

seomagento2magento2 modulehyvalumapanthinternal-linkingcrosslinks

### Embed Badge

![Health badge](/badges/mage2kishan-module-crosslinks/health.svg)

```
[![Health](https://phpackages.com/badges/mage2kishan-module-crosslinks/health.svg)](https://phpackages.com/packages/mage2kishan-module-crosslinks)
```

###  Alternatives

[run-as-root/magento2-prometheus-exporter

Magento2 Prometheus Exporter

68353.9k](/packages/run-as-root-magento2-prometheus-exporter)[mollie/magento2

Mollie Payment Module for Magento 2

1131.8M12](/packages/mollie-magento2)[opengento/module-category-import-export

This module add the capability to import and export the categories from the back-office.

1310.2k1](/packages/opengento-module-category-import-export)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
