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

Seo Bundle Laravel Package

axstrad/seo-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle to your composer.json:

    composer require axstrad/seo-bundle
    

    Enable it in config/bundles.php:

    return [
        // ...
        Axstrad\SeoBundle\AxstradSeoBundle::class => ['all' => true],
    ];
    
  2. Configuration Extend Symfony-CMF's SEO bundle config in config/packages/axstrad_seo.yaml:

    axstrad_seo:
        doctrine: true  # Enable Doctrine ORM support
        routes:
            home: /       # Map routes to SEO entities
    
  3. First Use Case Annotate an entity with @Seo and define metadata:

    use Axstrad\SeoBundle\Annotation\Seo;
    
    /**
     * @Seo(
     *     title="Homepage",
     *     description="Welcome to our site",
     *     keywords="home, welcome"
     * )
     */
    class Homepage
    {
        // ...
    }
    

    Fetch SEO data in a controller:

    use Axstrad\SeoBundle\Service\SeoService;
    
    public function index(SeoService $seoService)
    {
        $seoData = $seoService->getSeoDataForRoute('/');
        return new Response($seoData->getTitle());
    }
    

Implementation Patterns

Workflows

  1. Entity-Based SEO

    • Use @Seo annotations on Doctrine entities (e.g., BlogPost, Product).
    • Dynamically generate metadata via entity methods:
      /**
       * @Seo(title="%title%", description="%excerpt%")
       */
      class BlogPost
      {
          public function getSeoTitle(): string
          {
              return $this->title . ' | ' . config('app.name');
          }
      }
      
  2. Route-Level SEO

    • Map routes to entities in config:
      axstrad_seo:
          routes:
              blog_post: /blog/{slug}
              product:    /product/{id}
      
    • Resolve SEO data in controllers:
      $seoData = $seoService->getSeoDataForRoute($request->getPathInfo());
      $this->renderSeo($seoData); // Custom method to inject into Twig
      
  3. Twig Integration Pass SEO data to templates:

    return $this->render('blog/post.html.twig', [
        'seo' => $seoService->getSeoDataForEntity($post),
    ]);
    

    Use in Twig:

    <title>{{ seo.title }}</title>
    <meta name="description" content="{{ seo.description }}">
    
  4. Dynamic Metadata Override SEO data per request:

    $seoData = $seoService->getSeoDataForEntity($entity);
    $seoData->setTitle('Custom Title - ' . $seoData->getTitle());
    

Integration Tips

  • Symfony-CMF: Combine with symfony-cmf/routing for route-aware SEO.
  • SonataAdmin: Extend SeoService to fetch SEO data for admin-generated entities.
  • APIs: Use SeoService to generate SEO headers for JSON responses:
    $response->headers->set('X-Seo-Title', $seoData->getTitle());
    

Gotchas and Tips

Pitfalls

  1. Doctrine Cache Invalidation

    • SEO annotations are cached by Doctrine. Clear cache after entity updates:
      php bin/console doctrine:cache:clear-metadata
      
    • Or manually invalidate:
      $seoService->invalidateSeoCacheForEntity($entity);
      
  2. Route Resolution Conflicts

    • Ensure axstrad_seo.routes maps to unique route patterns. Overlaps may cause unexpected behavior.
    • Debug with:
      $seoService->getRouteForPath('/ambiguous-path'); // Returns null if no match
      
  3. Annotation Parsing

    • Annotations must be parsed after Doctrine metadata is loaded. Avoid using @Seo in prePersist/preUpdate callbacks.
    • For dynamic metadata, use entity getters (e.g., getSeoTitle()) instead of annotation values.
  4. Legacy Symfony Versions

    • The bundle targets Symfony 2.3–2.6. Use with caution in newer versions (e.g., Symfony 4+ may require patches).

Debugging

  • Enable Debug Mode Add to config/packages/dev/axstrad_seo.yaml:

    axstrad_seo:
        debug: true
    

    Logs SEO resolution steps to var/log/dev.log.

  • Check Resolved Data Dump SEO data in a controller:

    dump($seoService->getSeoDataForRoute('/')->toArray());
    

Extension Points

  1. Custom Metadata Providers Implement Axstrad\SeoBundle\Provider\SeoMetadataProviderInterface to add logic:

    class CustomSeoProvider implements SeoMetadataProviderInterface
    {
        public function getMetadata(EntityManagerInterface $em, string $route, array $params)
        {
            if ($route === '/promo') {
                return new SeoData('Promo', 'Limited-time offer!');
            }
            return null;
        }
    }
    

    Register in config:

    axstrad_seo:
        providers:
            - App\Provider\CustomSeoProvider
    
  2. Override SeoData Class Extend Axstrad\SeoBundle\Model\SeoData to add custom fields:

    class ExtendedSeoData extends SeoData
    {
        private $canonicalUrl;
    
        public function setCanonicalUrl(string $url): self
        {
            $this->canonicalUrl = $url;
            return $this;
        }
    }
    

    Configure in services.yaml:

    services:
        Axstrad\SeoBundle\Model\SeoData: '@App\ExtendedSeoData'
    
  3. Event Listeners Listen for seo.metadata.resolved events to modify SEO data:

    $eventDispatcher->addListener('seo.metadata.resolved', function (SeoMetadataEvent $event) {
        $event->getSeoData()->setTitle('[Modified] ' . $event->getSeoData()->getTitle());
    });
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware