Skip to content

Latest commit

Β 

History

History
329 lines (240 loc) Β· 9.61 KB

File metadata and controls

329 lines (240 loc) Β· 9.61 KB

Canonical URL for Variants - Shopware 6 Plugin

πŸ‡©πŸ‡ͺ 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.

πŸ“‹ Features

  • βœ… 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

🎯 Why this Plugin?

The Problem

Product variants (e.g., T-shirt in different colors/sizes) each have their own URLs:

  • https://shop.com/tshirt-blue-m
  • https://shop.com/tshirt-blue-l
  • https://shop.com/tshirt-red-m
  • ...

This leads to duplicate content and can negatively affect SEO performance.

The Solution

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.

πŸ“¦ Installation

Requirements

  • 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

Via Composer (recommended)

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

Manual Installation

  1. Unzip plugin archive
  2. Upload folder to custom/plugins/WSCPluginSWCanonicalURLVariant/
  3. In Shopware Backend go to Extensions β†’ My Extensions and install
  4. Activate plugin
  5. Clear cache: bin/console cache:clear
  6. Compile theme: bin/console theme:compile

πŸš€ Configuration & Usage

Step 1: Find CustomFields

After installation, new CustomFields are automatically available in the product editor:

CustomField Set: P. SEO

Available Fields:

  1. Set canonical tag to main product (Boolean/Switch)
  2. New URL (Text field for custom URLs)

Step 2: Configure Product

⚠️ Important: The CustomFields must always be set on the main product (parent), not on individual variants!

  1. Navigate to Catalogues β†’ Products in Shopware Backend
  2. Open a main product with variants
  3. Scroll to "Specifications" or "Custom Fields" tab
  4. Find CustomField Set "P. SEO"

Option A: Automatic Parent URL (Recommended)

Usage:

  1. βœ… Activate "Set canonical tag to main product"
  2. ⬜ Leave "New URL" field empty
  3. 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">

Option B: Custom URL

Usage:

  1. βœ… Optional: Activate "Set canonical tag to main product"
  2. ✏️ Enter complete URL in "New URL" field
    • e.g., https://shop.com/special-category/product
  3. 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">

Priority Logic

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)

πŸ”§ Technical Details

Architecture

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

CustomFields

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

Events & Hooks

  • Event: ProductPageLoadedEvent
  • Event Priority: -100 (executed as one of the last)
  • Template Priority: 100 (high weight)

Workflow

  1. Product page loads β†’ ProductPageLoadedEvent is triggered
  2. Plugin checks: Is the current product a variant?
  3. If YES: Load parent product from database
  4. Check CustomFields:
    • Custom URL set? β†’ Use it
    • Otherwise: Boolean active? β†’ Generate parent URL
  5. Set meta information: page.metaInformation.canonical
  6. Template renders: Canonical tag in <head>

πŸ§ͺ Development & Testing

Local Development

# 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

Run Tests

# PHPUnit tests
vendor/bin/phpunit

# With coverage
vendor/bin/phpunit --coverage-html coverage/

Create Production ZIP

# With version number
./build.sh 1.0.0

# Creates: WSCPluginSWCanonicalURLVariant-1.0.0.zip

πŸ”„ Update

composer update wsc/plugin-sw-canonical-url-variant
bin/console plugin:update WSCPluginSWCanonicalURLVariant
bin/console cache:clear
bin/console theme:compile

πŸ—‘οΈ Uninstallation

bin/console plugin:deactivate WSCPluginSWCanonicalURLVariant
bin/console plugin:uninstall WSCPluginSWCanonicalURLVariant
bin/console cache:clear

⚠️ Note: The CustomFields are not automatically deleted during uninstallation to prevent data loss. If desired, they can be manually removed in the backend under Settings β†’ System β†’ Custom Fields.

πŸ› Debugging & Troubleshooting

Enable Debug Logs

Debug logs are present in the code and write to:

var/log/canonical_debug.log

Monitor log file:

tail -f var/log/canonical_debug.log

Common Issues

Problem: Canonical tag is not set

Solutions:

  1. Clear cache: bin/console cache:clear
  2. Recompile theme: bin/console theme:compile
  3. CustomField activated on main product? (not on variant!)
  4. Plugin activated? bin/console plugin:list
  5. Check debug logs

Problem: Template not loaded

Solutions:

  1. Check template priority (should be 100)
  2. Reinstall plugin after theme update
  3. Clear browser cache

πŸ“Š Performance

  • ⚑ 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

πŸ”’ Security

  • βœ… No external dependencies
  • βœ… Input validation for custom URLs
  • βœ… SQL injection safe through EntityRepository
  • βœ… XSS protection through Twig auto-escaping
  • βœ… No sensitive data in code

🀝 Support & Contact

πŸ“ Changelog

See CHANGELOG.md for details on all changes.

πŸ“„ License

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.

πŸ‘₯ Author

Christian SΓ€um Web SEO Consulting Web-SEO-Consulting.eu

πŸ’– Support

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:

Buy Me a Coffee GitHub Sponsors PayPal


⭐ If this plugin helps you, give us a star on GitHub!