Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sitemap Bundle Laravel Package

skuola/sitemap-bundle

Symfony bundle for generating XML sitemaps from your application's routes and content. Configure sitemap sections, URLs, priorities, and change frequencies, then expose a search-engine-ready sitemap.

View on GitHub
Deep Wiki
Context7

Getting Started

Read the framework boundary first. This is a Symfony 2 bundle, not a Laravel package. It has no service provider, facade, config publishing, or Blade view. Before anything else, confirm which framework you're actually in:

  • Symfony 2.x/3.x app: usable, follow the steps below.
  • Laravel app: stop. Skip to Gotchas and Tips — you cannot composer require this into Laravel and call it a day. Use spatie/laravel-sitemap instead.

Where to look first, in order:

  1. README.md on github.com/skuola/SitemapBundle — bundle class name, install steps, and the routing import line.
  2. composer.json — PHP constraint and Symfony version constraint. Last release was 2016, so expect php: >=5.5 and Symfony 2.8/3.0-era requirements. This is the compatibility gate.
  3. DependencyInjection/ and Resources/config/services.* — how the generator/controller is wired, and which service IDs you can override.
  4. Controller/ and Resources/views/ — the actual XML-rendering logic and template.

Minimal steps (Symfony):

composer require skuola/sitemap-bundle
// app/AppKernel.php
$bundles = [
    // ...
    new Skuola\SitemapBundle\SkuolaSitemapBundle(), // verify exact namespace in the repo
];
# app/config/routing.yml
sitemap:
    resource: "@SkuolaSitemapBundle/Resources/config/routing.xml" # confirm path in repo

First use case: expose /sitemap.xml listing your static pages plus one dynamic entity (e.g. blog posts from a Doctrine repository). Hit the route in a browser, view source, and validate the XML with xmllint --noout sitemap.xml or a sitemap validator. That single loop tells you whether the bundle's URL registration style fits your app.

Implementation Patterns

Determine the URL registration style before writing anything. Symfony 2 sitemap bundles typically take one of two shapes — find out which this one uses by grepping the repo for Provider, Generator, Url, or Annotation:

  • Annotation/config-driven: you declare routes or config entries and the bundle enumerates them. Easiest static-page story, weakest for paginated entity listings.
  • Service/provider-driven: you implement an interface returning Url value objects. More code, but the right fit for dynamic content.

Static + dynamic hybrid (the common real-world setup):

// Controller or provider service
$urls = [];

// Static pages
foreach (['/', '/about', '/contact'] as $path) {
    $urls[] = (new Url())->setLoc($this->generateUrl($path))->setPriority(0.8);
}

// Dynamic: blog posts — select only needed columns to avoid N+1
$posts = $postRepo->createQueryBuilder('p')
    ->select('p.slug', 'p.updatedAt')
    ->getQuery()
    ->getResult();

foreach ($posts as $post) {
    $urls[] = (new Url())
        ->setLoc($this->generateUrl('post_show', ['slug' => $post->getSlug()]))
        ->setLastmod($post->getUpdatedAt())   // W3C datetime
        ->setChangefreq('weekly')
        ->setPriority(0.6);
}

Sitemap index for large sites. Anything over ~50k URLs or 50 MB should be split into sitemap-1.xml, sitemap-2.xml, … and sitemap.xml becomes an index referencing them. Most 2016-era Symfony bundles don't do this for you — hand-roll it or use a paginated provider.

Caching is mandatory, not optional. Sitemap generation is an expensive full-table scan plus route generation. Wrap it:

# services.yml
sitemap.cached_generator:
    class: AppBundle\Sitemap\CachedGenerator
    decorates: skuola_sitemap.generator   # verify the real service id in the repo
    arguments: ['@sitemap.cached_generator.inner', '@cache.app']

Invalidate on content publish via a Doctrine postPersist/postUpdate listener or a kernel event — not on every request.

Prefer console-driven static output. For anything with more than a few hundred URLs, add a bin/console app:sitemap:generate command that writes web/sitemap.xml and let nginx/Apache serve it. Skip the controller entirely in that pattern. It removes generation from the request path and makes regeneration debuggable.

Multilingual (hreflang). If you're running a localized site (JMS i18n routing or similar), generate one sitemap per locale plus an index. Most bundles of this vintage have no hreflang support — verify before promising it to a stakeholder.

Gotchas and Tips

  • The Laravel mismatch is the headline. This bundle boots through Symfony's kernel and service container. In Laravel you'd have to reimplement its DI wiring, Twig rendering, and routing by hand — for a 4-star, 8-year-stale package. That's not leverage, that's a liability. Use spatie/laravel-sitemap: actively maintained, Laravel 10/11 compatible, supports sitemap indexes plus image/news sitemaps. A scheduled console command calling ->writeToFile() is ten lines.
  • Maintenance risk is severe. Last release 2016, 0 dependents, no visible activity. Assume it does not run cleanly on PHP 8.x or Symfony 5+. Budget for a fork, or pin the whole app to EOL dependencies — usually the wrong trade.
  • Confirm the exact bundle class and service IDs from the repo before copying snippets. Old Symfony 2 READMEs are frequently incomplete or out of sync with the code. bin/console debug:container | grep sitemap (or container:debug on 2.x) settles it fast.
  • XML escaping. URLs with query strings (&) must be escaped or parsers reject the file. Check whether the bundle's Twig template uses {{ url }} (autoescaped) or {{ url|raw }} (not). Fix it yourself if unsure.
  • lastmod format. Must be W3C datetime: Y-m-d\TH:i:sP (or Y-m-d). Passing a raw DB datetime string through unformatted is the most common validator failure.
  • Content-Type and robots. Serve as application/xml; charset=UTF-8 and add the Sitemap: https://example.com/sitemap.xml line to robots.txt. Neither the bundle nor the framework does this for you.
  • Memory and streaming. For big sites, stream with Symfony's StreamedResponse rather than concatenating one giant string — otherwise you'll hit memory_limit around the tens-of-thousands of URLs mark.
  • Blank XML is usually a Twig error. Check var/logs/dev.log; a swallowed exception during template render produces an empty 200 response that looks like "no URLs." Also confirm the route is registered with bin/console router:debug (Symfony) before blaming the bundle.
  • Extension points. If the generator is too rigid, override its service definition ID in services.yml (Symfony 2 has no ergonomic service decoration) or subclass the controller. That's the supported escape hatch — expect to need it for anything beyond the bundle's defaults.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect