Ofertas de Fin de Verano

Todos los planes rebajados hasta el 31 de agosto.

Ver planes
00 Días
00 Horas
00 Minutos
00 Segundos

Ofertas de Fin de Verano

Precios rebajados en todos los planes, para nuevas suscripciones y renovaciones. Solo hasta el 31 de agosto.
Ver planes
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.