Search by

srg / siteseo

srg

Manage On-Site SEO and social media tags in your database not your code.

v1.0.2 2026-09-02 03:15 UTC

This package is auto-updated.

Last update: 2026-09-02 03:16:22 UTC


README

SiteSeo-Github-Banner

SiteSeo

SiteSeo enables your Laravel app to store SEO and social media meta tag data in the database instead of your code.

SiteSeo creates tag records identified by page route name, and renders tags in your views' head section. It ships with a self-contained admin UI for managing tags and uploading images.

Installation

composer require srg/siteseo
php artisan migrate
php artisan storage:link

Then set at least one admin email in .envthe admin UI is inaccessible to everyone (403) until this is set:

SITESEO_ADMIN_EMAILS=you@example.com

See Configuration below for details.

Help Support

If you find this package useful help support my projects:

kisReviews-Github

kisReviews.com

StockNotes-Github

StockNotes.app

Admin UI

Once installed, tag records can be managed at /siteseo (index, create, edit, delete). The routes are registered by SiteSeoServiceProvider behind the web, auth middleware, plus a package middleware (EnsureSiteSeoAdmin) that restricts access to the emails configured in admin_emails (see below).

Feature/OG/Twitter images are managed exclusively through file upload in this UI. Uploaded files are stored on the public disk under storage/app/public/siteseo/ and public URL is saved in the tag record.

Configuration

Configuration lives in packages/srg/siteseo/src/config/siteseo.php and is merged automatically via SiteSeoServiceProvider::register() — setting the env vars below is enough, no publish step required. Only run php artisan vendor:publish --tag=siteseo-config if you'd rather edit config/siteseo.php directly instead of using env vars.

Key Env var Default Purpose
path SITESEO_PATH siteseo URL path prefix for the admin CRUD routes, e.g. a/siteseo/a/siteseo, /a/siteseo/create, /a/siteseo/{tag}/edit. Route names stay siteseo.index, siteseo.edit, etc. regardless of the path.
admin_emails SITESEO_ADMIN_EMAILS (empty) Comma-separated list of emails allowed into the admin UI, trimmed, matched exactly against the authenticated user's email. Empty or unset means nobody can access it — this fails closed, not open.

Usage

Default: automatic tags for named routes (app.blade.php)

If your app uses Inertia.js without server-side rendering, do not rely on a client-side <Head> component (Vue/React) to set meta tags on public/marketing pages. Search engines will run javascript but social media crawlers (Facebook, Twitter/X, LinkedIn, etc.) will not display the link card.

The simplest integration is a single call in your Inertia root Blade view (the file registered as rootView in your HandleInertiaRequests middleware) — see resources/views/app.blade.php:

If you're using blade then it can be in any layout head section.

{!! isset($seo) ? $seo->render() : \Srg\SiteSeo\Seo::fillAndRender() !!}

Overriding per-route with dynamic data

When a page needs tags built from data that isn't a Tag record — e.g. a blog post's own title/description/image — build a Seo instance in the controller and share it as $seo so app.blade.php picks it up instead of falling back.

use Srg\SiteSeo\Seo;

public function show(string $slug): Response
{
    $post = Post::published()->where('slug', $slug)->firstOrFail();

    $seo = new Seo;
    $seo->title($post->meta['title']);
    $seo->siteName(config('app.name', ''));
    $seo->description($post->meta['description']);
    $seo->canonical($post->meta['canonical_link']);
    $seo->image(asset($post->featured_image));
    $seo->fallback(); // fills OG/Twitter tags from title/description/canonical above

    view()->share('seo', $seo);

    return Inertia::render('public/blog/Show', ['post' => $post]);
}

fallback() is the instance-level counterpart to the Tag-based fallback used by fillAndRender() — it fills in Open Graph and Twitter tags from whatever title/description/canonical were already set on the instance, so per-route code only needs to set the primary fields.

License

The MIT License (MIT). Please see License File for more information.