PHPackages                             esign/laravel-seo - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. esign/laravel-seo

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

esign/laravel-seo
=================

Manage SEO tags within your Laravel application

2.5.0(3mo ago)424.4k↓58.3%MITPHPPHP ^8.1CI passing

Since Jan 28Pushed 3mo ago4 watchersCompare

[ Source](https://github.com/esign/laravel-seo)[ Packagist](https://packagist.org/packages/esign/laravel-seo)[ RSS](/packages/esign-laravel-seo/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (10)Dependencies (10)Versions (13)Used By (0)

Manage SEO tags within your Laravel application
===============================================

[](#manage-seo-tags-within-your-laravel-application)

[![Latest Version on Packagist](https://camo.githubusercontent.com/08e04521f8d17fb80879a9eda441396b30a8ab83e607d46ea4e914fda1abe8c2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f657369676e2f6c61726176656c2d73656f2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/esign/laravel-seo)[![Total Downloads](https://camo.githubusercontent.com/bc228e637ce6a1eba9ef1e77204bede850a7b9148b1ad488eb6ee049bc04109a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f657369676e2f6c61726176656c2d73656f2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/esign/laravel-seo)[![GitHub Actions](https://github.com/esign/laravel-seo/actions/workflows/main.yml/badge.svg)](https://github.com/esign/laravel-seo/actions/workflows/main.yml/badge.svg)

This package allows you to render SEO related HTML tags that can be set from anywhere in your application. Currently Meta, Open Graph, Twitter Card and JsonLD are supported. It also ships with some handy ways to configure SEO for your Eloquent models.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require esign/laravel-seo
```

The package will automatically register a service provider.

Next up, you can publish the configuration file:

```
php artisan vendor:publish --provider="Esign\Seo\SeoServiceProvider" --tag="config"
```

The config file will be published as `config/seo.php` with the following content:

```
return [
    /**
     * The class that will be used when you call the Seo facade or the seo helper method.
     * The configured class must extend the `Esign\Seo\Seo` class.
     */
    'seo' => \Esign\Seo\Seo::class,

    /**
     * Tags are used to represent their own set of specific attributes.
     * The configured tags must extend their corresponding base class.
     */
    'tags' => [
        'meta' => \Esign\Seo\Tags\Meta::class,
        'open_graph' => \Esign\Seo\Tags\OpenGraph::class,
        'twitter_card' => \Esign\Seo\Tags\TwitterCard::class,
        'json_ld' => \Esign\Seo\Tags\JsonLd::class,
    ],
];
```

Usage
-----

[](#usage)

### Preparing your HTML

[](#preparing-your-html)

You may start off by including the seo views in the head of your HTML:

```

    @include('seo::seo')

```

In case you want to customize these views, you may publish them using the following command:

```
php artisan vendor:publish --provider="Esign\Seo\SeoServiceProvider" --tag="views"
```

### Setting attributes

[](#setting-attributes)

To quickly set up some SEO attributes, you may use the Seo class. This is usually done from the controller, but that shouldn't limit you from using it in other places:

```
use Esign\Seo\Facades\Seo;

class PostController extends Controller
{
    public function show(Post $post)
    {
        Seo::setTitle($post->title)->setDescription($post->description);

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

The SEO class will forward these to all the underlying tags. In case you want some more fine grained control over what attributes are being set you may use the individual tags:

```
use Esign\Seo\Facades\Seo;
use Esign\Seo\Facades\Tags\Meta;
use Esign\Seo\Facades\Tags\OpenGraph;
use Esign\Seo\Facades\Tags\TwitterCard;

Seo::meta()->setTitle('My Meta Title');
Seo::og()->setTitle('My Open Graph Title');
Seo::twitter()->setTitle('My Twitter Title');

Meta::setTitle('My Meta Title');
OpenGraph::setTitle('My Open Graph Title');
TwitterCard::setTitle('My Twitter Card Title');
```

You can also use a fluent API that allows you to chain methods:

```
use Esign\Seo\Facades\Seo;
use Esign\Seo\Tags\Meta;
use Esign\Seo\Tags\OpenGraph;
use Esign\Seo\Tags\TwitterCard;

Seo::meta(fn (Meta $meta) => $meta->setTitle('My Meta Title'))
    ->og(fn (OpenGraph $openGraph) => $openGraph->setTitle('My Open Graph Title'))
    ->twitter(fn (TwitterCard $twitterCard) => $twitterCard->setTitle('My Twitter Card Title'));
```

### Defining mutators

[](#defining-mutators)

This package allows you to define [mutators](https://laravel.com/docs/8.x/eloquent-mutators#defining-a-mutator) like Laravel's model attributes:

```
use Esign\Seo\Tags\Meta as EsignMeta;

class Meta extends EsignMeta
{
    public function setDescriptionAttribute(?string $value): string
    {
        return (string) Str::limit($value, 160, '');
    }
}
```

A `setTitleAttribute` has been included on all traits that will suffix your title with your app name:

```
public function setTitleAttribute(?string $title): ?string
{
    return sprintf('%s | %s', $title, config('app.name'));
}
```

To bypass a mutator while setting an attribute, you may use the `setRaw` method:

```
Seo::setTitle('My Normal Seo Title'); // My Normal Seo Title | Esign
Seo::setRaw('title', 'My Raw Seo Title'); // My Raw Seo Title
```

### Setting SEO for models

[](#setting-seo-for-models)

To set SEO for models, you may implement the `Esign\Seo\Contracts\SeoContract` interface. A handy trait `Esign\Seo\Concerns\HasSeoDefaults` has been included that can quickly help you set up some SEO defaults for your model. This however is not necessary, you could also implement the methods yourself:

```
use Esign\Seo\Concerns\HasSeoDefaults;
use Esign\Seo\Contracts\SeoContract;

class Post extends Model implements SeoContract
{
    use HasSeoDefaults;

    public function getSeoUrl(): ?string
    {
        return route('posts.show', ['slug' => $this->slug]);
    }
}
```

You may set this `SeoContract` using the `set` method:

```
use Esign\Seo\Facades\Seo;

class PostController extends Controller
{
    public function show(Post $post)
    {
        Seo::set($post);

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

### Seo API

[](#seo-api)

```
use Esign\Seo\Facades\Seo;
use Esign\Seo\Contracts\SeoContract;

Seo::when(mixed $value, callable $callback, callable|null $default);
Seo::unless(mixed $value, callable $callback, callable|null $default);
Seo::setTitle(?string $title);
Seo::setDescription(?string $title);
Seo::setUrl(?string $title);
Seo::setImage(?string $title);
Seo::setAlternateUrls(array $alternateUrls);
Seo::set(SeoContract $seoContract)
Seo::meta();
Seo::og();
Seo::twitter();
Seo::jsonLd();
```

### Meta API

[](#meta-api)

```
use Esign\Seo\Facades\Tags\Meta;

// Conditions
Meta::when(mixed $value, callable $callback, callable|null $default);
Meta::whenEmpty(string $key, callable $callback, callable|null $default);
Meta::unless(mixed $value, callable $callback, callable|null $default);

// Getting attributes
Meta::get(string $key, mixed $default = null);
Meta::has(string $key);
Meta::getTitle();
Meta::getDescription();
Meta::getImage();
Meta::getUrl();
Meta::getPrev();
Meta::getNext();
Meta::getRobots();
Meta::getAlternateUrls();

// Setting attributes
Meta::set(string $key, mixed $value);
Meta::setRaw(string $key, mixed $value);
Meta::setTitle(?string $title);
Meta::setDescription(?string $description);
Meta::setImage(?string $image);
Meta::setUrl(?string $url);
Meta::setPrev(?string $prev);
Meta::setNext(?string $next);
Meta::setRobots(?string $robots);
Meta::setAlternateUrls(array $alternateUrls);
Meta::addAlternateUrls(array $alternateUrls);
```

### Open Graph API

[](#open-graph-api)

```
use Esign\Seo\Facades\Tags\OpenGraph;

// Conditions
OpenGraph::when(mixed $value, callable $callback, callable|null $default);
OpenGraph::whenEmpty(string $key, callable $callback, callable|null $default);
OpenGraph::unless(mixed $value, callable $callback, callable|null $default);

// Getting attributes
OpenGraph::get(string $key, mixed $default = null);
OpenGraph::has(string $key);
OpenGraph::getType();
OpenGraph::getSiteName();
OpenGraph::getTitle();
OpenGraph::getDescription();
OpenGraph::getImage();
OpenGraph::getUrl();

// Setting attributes
OpenGraph::set(string $key, mixed $value);
OpenGraph::setRaw(string $key, mixed $value);
OpenGraph::setType(?string $title);
OpenGraph::setSiteName(?string $title);
OpenGraph::setTitle(?string $title);
OpenGraph::setDescription(?string $description);
OpenGraph::setImage(?string $image);
OpenGraph::setUrl(?string $url);
```

### Twitter Card API

[](#twitter-card-api)

```
use Esign\Seo\Facades\Tags\TwitterCard;

// Conditions
TwitterCard::when(mixed $value, callable $callback, callable|null $default);
TwitterCard::whenEmpty(string $key, callable $callback, callable|null $default);
TwitterCard::unless(mixed $value, callable $callback, callable|null $default);

// Getting attributes
TwitterCard::get(string $key, mixed $default = null);
TwitterCard::has(string $key);
TwitterCard::getType();
TwitterCard::getTitle();
TwitterCard::getDescription();
TwitterCard::getImage();

// Setting attributes
TwitterCard::set(string $key, mixed $value);
TwitterCard::setRaw(string $key, mixed $value);
TwitterCard::setType(?string $type);
TwitterCard::setDescription(?string $description);
TwitterCard::setImage(?string $image);
```

### JsonLd API

[](#jsonld-api)

```
use Esign\Seo\Facades\Tags\JsonLd;

// Conditions
JsonLd::when(mixed $value, callable $callback, callable|null $default);
JsonLd::whenEmpty(string $key, callable $callback, callable|null $default);
JsonLd::unless(mixed $value, callable $callback, callable|null $default);

// Getting attributes
JsonLd::get(string $key, mixed $default = null);
JsonLd::has(string $key);
JsonLd::getTypes();

// Setting attributes
JsonLd::set(string $key, mixed $value);
JsonLd::setRaw(string $key, mixed $value);
JsonLd::addType(iterable|Spatie\SchemaOrg\Type $type);
JsonLd::setTypes(array $types);
```

This package also ships with a nice helper method that you may use as an alternative to the facade:

```
use Esign\Seo\Facades\Seo;

Seo::setTitle('My Title')->setDescription('My Description');
seo()->setTitle('My Title')->setDescription('My Description');
```

Testing
-------

[](#testing)

```
composer test
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

50

—

FairBetter than 95% of packages

Maintenance79

Regular maintenance activity

Popularity31

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity65

Established project with proven stability

 Bus Factor1

Top contributor holds 88.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~167 days

Recently: every ~278 days

Total

10

Last Release

109d ago

Major Versions

1.0.0 → 2.0.02022-02-08

PHP version history (2 changes)1.0.0PHP ^8.0

2.4.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/4599d7a8f6fdb63dd04305a49ae5ec9700b7a6eacdbe3a54f89584d75e34503f?d=identicon)[esign](/maintainers/esign)

---

Top Contributors

[![jordyvanderhaegen](https://avatars.githubusercontent.com/u/24370626?v=4)](https://github.com/jordyvanderhaegen "jordyvanderhaegen (48 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (4 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (2 commits)")

---

Tags

jsonldlaravelmetaopengraphphpseotwittercardJSON-LDseometatwitter cardopen-graphlaravel-seoesign

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/esign-laravel-seo/health.svg)

```
[![Health](https://phpackages.com/badges/esign-laravel-seo/health.svg)](https://phpackages.com/packages/esign-laravel-seo)
```

###  Alternatives

[artesaos/seotools

SEO Tools for Laravel and Lumen

3.4k5.4M63](/packages/artesaos-seotools)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[nystudio107/craft-seomatic

SEOmatic facilitates modern SEO best practices &amp; implementation for Craft CMS 5. It is a turnkey SEO system that is comprehensive, powerful, and flexible.

1741.5M61](/packages/nystudio107-craft-seomatic)[vaersaagod/seomate

SEO, mate! It's important.

4442.8k2](/packages/vaersaagod-seomate)[lionix/seo-manager

SEO Manager for Laravel Framework

2145.4k](/packages/lionix-seo-manager)[devrabiul/laravel-seo-manager

Laravel SEO Manager is an SEO tool that improves SEO by adding recommended meta tags.

396.7k](/packages/devrabiul-laravel-seo-manager)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
