Weave Code
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

core23/sitemap-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install via Composer:
    composer require nucleos/sitemap-bundle
    
  2. Enable the Bundle in config/bundles.php:
    return [
        // ...
        Nucleos\SitemapBundle\NucleosSitemapBundle::class => ['all' => true],
    ];
    
  3. Configure Routes in config/routes.yaml:
    nucleos_sitemap:
        resource: "@NucleosSitemapBundle/Resources/config/routing.yml"
        prefix: /
    
  4. Generate a Basic Sitemap: Create a service or controller to define URLs dynamically. Example:
    use Nucleos\SitemapBundle\Sitemap\SitemapInterface;
    use Nucleos\SitemapBundle\Sitemap\SitemapUrl;
    
    class MySitemapService
    {
        public function getUrls(): array
        {
            return [
                new SitemapUrl('https://example.com/home', 'daily', '1.0', 'Homepage'),
                new SitemapUrl('https://example.com/blog', 'weekly', '0.8', 'Blog'),
            ];
        }
    }
    
  5. Register the Service in config/services.yaml:
    services:
        Nucleos\SitemapBundle\Sitemap\SitemapInterface: '@App\Service\MySitemapService'
    

First Use Case

Generate a sitemap for a Symfony application with dynamic routes (e.g., blog posts, product pages). Use the SitemapUrl class to define URLs with priority and change frequency, then inject the service into a controller or command to render the XML.


Implementation Patterns

Dynamic URL Generation

  1. Service-Based Approach: Create a service implementing SitemapInterface to fetch URLs dynamically (e.g., from a database or API). Example:

    class BlogSitemapService implements SitemapInterface
    {
        public function getUrls(): array
        {
            $posts = $this->postRepository->findAllPublished();
            return array_map(fn($post) => new SitemapUrl(
                route('post.show', ['slug' => $post->slug]),
                'weekly',
                '0.9',
                $post->title
            ), $posts);
        }
    }
    
  2. Event-Driven Updates: Trigger sitemap regeneration after content changes (e.g., post.published event):

    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Nucleos\SitemapBundle\Event\SitemapRegenerateEvent;
    
    class SitemapSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [
                'post.published' => 'onPostPublished',
            ];
        }
    
        public function onPostPublished(PostPublishedEvent $event)
        {
            $this->eventDispatcher->dispatch(new SitemapRegenerateEvent());
        }
    }
    
  3. Caching: Cache the generated sitemap to reduce server load. Use Symfony’s cache system:

    # config/packages/nucleos_sitemap.yaml
    nucleos_sitemap:
        cache_enabled: true
        cache_lifetime: 3600  # 1 hour
    

Integration with Symfony

  1. Route-Based URLs: Generate URLs using Symfony’s UrlGeneratorInterface for consistency:

    $urlGenerator = $this->container->get('router');
    $url = $urlGenerator->generate('post.show', ['slug' => $post->slug]);
    
  2. Custom Templates: Override the default XML template by extending the bundle’s SitemapRenderer:

    {# templates/NucleosSitemapBundle/sitemap.xml.twig #}
    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
        {% for url in urls %}
            <url>
                <loc>{{ url.loc }}</loc>
                <lastmod>{{ url.lastmod|date('Y-m-d') }}</lastmod>
                <changefreq>{{ url.changefreq }}</changefreq>
                <priority>{{ url.priority }}</priority>
            </url>
        {% endfor %}
    </urlset>
    
  3. Multi-Language Support: Generate separate sitemaps for each locale using route parameters:

    $url = $urlGenerator->generate('post.show', [
        'slug' => $post->slug,
        '_locale' => 'en',
    ]);
    

Advanced Patterns

  1. Sitemap Index: Split large sitemaps into multiple files and generate a sitemap-index.xml:

    # config/packages/nucleos_sitemap.yaml
    nucleos_sitemap:
        sitemap_index:
            enabled: true
            max_urls_per_sitemap: 5000
    
  2. Conditional URL Inclusion: Filter URLs based on business logic (e.g., exclude drafts):

    public function getUrls(): array
    {
        return array_filter($this->getAllUrls(), fn($url) => !$url->isDraft());
    }
    
  3. External URLs: Include external URLs (e.g., third-party resources) with SitemapUrl:

    new SitemapUrl('https://external-site.com/resource', 'monthly', '0.5', 'External Resource');
    

Gotchas and Tips

Common Pitfalls

  1. URL Generation Issues:

    • Problem: URLs generated via SitemapUrl may not resolve correctly if the route is undefined or parameters are invalid.
    • Fix: Use UrlGeneratorInterface to generate absolute URLs and validate routes:
      try {
          $url = $urlGenerator->generate('post.show', ['slug' => $post->slug], UrlGeneratorInterface::ABSOLUTE_URL);
      } catch (\Exception $e) {
          // Log or skip invalid URLs
      }
      
  2. Caching Conflicts:

    • Problem: Cached sitemaps may not reflect recent changes if the cache is not invalidated.
    • Fix: Clear the cache manually or use events to trigger regeneration:
      php bin/console cache:clear nucleos_sitemap
      
  3. XML Validation Errors:

    • Problem: Invalid XML (e.g., missing loc tag) may cause search engines to ignore the sitemap.
    • Fix: Validate the output using an XML validator or manually inspect the generated file.
  4. Duplicate URLs:

    • Problem: Duplicate entries can occur if the same URL is added multiple times.
    • Fix: Use array_unique or a SplObjectStorage to deduplicate URLs:
      $urls = array_unique($this->getUrls(), SplObjectStorage::class);
      
  5. Locale Mismatches:

    • Problem: URLs generated without locale may not work in multi-language setups.
    • Fix: Always include _locale in route parameters or use the router to generate locale-aware URLs.

Debugging Tips

  1. Log Generated URLs: Enable debug logging to inspect URLs before rendering:

    # config/packages/monolog.yaml
    handlers:
        sitemap:
            type: stream
            path: "%kernel.logs_dir%/sitemap.log"
            level: debug
    

    Log URLs in your SitemapInterface implementation:

    $this->logger->debug('Generated sitemap URLs', ['urls' => $urls]);
    
  2. Inspect Cache: Check if the cache is working as expected:

    php bin/console cache:pool:list
    php bin/console cache:pool:clear nucleos_sitemap
    
  3. Validate XML: Use an online tool like XML Validation to check the generated sitemap.xml.

Configuration Quirks

  1. Default Change Frequency: The bundle defaults to 'daily' for all URLs. Override this in your SitemapUrl constructor or set a default in the bundle config:

    # config/packages/nucleos_sitemap.yaml
    nucleos_sitemap:
        default_changefreq: 'weekly'
    
  2. Priority Clamping: The priority field in SitemapUrl is clamped between 0.0 and 1.0. Ensure values are within this range:

    $priority = min(1.0, max(0.0, $yourPriorityValue));
    
  3. Lastmod Precision: The lastmod field should be in YYYY-MM-DD format. Use Symfony’s DateTime utilities to format dates:

    $lastmod = $post->updatedAt->format('Y-m-d');
    

Extension Points

  1. Custom URL Providers: Extend the bundle
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle