Auditoría SEO gratuita (seo:audit)
php artisan seo:audit responde a una pregunta: ¿qué problemas tienen ahora los metadatos de mis páginas? Recorre los modelos HasSEO en el proceso actual, sin cola, licencia ni red, y muestra un estado pass / warn / fail por página y un resumen.
bash
php artisan seo:audit+--------------+--------+----------------------------+
| Page | Status | Findings |
+--------------+--------+----------------------------+
| Post #1 | PASS | — |
| Post #2 | WARN | notice title_too_short |
| Post #3 | FAIL | critical missing_title |
| | | warning missing_description|
+--------------+--------+----------------------------+
3 page(s) — 1 passed, 1 warned, 1 failed
4 issue(s) — 1 critical, 1 warning, 2 noticeQué comprueba
Solo ejecuta la clase metadata: comprobaciones derivadas del modelo y del resolvedor, sin descargar la página.
| Comprobación | Códigos |
|---|---|
| Título y descripción presentes, incluidos respaldos | missing_title, missing_description |
| Imagen OG presente, incluidos respaldos | missing_og_image |
| Longitud del título y la descripción | title_too_long, title_too_short, description_too_long, description_too_short |
| Títulos y descripciones duplicados entre páginas | duplicate_title, duplicate_description |
| Robots contradictorios y noindex que conviene revisar | robots_conflict_indexing, robots_conflict_following, noindex_warning |
| Canonical: formato, otro dominio, URL compartida o insegura | invalid_canonical, cross_domain_canonical, shared_canonical, insecure_canonical |
| Preparación para respuestas (AEO): datos estructurados de artículos | aeo_missing_author, aeo_article_missing_date |
| Palabra clave objetivo definida, tras activación | missing_focus_keyword |
| Alternativas hreflang, solo en el núcleo y si la página declara alguna | hreflang_invalid_code, hreflang_duplicate_code, hreflang_missing_self |
Los códigos tienen el mismo significado que en Pro. Los códigos hreflang de esta tabla y blank_explicit_override son exclusivos del núcleo. Las longitudes siguen el presupuesto por escritura: 60/160 grafemas para texto latino y aproximadamente 30/80 para CJK. Se mide el valor resuelto con el sufijo del título incluido. El editor Filament usa la misma política, aunque también puede mostrar texto aún sin guardar.
Las comprobaciones hreflang usan la lista después de aplicar seo.hreflang, como las etiquetas y el sitemap. La reciprocidad requiere rastreo y se comprueba en Pro.
Las comprobaciones AEO solo se aplican a artículos JSON-LD (Article, BlogPosting, NewsArticle, …) sin entidad author o sin datePublished / dateModified. Examinar autoría y fechas permite identificar la procedencia y cronología explícitas. Si no hay un artículo declarado, no se genera este aviso. Son recomendaciones de nivel notice, excluidas del score Pro de 0 a 100.
Qué no comprueba — límites del comando
Una auditoría local de metadatos no cubre todo el análisis Pro. Cada ejecución recuerda que no incluye:
- Comprobaciones del HTML servido:
missing_h1,multiple_h1,missing_image_alt,thin_contentymixed_contentrequieren el contenido real de la página. - Comprobaciones de red del canonical:
canonical_target_broken/_redirect/_noindexnecesitan una petición saliente protegida. - El score numérico de 0 a 100: Pro lo guarda con una rúbrica versionada en el resultado del análisis; consulta score SEO (EN).
Estas funciones pertenecen a Pro. Consulta el registro completo de problemas (EN).
Elegir qué modelos auditar
El comando usa seo.audit.models, con respaldo en seo.sitemap.models:
php
// config/seo.php
'audit' => [
'models' => [
\App\Models\Post::class,
\App\Models\Page::class,
],
],También puedes indicar modelos explícitos:
bash
php artisan seo:audit --model="App\Models\Post" --model="App\Models\Page"Opciones
| Opción | Efecto |
|---|---|
--model= | Clase con HasSEO; repetible, reemplaza la configuración. |
--locale= | Idioma de resolución; por defecto, el de la aplicación. |
--limit= | Máximo de registros por modelo; 0 significa todos. |
--issues-only | Mostrar solo páginas con al menos un problema. |
--strict | Devolver un código de salida no nulo si aparece cualquier problema, para CI. |
--json | Generar JSON con páginas, resumen y cobertura en lugar de la tabla. |
Comprobación en CI
Con --strict, la auditoría funciona como comprobación del build:
bash
php artisan seo:audit --strictDevuelve 1 si alguna página tiene advertencias o fallos, y 0 si todas las páginas auditadas pasan.
JSON
bash
php artisan seo:audit --jsonjson
{
"pages": [
{
"model": "App\\Models\\Post",
"key": 3,
"label": "Post #3",
"url": "https://example.com/blog/...",
"status": "fail",
"issues": [
{ "code": "missing_title", "severity": "critical", "field": "title", "message": "Page is missing a title tag." }
]
}
],
"summary": { "pages": 3, "passed": 1, "warned": 1, "failed": 1, "issues": 4, "by_severity": { "critical": 1, "warning": 1, "notice": 2 } },
"skipped": [],
"coverage": { "executes": "metadata", "note": "...", "reference": "https://rankbeam.dev/pro/scan-issues" }
}Palabras clave objetivo
El aviso missing_focus_keyword está desactivado por defecto. Aparece tras activar el flujo de palabras clave:
php
// config/seo.php
'keywords' => [
'enabled' => true,
],Pro lee el mismo ajuste, por lo que auditoría, análisis y editor comparten la activación. Usa el campo Filament o $model->saveSEO(['focus_keywords' => [['keyword' => 'laravel seo', 'is_primary' => true]]]).
Explicar valores inesperados con seo:explain
seo:audit muestra qué está mal. seo:explain (EN) explica de dónde viene el valor: configuración, valor predeterminado, cálculo o dato explícito; qué reemplazó y qué tratamiento posterior recibió, como sufijo, limpieza del canonical o protección de indexación. Úsalo cuando una etiqueta o un resultado te sorprenda:
bash
php artisan seo:explain "App\Models\Post" 42