Looking to hire Laravel developers? Try LaraJobs

laravel-seo maintained by abdur-rahaman

Description
A comprehensive SEO management package for Laravel applications, inspired by Yoast SEO.
Author
Last update
2026/11/01 13:03 (dev-main)
License
Downloads
3

Comments
comments powered by Disqus

Laravel SEO

SEO management package for Laravel (meta tags, social cards, sitemap, schema, analysis form).

Package: abdur-rahaman/laravel-seo
Requirements: PHP 8.3+, Laravel 11 / 12 / 13


Install

composer require abdur-rahaman/laravel-seo
php artisan seo:install
php artisan migrate

Publish assets only (CSS/JS for the admin form):

php artisan seo:publish-assets

Initial

1. Config (optional)

php artisan vendor:publish --tag=laravel-seo-config

Set defaults in config/laravel-seo.php or .env:

SEO_DEFAULT_TITLE="${APP_NAME}"
SEO_DEFAULT_DESCRIPTION="Your default meta description"
SEO_SITE_NAME="${APP_NAME}"
SEO_SITE_URL="${APP_URL}"

2. Admin layout assets

The SEO form needs Bootstrap 5, Font Awesome, and jQuery in your admin layout. Package CSS/JS:

<link rel="stylesheet" href="{{ asset('vendor/laravel-seo/css/laravel-seo.css') }}">
{{-- after jQuery + Bootstrap --}}
<script src="{{ asset('vendor/laravel-seo/js/laravel-seo.js') }}"></script>

Or rely on @stack('styles') / @stack('scripts') if your layout already yields them (the form component pushes these stacks).


Load input fields and plugins in form

Add the SEO form component to any create/edit view:

<form method="POST" action="{{ route('posts.update', $post) }}">
    @csrf
    @method('PUT')

    {{-- your normal fields (title, body, etc.) --}}

    <x-laravel-seo::form
        :model="$post"
        :content="$post->body ?? ''"
        name-prefix="seo"
    />

    <button type="submit">Save</button>
</form>

Form tabs & fields

Tab Fields
General SEO Focus keyword, SEO title, meta description, additional keywords, canonical URL, Google preview
Social Media OG title / description / image, Twitter title / description / image
Advanced Robots index/follow, exclude from sitemap, canonical
Schema Schema type, custom JSON-LD data
Analysis SEO score + keyword / content checks

Save SEO from the controller

use Abdurrahaman\LaravelSeo\DTOs\SeoData;

public function update(Request $request, Post $post)
{
    $data = $request->validate([
        'title' => ['required', 'string'],
        'body'  => ['nullable', 'string'],
        'seo'   => ['nullable', 'array'],
    ]);

    $post->update(collect($data)->except('seo')->all());

    if (! empty($data['seo'])) {
        $post->updateSeo(SeoData::fromArray($data['seo']));
    }

    return back()->with('success', 'Saved.');
}

Input names use the prefix: seo[title], seo[description], seo[focus_keyword], etc.

For a new model without SEO yet:

<x-laravel-seo::form
    :content="old('body', '')"
    name-prefix="seo"
/>

Setup in model

Use the HasSeo trait on any Eloquent model:

<?php

namespace App\Models;

use Abdurrahaman\LaravelSeo\Support\HasSeo;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasSeo;

    protected $fillable = ['title', 'slug', 'body'];
}

API on the model

// Relation
$post->seo;

// Create / update SEO
$post->updateSeo([
    'title'          => 'My Post Title',
    'description'    => 'Meta description here.',
    'focus_keyword'  => 'laravel seo',
    'keywords'       => ['laravel', 'seo'],
    'canonical_url'  => url()->current(),
    'og_title'       => 'Share title',
    'og_description' => 'Share description',
    'og_image'       => asset('images/og.jpg'),
    'twitter_title'  => 'Twitter title',
    'twitter_image'  => asset('images/twitter.jpg'),
    'robots_index'   => true,
    'robots_follow'  => true,
    'schema_type'    => 'Article',
]);

// Helpers
$post->hasSeo();   // bool
$post->deleteSeo();

Load model SEO for the current page

use Abdurrahaman\LaravelSeo\Facades\SEO;

public function show(Post $post)
{
    SEO::for($post);

    return view('posts.show', compact('post'));
}

If the model has no SEO row yet, set fallbacks:

SEO::for($post);

if (! $post->hasSeo()) {
    SEO::setTitle($post->title)
        ->setDescription(str($post->body)->limit(150)->toString());
}

SEO tags in meta (front-end)

Put the helper once in your main layout <head>:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    {{ laravel_seo() }}

    {{-- or: @seo --}}
</head>
<body>
    @yield('content')
</body>
</html>

What gets rendered

  • <title>...</title>
  • <meta name="description" ...>
  • <link rel="canonical" ...>
  • <meta name="robots" ...>
  • Open Graph (og:title, og:description, og:image, …)
  • Twitter / X cards (twitter:card, twitter:title, …)
  • JSON-LD (<script type="application/ld+json">)

Set tags without a model

use Abdurrahaman\LaravelSeo\Facades\SEO;

SEO::setTitle('About Us')
    ->setDescription('About our company.')
    ->setKeyword('about us')
    ->setImage(asset('images/about.jpg'))
    ->setCanonical(url('/about'));

Or:

laravel_seo()
    ->title('About Us')
    ->description('About our company.')
    ->keyword('about us')
    ->image(asset('images/about.jpg'));

Defaults from config/laravel-seo.php are used when a field is empty.


AI SEO Generator (ChatGPT)

Generate SEO title, meta description, focus keyword, and keywords from page content via OpenAI.

1. Enable in .env

SEO_AI_ENABLED=true
SEO_AI_API_KEY=sk-your-openai-api-key
SEO_AI_MODEL=gpt-4o-mini
# optional:
# SEO_AI_BASE_URL=https://api.openai.com/v1
# SEO_AI_LANGUAGE=en

Or use OPENAI_API_KEY instead of SEO_AI_API_KEY.

Publish config if you have not already:

php artisan vendor:publish --tag=laravel-seo-config

2. Use the form

On the General SEO tab, click Generate with AI.

The button reads content from common fields (#body, textarea[name="body"], textarea[name="content"], TinyMCE/CKEditor) and fills:

  • Focus keyword
  • SEO title
  • Meta description
  • Additional keywords

Then review and save the form as usual.

3. Protect the endpoint (recommended)

In config/laravel-seo.php:

'ai' => [
    'enabled' => true,
    'middleware' => ['web', 'auth'], // require login
    // ...
],

4. Republish assets after upgrade

php artisan seo:publish-assets --force