Saltar al contenido
Filament SEO
code

Detalles del ejemplo

Filament SEO

Campos SEO reutilizables para Filament v4 con soporte para meta tags, Open Graph, Twitter Cards y preview de Google en tiempo real.

Instalación

composer require cursosdesarrolloweb/filament-seo

Configuración

1. Publicar y ejecutar migraciones

php artisan vendor:publish --tag=filament-seo-migrations
php artisan migrate

2. Añadir el trait a tus modelos

use CursosDesarrolloWeb\Seo\Concerns\HasSeoMeta;

class Post extends Model
{
    use HasSeoMeta;
}

3. Añadir los campos SEO a tu Resource

use CursosDesarrolloWeb\Seo\Forms\Components\SeoFields;

public static function form(Schema $schema): Schema
{
    return $schema->components([
        TextInput::make('title')->required(),
        RichEditor::make('content'),
        
        // Añadir campos SEO
        SeoFields::make()->getSection(),
    ]);
}

Publicar recursos opcionales

Configuración

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

Traducciones

php artisan vendor:publish --tag=filament-seo-translations

Vistas

php artisan vendor:publish --tag=filament-seo-views

Uso

Campos SEO básicos

use CursosDesarrolloWeb\Seo\Forms\Components\SeoFields;

// Todos los campos (Meta, Open Graph, Twitter, Preview)
SeoFields::make()->getSection(),

// Solo meta tags básicos
SeoFields::make()
    ->withoutOpenGraph()
    ->withoutTwitter()
    ->getSection(),

// Sin preview de Google
SeoFields::make()
    ->withoutPreview()
    ->getSection(),

// Límites de caracteres personalizados
SeoFields::make()
    ->seoTitleLimit(70)
    ->seoDescriptionLimit(180)
    ->getSection(),

Relación personalizada

Si tu modelo usa un nombre de relación diferente:

// En tu modelo
public function metaSeo(): MorphOne
{
    return $this->morphOne(SeoMeta::class, 'seoable');
}

// En tu Resource
SeoFields::make('metaSeo')->getSection(),

Renderizar meta tags en el frontend

En tu layout o vista:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    {{-- Con modelo que tiene HasSeoMeta --}}
    <x-filament-seo::meta-tags :model="$post" />
</head>

O con valores manuales:

<x-filament-seo::meta-tags 
    title="Mi Página"
    description="Descripción de la página"
    image="https://ejemplo.com/imagen.jpg"
    type="article"
/>

O combinando ambos (el modelo tiene prioridad):

<x-filament-seo::meta-tags 
    :model="$post"
    title="Título por defecto"
    description="Descripción por defecto"
/>

Características

Meta Tags Básicos

  • Título SEO - Con contador de caracteres (recomendado: 60)
  • Descripción SEO - Con contador de caracteres (recomendado: 160)
  • URL Canónica - Para evitar contenido duplicado
  • Indexable - Control noindex
  • Follow - Control nofollow

Open Graph

  • og:type - website, article, product, etc.
  • og:title - Con fallback a título SEO
  • og:description - Con fallback a descripción SEO
  • og:image - Imagen para compartir

Twitter Cards

  • twitter:card - summary, summary_large_image, etc.
  • twitter:title - Con fallback a og:title
  • twitter:description - Con fallback a og:description
  • twitter:image - Con fallback a og:image

Google Preview

Vista previa en tiempo real de cómo aparecerá tu página en los resultados de búsqueda de Google.

Personalización

Configuración

// config/filament-seo.php
return [
    // Nombre de la tabla
    'table' => 'seo_metas',
    
    // Modelo personalizado
    'model' => \App\Models\SeoMeta::class,
    
    // Límites de caracteres
    'limits' => [
        'meta_title' => 60,
        'meta_description' => 160,
    ],
    
    // Valores por defecto de Open Graph
    'og_defaults' => [
        'type' => 'website',
        'site_name' => 'Mi Sitio',
    ],
    
    // Valores por defecto de Twitter
    'twitter_defaults' => [
        'card' => 'summary_large_image',
        'site' => '@miusuario',
        'creator' => '@miusuario',
    ],
    
    // Habilitar/deshabilitar secciones
    'sections' => [
        'meta' => true,
        'open_graph' => true,
        'twitter' => true,
        'preview' => true,
    ],
];

Modelo personalizado

use CursosDesarrolloWeb\Seo\Models\SeoMeta as BaseSeoMeta;

class SeoMeta extends BaseSeoMeta
{
    // Tus personalizaciones
}

API del Modelo SeoMeta

Métodos Helper

$seo = $post->seoMeta;

// Obtener título con fallbacks
$seo->getTitle('Fallback');  // meta_title → og_title → fallback

// Obtener descripción con fallbacks
$seo->getDescription('Fallback');  // meta_description → og_description → fallback

// Obtener atributo robots
$seo->robots;  // "index, follow" o "noindex, nofollow"

// Fallbacks para Open Graph
$seo->getOgTitleWithFallback();
$seo->getOgDescriptionWithFallback();

// Fallbacks para Twitter (cascada completa)
$seo->getTwitterTitleWithFallback();       // twitter_title → og_title → meta_title
$seo->getTwitterDescriptionWithFallback(); // twitter_description → og_description → meta_description
$seo->getTwitterImageWithFallback();       // twitter_image → og_image

Estructura de la base de datos

Tabla seo_metas

Campo Tipo Descripción
id bigint Primary key
seoable_id bigint ID del modelo relacionado
seoable_type string Clase del modelo relacionado
meta_title string(200) Título SEO
meta_description text Descripción SEO
meta_canonical string(500) URL canónica
indexable boolean Permitir indexación (default: true)
follow boolean Permitir seguir enlaces (default: true)
og_title string(200) Título Open Graph
og_description text Descripción Open Graph
og_image string(500) URL de imagen Open Graph
og_type string(50) Tipo de contenido (default: website)
twitter_card string(50) Tipo de tarjeta Twitter
twitter_title string(200) Título Twitter
twitter_description text Descripción Twitter
twitter_image string(500) URL de imagen Twitter
timestamps created_at, updated_at

Requisitos

  • PHP 8.2+
  • Laravel 11+
  • Filament 4.x|5.x

Licencia

Propietario - Solo para suscriptores de CursosDesarrolloWeb.