setono / sylius-seo-plugin
SEO plugin for your Sylius store
Package info
github.com/Setono/sylius-seo-plugin
Type:sylius-plugin
pkg:composer/setono/sylius-seo-plugin
Fund package maintenance!
Requires
- php: >=8.2
- doctrine/orm: ^2.0 || ^3.0
- liip/imagine-bundle: ^2.0
- psr/event-dispatcher: ^1.0
- psr/log: ^1.1 || ^2.0 || ^3.0
- setono/composite-compiler-pass: ^1.2
- spatie/schema-org: ^3.23.1
- sylius/channel: ^2.0
- sylius/channel-bundle: ^2.0
- sylius/core: ^2.0
- sylius/core-bundle: ^2.0
- sylius/inventory: ^2.0
- sylius/locale: ^2.0
- sylius/product: ^2.0
- sylius/resource-bundle: ^1.12
- symfony/config: ^6.4 || ^7.4
- symfony/dependency-injection: ^6.4 || ^7.4
- symfony/event-dispatcher: ^6.4 || ^7.4
- symfony/form: ^6.4 || ^7.4
- symfony/http-foundation: ^6.4 || ^7.4
- symfony/http-kernel: ^6.4 || ^7.4
- symfony/routing: ^6.4 || ^7.4
- symfony/string: ^6.4 || ^7.4
- twig/twig: ^3.0
- webmozart/assert: ^1.11
Requires (Dev)
- api-platform/symfony: ^4.3.3
- payum/core: ^1.7.5
- phpunit/phpunit: ^10.5
- setono/sylius-plugin: ^2.0
- sylius/grid-bundle: ^1.15
- sylius/sylius: ~2.2.5
- symfony/browser-kit: ^6.4 || ^7.4
- symfony/debug-bundle: ^6.4 || ^7.4
- symfony/dom-crawler: ^6.4 || ^7.4
- symfony/dotenv: ^6.4 || ^7.4
- symfony/intl: ^6.4 || ^7.4
- symfony/property-info: ^6.4 || ^7.4
- symfony/serializer: ^6.4 || ^7.4
- symfony/web-profiler-bundle: ^6.4 || ^7.4
- symfony/webpack-encore-bundle: ^2.2
This package is auto-updated.
Last update: 2026-06-22 13:18:45 UTC
README
Add the SEO features that Sylius is missing — structured data, Open Graph metadata and a manageable
robots.txt — with sensible defaults and zero template changes.
Once installed, the plugin automatically enriches your storefront's <head> on every page, so search
engines and social networks understand your catalog out of the box.
Features
-
🔎 Schema.org structured data (JSON-LD) — automatically generates and renders structured data for your storefront:
OnlineStoreandWebSiteon the homepage (theWebSitenode can expose a Sitelinks Search Box)Product/ProductGroupon product pages, including images and offers (price, availability, canonical variant URLs)
The data is rendered as a single JSON-LD graph in the shop
<head>. -
📣 Open Graph metadata — emits
<meta property="og:*">tags (title, description, site name, locale, images, …) for rich link previews on social platforms, populated from your channel and products. -
🤖 robots.txt management — edit a
robots.txtper channel straight from the admin panel and serve it at/robots.txt. The content is rendered as a Twig template, so it can be dynamic. -
🧩 Extensible by design — add or override any fact in the structured data with a tagged data mapper, or hook into the dedicated events. Nothing is hardcoded.
-
🌍 Translations — the admin UI ships with translations for 16 locales.
Requirements
| Package | Version |
|---|---|
| PHP | >= 8.2 |
| Symfony | 6.4 or 7.4 |
| Sylius | ^2.0 |
Using Sylius 1.x? Use the
1.xbranch (^1.0) instead.
Installation
1. Require the plugin
composer require setono/sylius-seo-plugin
2. Register the plugin
# config/bundles.php return [ // ... Setono\SyliusSEOPlugin\SetonoSyliusSEOPlugin::class => ['all' => true], ];
3. Import the routing
# config/routes/setono_sylius_seo.yaml setono_sylius_seo: resource: "@SetonoSyliusSEOPlugin/config/routes.yaml"
4. Implement ChannelInterface
The plugin stores the robots.txt content on your channel. Implement the plugin's ChannelInterface
and use the ChannelTrait on your Channel entity:
<?php declare(strict_types=1); namespace App\Entity\Channel; use Doctrine\ORM\Mapping as ORM; use Setono\SyliusSEOPlugin\Model\ChannelInterface; use Setono\SyliusSEOPlugin\Model\ChannelTrait; use Sylius\Component\Core\Model\Channel as BaseChannel; #[ORM\Entity] #[ORM\Table(name: 'sylius_channel')] class Channel extends BaseChannel implements ChannelInterface { use ChannelTrait; }
5. Update your database schema
php bin/console doctrine:migrations:diff php bin/console doctrine:migrations:migrate -n
That's it — structured data and Open Graph tags are now rendered on your storefront automatically.
Usage
Structured data & Open Graph
There is nothing to wire up in your templates. The plugin injects its output into the shop <head>
via Sylius Twig Hooks, so visiting the homepage or a product page already produces the JSON-LD graph
and the og:* meta tags. Use Google's
Rich Results Test to verify the structured data.
robots.txt
Go to Admin → Channels → (edit a channel) and fill in the Robots.txt field. The content is
served at /robots.txt for that channel's domain.
If a physical
public/robots.txtfile exists it is served by your web server and shadows this route. The admin form warns you when that is the case.
Configuration
All structured data features are enabled by default. The full configuration with its defaults:
# config/packages/setono_sylius_seo.yaml setono_sylius_seo: # Service id of the canonical product variant URL generator. Override with your own implementation. product_variant_url_generator: 'Setono\SyliusSEOPlugin\UrlGenerator\ProductVariantUrlGenerator' structured_data: product: enabled: true online_store: enabled: true website: # Disabled by default. Enable it to add a WebSite node with a Sitelinks Search Box. enabled: false search_url_template: route: app_shop_search # your own route handling search queries query_parameter: q # the query parameter that route expects
To turn a feature off, disable it:
setono_sylius_seo: structured_data: product: enabled: false
Extending
Add or override structured data
Each Schema.org type is built by a set of data mappers. To add a new fact, create a class implementing the relevant interface — it is autoconfigured and picked up automatically:
| Schema.org type | Interface to implement |
|---|---|
| Product | Setono\SyliusSEOPlugin\DataMapper\Product\ProductDataMapperInterface |
| Product group | Setono\SyliusSEOPlugin\DataMapper\ProductGroup\ProductGroupDataMapperInterface |
| Online store | Setono\SyliusSEOPlugin\DataMapper\OnlineStore\OnlineStoreDataMapperInterface |
| Website | Setono\SyliusSEOPlugin\DataMapper\Website\WebsiteDataMapperInterface |
use Setono\SyliusSEOPlugin\DataMapper\Product\ProductDataMapperInterface; use Spatie\SchemaOrg\Product; use Sylius\Component\Core\Model\ProductVariantInterface; final class MpnProductDataMapper implements ProductDataMapperInterface { public function map(ProductVariantInterface $productVariant, Product $product): void { // enrich the generated Schema.org Product with your own data $product->mpn($productVariant->getCode()); } }
Events
After each object is added to the graph the plugin dispatches an event you can subscribe to in order to extend or replace the generated data:
Setono\SyliusSEOPlugin\Event\OnlineStoreAddedToGraphSetono\SyliusSEOPlugin\Event\ProductAddedToGraphSetono\SyliusSEOPlugin\Event\ProductGroupAddedToGraphSetono\SyliusSEOPlugin\Event\WebsiteAddedToGraph
Contributing
composer install composer phpunit # run the unit tests composer analyse # run static analysis composer check-style # check the coding standard
See the test application in tests/Application for a runnable Sylius store with the plugin installed.
License
This plugin is released under the MIT License.