abdellahramadan/seo-bundle
Symfony SEO bundle providing meta tags, Open Graph/Twitter cards, Schema.org structured data, sitemap generation, breadcrumbs, Google Tag and Meta Pixel integration, plus dev-mode SEO profiling. Configure via DI or Twig helpers for easy template rendering.
Installation:
composer require rami/seo-bundle
Ensure Abdellahramadan\SeoBundle\SeoBundle::class is registered in config/bundles.php.
First Use Case:
Inject MetaTagsManagerInterface into a controller to set basic SEO metadata:
use Abdellahramadan\SeoBundle\Metas\MetaTagsManagerInterface;
public function index(MetaTagsManagerInterface $metaTags): Response
{
$metaTags->setTitle('Page Title')
->setDescription('Page description for search engines');
return $this->render('page.html.twig');
}
Where to Look First:
config/packages/abdellahramadan_seo.yaml (default config).src/Controller/ for controller-level SEO logic.Controller-Level SEO: Use dependency injection to set metadata dynamically:
public function show(MetaTagsManagerInterface $metaTags, $id)
{
$metaTags->setTitle("Product #$id")
->setCanonicalUrl($this->generateUrl('product_show', ['id' => $id]));
}
Twig Integration: Extend templates with SEO blocks:
{% block meta_tags %}
{{ seo.meta_tags() }}
{% endblock %}
Structured Data (Schema):
Define schema in YAML (e.g., config/packages/abdellahramadan_seo.yaml):
seo:
schema:
'@product': '@App\Dto\ProductSchema'
Implement SchemaInterface in a DTO:
class ProductSchema implements SchemaInterface
{
public function getSchema(array $data): array
{
return [
'@context' => 'https://schema.org',
'@type' => 'Product',
'name' => $data['name'],
// ...
];
}
}
Sitemap Generation:
Configure routes in config/packages/abdellahramadan_seo.yaml:
seo:
sitemap:
routes:
- { route: 'homepage' }
- { route: 'product_list' }
Generate via CLI:
php bin/console seo:sitemap:generate
OpenGraph/Twitter Cards: Set dynamic properties in controllers:
$metaTags->setOpenGraphImage($product->getImageUrl())
->setTwitterCard('summary_large_image');
KernelEvents::VIEW to modify SEO metadata globally:
public function onKernelView(ViewEvent $event)
{
$metaTags = $event->getController()[1]->getMetaTags();
$metaTags->setKeywords('seo, laravel');
}
config/packages/dev/abdellahramadan_seo.yaml for staging/production.seo.cache.enabled in config to cache metadata (reduces DB/controller calls).Missing Dependencies:
twig and symfony/twig-bridge are installed (required for Twig integration).symfony/routing must be configured.Schema Validation:
@context in schema DTOs causes malformed JSON-LD.Sitemap Generation:
GET with side effects)./sitemap.xml. Customize via seo.sitemap.url in config.Profiler Overhead:
seo.profiler.enabled) adds latency. Disable in production:
seo:
profiler:
enabled: "%kernel.debug%"
Twig Template Conflicts:
{{ seo.meta_tags() }} renders nothing, check:
Abdellahramadan\SeoBundle\Twig\SeoExtension).meta_tags block.config/packages/dev/monolog.yaml:
handlers:
seo:
type: stream
path: "%kernel.logs_dir%/seo.log"
level: debug
channels: ["seo"]
php bin/console seo:sitemap:validate.php bin/console cache:clear.Custom Meta Tags:
Extend MetaTagsManager by implementing MetaTagsInterface:
class CustomMetaTags implements MetaTagsInterface
{
public function setCustomTag(string $name, string $content): self
{
// ...
}
}
Register as a service:
services:
App\Service\CustomMetaTags:
tags: ['seo.meta_tags_manager']
Dynamic Schema:
Use SchemaManagerInterface to fetch schema data from APIs:
public function getSchema(array $data): array
{
$product = $this->productApi->fetch($data['id']);
return $this->schemaFactory->createProductSchema($product);
}
Breadcrumb Customization:
Override the default BreadcrumbGenerator:
services:
App\Generator\CustomBreadcrumbGenerator:
decorates: 'abdellahramadan_seo.breadcrumb_generator'
arguments: ['@abdellahramadan_seo.breadcrumb_generator']
Google Tag Manager (GTM):
Combine with symfony/webpack-encore to inject GTM dynamically:
{{ seo.google_tag() }}
{{ encore_entry_script_tags('gtm') }}
Default Values: All options are nullable. Explicitly set null to override defaults:
seo:
meta_tags:
default:
author: null # Disables default author
Priority Order: Metadata is merged in this order:
seo.route).Sitemap Frequency:
Use seo.sitemap.frequency to set <changefreq> (e.g., daily, weekly). Default is monthly.
How can I help you explore Laravel packages today?