Auditoría técnica de SEO con Lighthouse CLI y Node.js (sin depender de PageSpeed Insights)
El problema Revisar manualmente PageSpeed Insights o Search Console página por página no escala. Si manejas 20, 50 o 200 URLs (un e-commerce, un blog grande, un sitio multi-idioma), necesitas automatizar la auditoría t
El problema
Revisar manualmente PageSpeed Insights o Search Console página por página no escala. Si manejas 20, 50 o 200 URLs (un e-commerce, un blog grande, un sitio multi-idioma), necesitas automatizar la auditoría técnica: performance, SEO score, accesibilidad y buenas prácticas, todo en un solo reporte.
Aquí vamos a montar un script en Node que:
- Corre Lighthouse por línea de comandos sobre una lista de URLs.
- Extrae las métricas clave (Core Web Vitals, score SEO, errores de indexación).
- Genera un CSV consolidado que puedes abrir en Sheets/Excel o pasar a un dashboard.
Requisitos
node -v # v18 o superior recomendado
npm i -g lighthouse chrome-launcher
lighthouse trae su propio Chrome headless por debajo, así que no necesitas instalar Chrome aparte en la mayoría de entornos (aunque en CI a veces sí hay que apuntar a un binario existente).
Paso 1: correr Lighthouse desde la CLI
Lo más simple, para una sola URL:
lighthouse https://tusitio.com \
--output json \
--output-path ./reports/home.json \
--chrome-flags="--headless" \
--only-categories=performance,seo,accessibility,best-practices
Esto genera un JSON con todo el detalle. El campo que más nos interesa para SEO técnico es categories.seo.score y las auditorías individuales dentro de audits, como is-crawlable, robots-txt, hreflang, canonical y structured-data.
Paso 2: automatizar varias URLs con un script de Node
Creamos un archivo audit.js que recorre un array de URLs, llama a Lighthouse programáticamente (no como proceso hijo, sino usando su API de Node) y consolida los resultados.
// audit.js
import lighthouse from 'lighthouse';
import * as chromeLauncher from 'chrome-launcher';
import fs from 'fs';
const urls = [
'https://tusitio.com',
'https://tusitio.com/blog',
'https://tusitio.com/servicios',
'https://tusitio.com/contacto',
];
async function auditUrl(url, chrome) {
const options = {
logLevel: 'error',
output: 'json',
onlyCategories: ['performance', 'seo', 'accessibility', 'best-practices'],
port: chrome.port,
};
const runnerResult = await lighthouse(url, options);
const { categories, audits } = runnerResult.lhr;
return {
url,
performance: Math.round(categories.performance.score * 100),
seo: Math.round(categories.seo.score * 100),
accessibility: Math.round(categories.accessibility.score * 100),
bestPractices: Math.round(categories['best-practices'].score * 100),
lcp: audits['largest-contentful-paint'].displayValue,
cls: audits['cumulative-layout-shift'].displayValue,
tbt: audits['total-blocking-time'].displayValue,
isCrawlable: audits['is-crawlable'].score === 1,
robotsTxtValid: audits['robots-txt'] ? audits['robots-txt'].score === 1 : null,
hasCanonical: audits['canonical'] ? audits['canonical'].score === 1 : null,
hasStructuredData: audits['structured-data']
? audits['structured-data'].score !== 0
: null,
};
}
async function run() {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
const results = [];
for (const url of urls) {
console.log(`Auditando ${url}...`);
try {
const result = await auditUrl(url, chrome);
results.push(result);
} catch (err) {
console.error(`Error auditando ${url}:`, err.message);
results.push({ url, error: err.message });
}
}
await chrome.kill();
fs.writeFileSync('./reports/audit-results.json', JSON.stringify(results, null, 2));
console.log('Auditoría completa. Ver ./reports/audit-results.json');
return results;
}
run();
Puntos a notar:
- Usamos
chromeLauncher.launch()una sola vez y reusamos el mismo puerto para todas las URLs, en vez de abrir un Chrome nuevo por cada una — esto es mucho más rápido cuando auditas varias páginas. -
audits['is-crawlable']te dice directamente si Google puede indexar la página (detectanoindex, bloqueos por robots, etc.) — esto conecta directo con el error #1 de "sitio bloqueado para Google". -
structured-datavalida si hay schema markup presente, relevante para AEO además de SEO tradicional.
Paso 3: exportar a CSV para revisar rápido
Un JSON con 50 URLs es difícil de escanear a simple vista. Convertimos a CSV:
// to-csv.js
import fs from 'fs';
const data = JSON.parse(fs.readFileSync('./reports/audit-results.json', 'utf-8'));
const headers = [
'url', 'performance', 'seo', 'accessibility', 'bestPractices',
'lcp', 'cls', 'tbt', 'isCrawlable', 'robotsTxtValid',
'hasCanonical', 'hasStructuredData',
];
const rows = data.map((row) =>
headers.map((h) => JSON.stringify(row[h] ?? '')).join(',')
);
const csv = [headers.join(','), ...rows].join('\n');
fs.writeFileSync('./reports/audit-results.csv', csv);
console.log('CSV generado en ./reports/audit-results.csv');
Con esto ya tienes un archivo que puedes abrir en cualquier hoja de cálculo y ordenar por seo o performance para ver qué páginas necesitan atención primero.
Paso 4 (opcional): correrlo en CI
Si quieres que esto corra automáticamente en cada deploy, un job simple en GitHub Actions:
# .github/workflows/lighthouse-audit.yml
name: Lighthouse Audit
on:
schedule:
- cron: '0 6 * * 1' # cada lunes 6am
workflow_dispatch:
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- run: npm install
- run: node audit.js
- run: node to-csv.js
- uses: actions/upload-artifact@v4
with:
name: seo-audit-report
path: reports/
Así tienes un historial de auditorías cada semana sin tocar nada manualmente, y puedes detectar regresiones (por ejemplo, si un deploy rompió el robots.txt o metió un noindex por error).
Qué mirar primero en los resultados
De las métricas que salen del script:
-
isCrawlable: falsees la alarma más urgente — significa que esa página literalmente no puede ser indexada. -
lcppor encima de 2.5s ya pone en desventaja competitiva según los umbrales de Core Web Vitals. -
hasStructuredData: falseen páginas clave (producto, servicio, artículo) es una oportunidad fácil de cerrar con JSON-LD.
Cierre
Automatizar esto no reemplaza una auditoría profesional completa (perfil de enlaces, intención de búsqueda, contenido duplicado entre dominios), pero sí te da visibilidad continua sobre los problemas técnicos que rompen el SEO silenciosamente — que suelen ser los que más impacto tienen y menos se detectan a tiempo.
Si prefieren que un equipo humano cruce estos datos con el resto de la estrategia (SEO, AEO, contenido, enlaces), la gente de Agencia Digital ECW hace auditorías de este tipo para negocios en Bogotá.
¿Ya usan Lighthouse en su pipeline de CI, o prefieren herramientas como Sitebulb o Screaming Frog para esto? Me interesa saber qué stack usan para auditorías recurrentes.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.