π©πͺ Deutsch | π«π· FranΓ§ais
A Shopware 6 plugin that automatically sets a canonical tag on product variants pointing to the main product or a custom URL - for better SEO performance and avoiding duplicate content.
- β Automatic canonical URL to main product for all variants
- β Custom canonical URL per product possible
- β Flexible control via CustomFields directly in the product editor
- β SEO-optimized for better search engine rankings
- β Priority logic for maximum flexibility
- β Easy to use without programming knowledge
Product variants (e.g., T-shirt in different colors/sizes) each have their own URLs:
https://shop.com/tshirt-blue-mhttps://shop.com/tshirt-blue-lhttps://shop.com/tshirt-red-m- ...
This leads to duplicate content and can negatively affect SEO performance.
This plugin sets a canonical tag on all variants pointing to the main product:
<link rel="canonical" href="https://shop.com/tshirt">This way, search engines recognize that all variants belong to the same product.
- Shopware Version: 6.5.x, 6.6.x or 6.7.x
- PHP Version: 8.4 or higher
- Server: Apache or Nginx with mod_rewrite
composer require wsc/plugin-sw-canonical-url-variant
bin/console plugin:refresh
bin/console plugin:install --activate WSCPluginSWCanonicalURLVariant
bin/console cache:clear
bin/console theme:compile- Unzip plugin archive
- Upload folder to
custom/plugins/WSCPluginSWCanonicalURLVariant/ - In Shopware Backend go to Extensions β My Extensions and install
- Activate plugin
- Clear cache:
bin/console cache:clear - Compile theme:
bin/console theme:compile
After installation, new CustomFields are automatically available in the product editor:
CustomField Set: P. SEO
Available Fields:
- Set canonical tag to main product (Boolean/Switch)
- New URL (Text field for custom URLs)
- Navigate to Catalogues β Products in Shopware Backend
- Open a main product with variants
- Scroll to "Specifications" or "Custom Fields" tab
- Find CustomField Set "P. SEO"
Usage:
- β Activate "Set canonical tag to main product"
- β¬ Leave "New URL" field empty
- Save product
Result: All variants automatically reference the main product via canonical tag.
Example:
Main Product: https://shop.com/tshirt
Variant Blue/M: https://shop.com/tshirt-blue-m
β <link rel="canonical" href="https://shop.com/tshirt">
Variant Red/L: https://shop.com/tshirt-red-l
β <link rel="canonical" href="https://shop.com/tshirt">
Usage:
- β Optional: Activate "Set canonical tag to main product"
- βοΈ Enter complete URL in "New URL" field
- e.g.,
https://shop.com/special-category/product
- e.g.,
- Save product
Result: All variants reference the entered custom URL.
Example:
New URL: https://shop.com/bestsellers/premium-tshirt
All variants β <link rel="canonical" href="https://shop.com/bestsellers/premium-tshirt">
The plugin works with the following priority order:
1. HIGHEST PRIORITY: New URL
ββ Field filled? β YES β Use this URL β
ββ Field filled? β NO β
2. MEDIUM PRIORITY: Boolean Field
ββ Activated? β YES β Auto-generate parent URL β
ββ Activated? β NO β
3. LOWEST PRIORITY: Standard Shopware
ββ Variant references itself (default behavior)
WSCPluginSWCanonicalURLVariant/
βββ src/
β βββ Installer/
β β βββ CustomFieldInstaller.php # CustomFields installation
β βββ Resources/
β β βββ config/
β β β βββ services.xml # Symfony Service Container
β β β βββ custom_fields/
β β β βββ custom_field_sets.php # CustomField set definition
β β β βββ products/
β β β βββ products_canonical.php
β β βββ views/
β β βββ storefront/
β β βββ page/product-detail/
β β βββ meta.html.twig # Template override
β βββ Subscriber/
β β βββ CanonicalSubscriber.php # Event logic
β βββ WSCPluginSWCanonicalURLVariant.php # Main plugin class
βββ tests/
β βββ Unit/ # PHPUnit tests
βββ .github/
β βββ workflows/
β βββ ci.yml # CI/CD pipeline
βββ composer.json
βββ build.sh # Build script for ZIP
βββ README.md
| Field Name | Type | Description |
|---|---|---|
custom_produkte_wsc_seo_canonical_variant_aktiv |
Boolean | Activates/Deactivates automatic parent URL |
custom_produkte_wsc_seo_canonical_variant_newurl |
Text | Custom canonical URL |
- Event:
ProductPageLoadedEvent - Event Priority:
-100(executed as one of the last) - Template Priority:
100(high weight)
- Product page loads β
ProductPageLoadedEventis triggered - Plugin checks: Is the current product a variant?
- If YES: Load parent product from database
- Check CustomFields:
- Custom URL set? β Use it
- Otherwise: Boolean active? β Generate parent URL
- Set meta information:
page.metaInformation.canonical - Template renders: Canonical tag in
<head>
# Clone repository
git clone https://github.com/your-repo/WSCPluginSWCanonicalURLVariant.git
cd WSCPluginSWCanonicalURLVariant
# Install dependencies
composer install
# Run tests
composer test
# Check code style
composer cs-check# PHPUnit tests
vendor/bin/phpunit
# With coverage
vendor/bin/phpunit --coverage-html coverage/# With version number
./build.sh 1.0.0
# Creates: WSCPluginSWCanonicalURLVariant-1.0.0.zipcomposer update wsc/plugin-sw-canonical-url-variant
bin/console plugin:update WSCPluginSWCanonicalURLVariant
bin/console cache:clear
bin/console theme:compilebin/console plugin:deactivate WSCPluginSWCanonicalURLVariant
bin/console plugin:uninstall WSCPluginSWCanonicalURLVariant
bin/console cache:clearDebug logs are present in the code and write to:
var/log/canonical_debug.log
Monitor log file:
tail -f var/log/canonical_debug.logProblem: Canonical tag is not set
Solutions:
- Clear cache:
bin/console cache:clear - Recompile theme:
bin/console theme:compile - CustomField activated on main product? (not on variant!)
- Plugin activated?
bin/console plugin:list - Check debug logs
Problem: Template not loaded
Solutions:
- Check template priority (should be 100)
- Reinstall plugin after theme update
- Clear browser cache
- β‘ Minimal overhead: Only one additional event subscriber
- π― Efficient caching: Uses Shopware's entity cache
- π No JavaScript: Pure server-side solution
- πΎ Lightweight: < 50 KB plugin size
- β No external dependencies
- β Input validation for custom URLs
- β SQL injection safe through EntityRepository
- β XSS protection through Twig auto-escaping
- β No sensitive data in code
- Email: Christian.Saeum@Web-SEO-Consulting.eu
- Website: Web-SEO-Consulting.eu
- Support: Support Page
See CHANGELOG.md for details on all changes.
GPL-3.0-or-later - see LICENSE file for details.
This plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation.
Christian SΓ€um Web SEO Consulting Web-SEO-Consulting.eu
Made with β€οΈ by WSC - Web SEO Consulting
This plugin is free and Open Source (GPL-3.0-or-later). If it helped you, I appreciate your support:
β If this plugin helps you, give us a star on GitHub!