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

Seo Bundle Laravel Package

skuola/seo-bundle

skuola/seo-bundle provides a reusable SEO layer for PHP applications, helping centralize metadata configuration so pages can expose consistent titles, descriptions, and related tags. It reduces repetitive setup and keeps search-engine details easier to manage across a project.

View on GitHub
Deep Wiki
Context7

Getting Started

First, a reality check before you install anything: skuola/seo-bundle is a Symfony 2 bundle, not a Laravel package. It ships a SeoBundle class extending Symfony's Bundle, registers services via Symfony's DI container, and expects Symfony's kernel.bundles registration flow. It is not PSR-4-autoloaded into a Laravel ServiceProvider graph, has no Laravel service provider, no config/seo.php publishable stub, and no facade. Composer will happily require it, but nothing in Laravel will auto-discover or boot it.

Given 0 stars, 0 dependents, and a last release of 2017-04-18, also treat this as effectively unmaintained. A Laravel developer should look here only to mine it for ideas, not to install it.

Minimal steps if you insist on inspecting it:

composer require skuola/seo-bundle --no-scripts   # expect Symfony 2/3 constraint conflicts

More realistically, clone and read it:

git clone https://github.com/skuola/SeoBundle
cd SeoBundle
cat composer.json          # note Symfony framework-bundle constraint
ls src/                    # find the Bundle class, Twig extensions, helpers

Where to look first, in order:

  1. composer.json — confirm the Symfony version constraint. If it pins ~2.x, it will not resolve alongside modern Laravel (which pulls Symfony 6/7 components). This is usually where the install dies.
  2. The bundle's DependencyInjection Extension and services.yml — this tells you what the utilities actually are (meta-tag builders, slug helpers, sitemap/robots generators are the usual suspects in a bundle like this).
  3. Any Twig extension classes — those hold the reusable logic most worth porting.

First use case: don't try to wire it in. Instead, pick the one utility you want (e.g. canonical-URL or meta-tag generation), port that class into app/Support/Seo, and write a small Laravel wrapper around it. That gets you 95% of the value with 0% of the Symfony-2 baggage.

Implementation Patterns

If you're evaluating or porting rather than installing, these are the patterns that map cleanly to Laravel.

Pattern 1 — Port the helper as a plain class + facade. Symfony bundles wrap utilities in services resolved from the container. In Laravel, hoist the logic into a standalone class and bind it:

// app/Support/Seo/MetaBuilder.php  (ported logic, no Symfony deps)
namespace App\Support\Seo;

class MetaBuilder
{
    protected array $tags = [];

    public function title(string $title): static
    {
        $this->tags['title'] = $title;
        return $this;
    }

    public function description(string $desc): static
    {
        $this->tags['description'] = $desc;
        return $this;
    }

    public function canonical(string $url): static
    {
        $this->tags['canonical'] = $url;
        return $this;
    }

    public function render(): string
    {
        // build <title>, <meta name="description">, <link rel="canonical">
    }
}

Bind it as a singleton so controllers, middleware, and Blade all share state:

// app/Providers/SeoServiceProvider.php
$this->app->singleton(MetaBuilder::class, fn () => new MetaBuilder());

Pattern 2 — Mid-stack enrichment via middleware. The idiomatic Laravel seam for SEO metadata is a middleware that sets defaults (site name, canonical from url()->current(), robots directive) and lets controllers override:

class SeoDefaults
{
    public function handle($request, Closure $next)
    {
        $seo = app(MetaBuilder::class);
        $seo->canonical($request->url());
        if ($request->query('page', 1) > 1) {
            $seo->noindex(); // paginated archives
        }
        return $next($request);
    }
}

Pattern 3 — Blade component over a Twig extension. If the bundle offers Twig functions like seo_meta(), replace them with an anonymous Blade component:

{{-- resources/views/components/seo.blade.php --}}
<title>{{ $seo->get('title') ?? config('app.name') }}</title>
<meta name="description" content="{{ $seo->get('description') }}">
<link rel="canonical" href="{{ $seo->get('canonical') }}">

Pattern 4 — Sitemap as an artisan command. Most Symfony SEO bundles include sitemap generation. In Laravel, model that as php artisan seo:sitemap writing to public/sitemap.xml, scheduled via routes/console.php. This is more maintainable than any container-wired generator.

Integration tips when reading the source: Symfony's Bundle::boot() and Extension::load() are analogous to Laravel's register()/boot() — map them one-to-one and you can mechanically translate most of the package. Anything using KernelInterface, ContainerInterface, or RequestStack from Symfony has a Laravel sibling ($app, app(), request()).

Gotchas and Tips

It will not install into a modern Laravel. The hardest constraint is Composer's dependency graph: a 2017 Symfony 2 bundle pins symfony/framework-bundle ~2.3|~3.0, and Laravel 9+ requires Symfony 5/6/7 components. composer require will fail with an unresolvable conflict. Workarounds (--ignore-platform-reqs, replace blocks) are a rabbit hole and will bite you at deploy time.

No framework auto-discovery. Laravel's package discovery reads extra.laravel.providers from composer.json. This bundle has no such key — it has Symfony's extra.symfony semantics or nothing at all. You'd have to manually register a service provider that doesn't exist.

Namespacing mismatch. The package namespace is almost certainly Skuola\SeoBundle\ (Symfony convention: Vendor\BundleName\). Laravel code expecting Skuola\Seo\ or similar will not autoload. Check composer.json's psr-4 block before assuming anything.

Unmaintained means no security updates. Last tagged release 2017. Even if you could get it running, you're shipping a class written against PHP ~5.6/7.0 idioms — no typed properties, no ??=-friendly patterns, likely count() on non-countables, maybe each(). Modern PHP (8.2+) will surface deprecations or fatal errors.

Debugging if you do wire it up: the failure points, in order, are (1) autoloader can't find the Bundle class — check psr-4 mapping and run composer dump-autoload; (2) service not found — the bundle expects its services.yml loaded via Symfony's container, which Laravel has no equivalent for; (3) Twig function undefined — Laravel uses Blade, not Twig, so any {{ seo_meta() }} in a template is dead on arrival.

Extension points worth stealing. The genuinely reusable ideas in a bundle like this are the small ones: a slugifier, a meta-tag renderer, canonical-URL normalization (strip trailing slashes, force lowercase host, drop tracking query params), and robots.txt/sitemap.xml shape. Those are 50–200 line classes — port them directly rather than depending on the package.

Tip — evaluate alternatives first. For Laravel, mature replacements exist for every capability this bundle likely offers: spatie/laravel-sitemap for sitemaps, artesaos/seotools or ralphjsmit/laravel-seo for meta tags, spatie/laravel-sluggable for slugs. Reach for those unless the specific bundle has logic you can't replicate.

Bottom line for a Laravel dev: treat skuola/seo-bundle as a source to read, not a dependency to add. Copy the utility classes, discard the Symfony plumbing, and don't add it to composer.json. With 0 stars, 0 dependents, and an eight-year-old last release, it has no community safety net — if it breaks in your app, you are the maintainer.

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.
ably/pubsub-server
mstfkhazaal/defender
mfonte/base62x
karnoweb/metapilot
tobya/bcsapiwrapper
swalker2/cpanel
vish4395/laravel-translation-manager
morningtrain/economic
teksite/systeminfo-laravel
atomcms/voting
run6/weather
siokas/laravelembeddirectives
adamlien/pkuuids
gilsonsouza/lara-doc-generator
manelgavalda/enrollment_mobile
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics