composer require aliarteo/ali-sitemap-bundle
config/bundles.php:
return [
// ...
Aliarteo\AliSitemapBundle\AliSitemapBundle::class => ['all' => true],
];
config/packages/ali_sitemap.yaml with a basic sitemap:
ali_sitemap:
sitemaps:
- slug: "main"
nodes:
- type: "route"
route: "homepage"
title: "Homepage"
php bin/console ali:sitemap:generate
Sitemaps will be generated in public/sitemap/.Define static routes in ali_sitemap.yaml:
ali_sitemap:
sitemaps:
- slug: "pages"
nodes:
- type: "route"
route: "app_about"
title: "About Us"
priority: 0.8
- type: "route"
route: "app_contact"
title: "Contact"
priority: 0.6
type: "routes" to dynamically generate URLs from Doctrine entities:
- slug: "blog"
nodes:
- type: "routes"
entity: "App\Entity\Post"
route: "app_post_show"
route_parameters: { slug: "getSlug" }
title_method: "getTitle"
lastmod_method: "getUpdatedAt"
query: { published: true }
orderBy: { date: DESC }
{{ render(controller('AliarteoAliSitemapBundle:Sitemap:render', {'slug': 'blog'})) }}
php bin/console ali:sitemap:generate --env=prod
products, categories, and articles to avoid hitting URL limits (50,000 URLs per sitemap).type: "routes" nodes.SitemapGenerator service to cache generated XML for performance:
services:
App\Service\CachedSitemapGenerator:
decorates: 'ali_sitemap.sitemap_generator'
arguments: ['@ali_sitemap.sitemap_generator.decorated', '@cache.app']
ali_sitemap Twig function to generate links:
<a href="{{ ali_sitemap('blog') }}">Blog Sitemap</a>
return $this->render('sitemap/index.html.twig', [
'sitemaps' => $this->get('ali_sitemap.sitemap_index')->getSitemaps(),
]);
Route Resolution Failures
app_home may fail if not defined in config/routes.yaml.php bin/console debug:router to verify route names.Dynamic Node Queries
repository_method defaults to findBy, but complex queries may fail.query_builder for advanced queries (requires bundle extension):
- type: "routes"
entity: "App\Entity\Product"
route: "app_product_show"
query_builder: "App\Query\ProductSitemapQueryBuilder"
URL Generation
generate_url with absolute paths or configure the base URL in ali_sitemap.yaml:
ali_sitemap:
base_url: "%env(APP_URL)%"
XML Validation Errors
lastmod or priority) may cause parsing errors.Log Generation Enable debug mode to log sitemap generation:
ali_sitemap:
debug: true
Check var/log/dev.log for errors.
Dry Run
Use the --dry-run flag to preview changes without writing files:
php bin/console ali:sitemap:generate --dry-run
Custom Node Types
Extend the bundle by adding a new node type (e.g., api for GraphQL endpoints):
// src/NodeType/ApiNodeType.php
class ApiNodeType extends AbstractNodeType {
public function buildUrl(NodeInterface $node, UrlGeneratorInterface $urlGenerator): string {
return $node->getUrl(); // Custom logic for API endpoints
}
}
Register in config/services.yaml:
services:
App\NodeType\ApiNodeType:
tags: ['ali_sitemap.node_type']
Override Templates Customize the XML output by overriding Twig templates:
vendor/aliarteo/ali-sitemap-bundle/Resources/views/Sitemap/sitemap.xml.twig to templates/Sitemap/sitemap.xml.twig.<image:loc> for image sitemaps).Event Listeners Hook into sitemap generation events (e.g., to modify nodes before XML generation):
// src/EventListener/SitemapListener.php
class SitemapListener {
public function onPreGenerate(NodeCollection $nodes) {
foreach ($nodes as $node) {
if ($node instanceof RouteNode) {
$node->setPriority(1.0); // Force high priority for routes
}
}
}
}
Register the listener in config/services.yaml:
services:
App\EventListener\SitemapListener:
tags:
- { name: kernel.event_listener, event: ali_sitemap.pre_generate, method: onPreGenerate }
Default Values
default_priority and default_changefreq apply to all nodes unless overridden.default_changefreq: "monthly" to avoid specifying it per node.Base URL Handling
The bundle auto-detects the base URL from Symfony’s Router. For custom domains, explicitly set:
ali_sitemap:
base_url: "https://example.com"
robots.txt Integration
The bundle auto-generates robots.txt with sitemap links. To disable:
ali_sitemap:
generate_robots_txt: false
ali_sitemap:
generate_index: false
- type: "filtered_routes"
entity: "App\Entity\Article"
route: "app_article_show"
filter_callback: "App\Filter\PublishedFilter"
How can I help you explore Laravel packages today?