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

Seotools Laravel Package

vinicius73/seotools

SEOTools is a Laravel package that simplifies search engine optimization for your applications. It provides helpers to generate meta tags, Open Graph and Twitter Card data, manage sitemaps and robots.txt, and integrate analytics, keeping SEO configuration clean and centralized.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Laravel 5-era SEO helper (last release 2016), so treat it as a "meta tag assembler in a facade" rather than a modern SEO suite. First thing to do is confirm it still boots on your Laravel version — if you're on 5.5+ it may work with the auto-discovery shim, but on Laravel 6+ you'll almost certainly need to fix the service provider / container bindings before anything renders.

  1. Install and pin. composer require vinicius73/seotools. Since the package is abandoned-by-inactivity, pin the exact version in composer.json and don't trust ^ constraints — a composer update months later can surface an unresolved dependency.

  2. Register the provider. In Laravel ≤5.4, add Vinicius73\SeoTools\Providers\SeoToolsServiceProvider::class to config/app.php under providers, and register the facade alias (usually 'Seo' => Vinicius73\SeoTools\Facades\Seo::class). On 5.5+ check whether the provider is actually listed in composer.json's extra.laravel.providers — if not, register manually.

  3. Publish config. php artisan vendor:publish --provider="Vinicius73\SeoTools\Providers\SeoToolsServiceProvider". This usually drops a config/seotools.php (or seo.php) with defaults for title separator, site name, default description, and possibly Open Graph defaults. Read this file first — it is the single best map of what the package actually does. If the publish tag is wrong, use --tag=config.

  4. Look at the source before the README. With 23 stars and a 2016 release, the README is likely thin and partly out of date. vendor/vinicius73/seotools/src/ is small — skim the facade and the main service class to see what methods actually exist (setTitle, setDescription, addMeta, addOpenGraph, render, etc.). Trust the source over the docs.

  5. First use case. In a controller action, set metadata, then output it in your layout:

    // Controller
    public function show(Post $post)
    {
        Seo::setTitle($post->title);
        Seo::setDescription(str_limit(strip_tags($post->body), 155));
        return view('posts.show', compact('post'));
    }
    
    {{-- layouts/app.blade.php --}}
    <head>
        {!! Seo::render() !!}
    </head>
    

    That single flow — set in controller, render in layout — is essentially the whole mental model of the package.

Implementation Patterns

Default-then-override in a base controller or middleware. Don't set SEO on every action. Put sensible site-wide defaults in config/seotools.php (site name, separator, default description) and only call the facade in actions that need to override. If the package doesn't merge defaults cleanly, wrap it in your own SeoService so controllers depend on your abstraction, not the vendor API.

// app/Http/Middleware/SeoDefaults.php
public function handle($request, Closure $next)
{
    Seo::setTitle(config('app.name'));
    Seo::setDescription(config('seotools.default_description'));
    return $next($request);
}

Per-model SEO via a trait or accessor contract. For blogs/products, the pattern that scales best is a small interface (Seoable) with seoTitle() / seoDescription() methods, and a helper that hydrates the facade from a model. This keeps metadata next to the content that owns it instead of scattered across controllers.

trait HasSeo
{
    public function applySeo()
    {
        Seo::setTitle($this->seo_title ?: $this->title);
        Seo::setDescription($this->seo_description ?: str_limit(strip_tags($this->body), 155));
        Seo::addMeta('og:type', 'article');
        if ($this->image) {
            Seo::addOpenGraph('image') ?? Seo::addMeta('og:image', url($this->image));
        }
        return $this;
    }
}

Note the ?? — many 2016-era SEO packages have an inconsistent API where some tags go through a dedicated method (addOpenGraph) and others only through the generic addMeta. Probe both in tinker before committing to one.

Open Graph / Twitter cards are the highest-value use case. Plain <title> and <meta name="description"> have been deprecated by Google for years; the durable value here is generating og:* and twitter:* tags for link previews on WhatsApp, Slack, Facebook, and Twitter — which matters a lot for a Brazilian audience where WhatsApp sharing is primary. Make sure og:image is an absolute URL and at least 1200×630; the package can't enforce this, so validate it yourself.

Render ordering matters. The facade is a request-scoped singleton, so anything that sets SEO must run before the view renders — controller actions and middleware are fine, Blade components are not (they render after <head> is already flushed). If you use view composers, register them so they run before the layout, not inside a partial.

Layout partial for the <head> block. Keep a resources/views/partials/seo.blade.php containing only {!! Seo::render() !!} and @include it. That gives you one place to swap in a modern replacement later without touching 40 layouts.

Sitemap / robots, if the package provides them. Some seotools packages ship sitemap and robots generators. If this one does, wire the sitemap to a route and a scheduled command ($schedule->command('seo:sitemap')) rather than generating on request — on a content-heavy site request-time generation will become a performance problem.

Gotchas and Tips

  • Assume an abandoned package. Last release Oct 2016, 23 stars, no maintenance. It targets Laravel 5.2–5.4. On Laravel 6/7 the service provider will likely fail because of config merging API changes or typed method signatures; on 8+ with PHP 8 you may hit deprecation notices. Budget an hour to read the source and patch, or more realistically, fork it into app/Support/Seo.
  • Facade alias conflicts. If your app or another package already aliases Seo (arcanedev/seotools, spatie, artesaos/seotools are common), you'll silently get the wrong class. Use the fully-qualified class name in use statements rather than relying on the alias.
  • Blade escaping. The render call must be {!! Seo::render() !!}. Using {{ }} double-escapes and produces literal &lt;meta...&gt; in the head. Conversely, audit what you feed into the setters — user-supplied titles with quotes can break out of content="..." attributes. Sanitize with e() or strip_tags() before passing.
  • Empty-tag pollution. Many of these packages emit tags even when the value is empty (<meta name="description" content="">), which is worse than no tag. Either don't call setters when the value is falsy, or wrap the render in a check.
  • Config caching. After php artisan config:cache, published config changes are invisible until you re-cache. If defaults "stop working" in staging, this is usually why.
  • Debugging tip. dd(Seo::render()) in a route closure is faster than re-reading the source. It instantly tells you which tags the package supports and how it formats them.
  • Extension point. The cleanest escape hatch is a view composer plus a thin SeoPresenter class that returns an array of meta tags, with the Blade partial iterating over it. You get full control of markup, keep the package doing only its data-collection job, and can drop it later by changing one composer binding.
  • Don't rely on it for anything beyond meta tags. It won't give you structured data (JSON-LD), canonical URLs, hreflang, or redirect management — those are the things modern SEO actually needs. If this package is your entire SEO story, plan a migration to spatie/laravel-sitemap + hand-rolled meta + JSON-LD in the layout.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
cgv/localized-resource