Auditoría SEO — fibrolab.cl (2026-04-27)

Auditoría comparativa vs. 2026-04-15. Reauditoría parcial tras el commit 93bccd8 feat(seo): auditoría SEO completa — fixes críticos y de alto impacto.

Puntaje de Salud SEO: 62 / 100 (anterior: 60)

Categoría Peso Puntaje Anterior Δ Ponderado
SEO Técnico 22% 71 72 −1* 15.6
Contenido / E-E-A-T 23% 62 54 +8 14.3
SEO On-Page (incl. Local) 20% 65 65 0 13.0
Datos Estructurados (Schema) 10% 64 75 −11* 6.4
Rendimiento (Core Web Vitals) 10% 60 55 +5 6.0
Búsqueda con IA (GEO) 10% 41 34 +7 4.1
Imágenes 5% 45 40 +5 2.3

* Caídas no son regresiones reales — reflejan problemas nuevos detectados en la reauditoría (bug de slug en Service schema; CSP solo en modo Report-Only) que el audit anterior no había revelado.

Tipo de negocio: Negocio local híbrido (fábrica + área de servicio nacional) — vertical: construcción de piscinas de fibra de vidrio. Sub-tipo de schema correcto: HomeAndConstructionBusiness + LocalBusiness.


Δ vs. 2026-04-15

✅ Resuelto (8 ítems)

  1. Cabeceras de seguridad — HSTS (max-age=31536000; includeSubDomains; preload), X-Frame-Options SAMEORIGIN, X-Content-Type-Options nosniff, Referrer-Policy strict-origin-when-cross-origin, Permissions-Policy. Confirmado en respuestas live.
  2. /gracias-por-cotizar* ya no son indexables — las 3 variantes envían noindex, nofollow.
  3. CLS arreglado — todas las <img> del homepage ahora tienen width/height. CLS estimado bajó de ~0.15 a ~0.02–0.05.
  4. Página /paneles-solares/ activa — la plantilla y el link del footer ya están publicados.
  5. /nosotros/ rediseñada — ahora ~350 palabras, año 2020 en hero badge (aún falta fundador/RUT/anécdota — ver H1).
  6. LCP image preload con WebP fallback en HTML — el <picture> y el <link rel=preload> ya referencian .webp (pero los archivos no existen aún en disco — ver C3).
  7. Single-hop redirects — http→https y non-www→www ambos en 1 salto.
  8. TTFB cacheado establex-litespeed-cache: hit confirmado, ~386 ms.

🔄 Parcial / aún abierto

Prior Estado actual
Schema Product sin aggregateRating Código correcto (gated if reviews); falta el flujo de reviews. No es bug — es ausencia de data.
Fotos generadas por ChatGPT en /piscinas-de-fibra/ NO arregladoChatGPT-Image-Apr-19-2025-12_29_*.png siguen en page-piscinas-de-fibra.php líneas 191–210.
GBP URL en sameAs NO arreglado — sólo Facebook + Instagram.
LCP otono.png 1.75 MB Parcialmente — el .webp referenciado en el preload no existe en disco, fallback al PNG sigue ocurriendo.
Inconsistencia "Fabrica de Piscinas FIBROLAB" vs "Fibrolab" NO arreglado — el GBP listing aún usa el nombre largo, schema usa "Fibrolab".
IndexNow NO activo.
Crawlers IA en robots.txt NO declarados explícitamente.
/tienda2/ indexable NO arreglado — sigue 200 + en product-sitemap.xml + page-sitemap.xml.
Duplicado /spas/ vs /spa-y-jacuzzi/ NO arreglado — ambos 200, ambos en sitemap, canonicales separados.
Doble H1 en homepage NO arreglado — confirmado en HTML live.
Logo como string en LocalBusiness NO arreglado.
PoolService en @type (tipo inexistente en Schema.org) NO arreglado.
3 familias de Google Fonts NO arreglado.
Font Awesome desde CDN externo NO arreglado.

🔴 CRÍTICO (arreglar ya — bloquean ranking o señales fundamentales)

C1. Service schema NO se emite en /bombas-de-calor/

Bug nuevo detectado. fibrolab_schema_service() en functions.php busca el slug 'page-bombas-de-calor' en el array $services, pero get_page_template_slug() devuelve 'page-bombas-de-calor.php'. La condición isset($services[$template]) siempre falla → cero bloques Service emitidos en esa página (la página de mayor margen del sitio).

Cómo: en functions.php, dentro de fibrolab_schema_service(), normalizar el slug:

$template = get_page_template_slug();
$template = $template ? basename( $template, '.php' ) : basename( get_page_template(), '.php' );

C2. Doble <h1> en homepage

front-page.php:143 emite un <h1> ("Fabrica de Piscinas con Instalación incluida") y front-page.php:328 emite otro ("Fábrica chilena de piscinas de fibra de vidrio desde 2020"). Confirmado en HTML live.

Cómo: cambiar el último argumento de fibrolab_product_section(...) en front-page.php:143 de 'h1' a 'h2'. Conservar el H1 de la sección "Quiénes Somos" (mejor narrativa de marca + año).

C3. LCP — el WebP del hero NO existe en disco

El <link rel="preload" imagesrcset="...otono.png.webp"> y los <source> del <picture> referencian archivos .webp que no fueron generados. El navegador 404→ fallback al PNG de 1.75 MB. LCP no se redujo realmente.

Cómo: 1. Generar las variantes WebP/AVIF: cwebp -q 82 otono.png -o otono.png.webp (o usar LiteSpeed Image Optimization → Optimize Now). 2. Comprimir el PNG fallback con oxipng -o 4 otono.png (1.75 MB → ~400 KB esperado). 3. Verificar que el preload no esté en 404 con DevTools Network → "preload" filter.

C4. CSP solo en modo Report-Only — no bloquea XSS

functions.php:901 envía Content-Security-Policy-Report-Only. No existe el header enforced. El comentario en líneas 858–881 describe esto como "Paso 1 / fase de observación" — pero ya pasaron más de 12 días. Sin enforcement, la CSP no ofrece protección contra XSS ni inyección de scripts.

Cómo: 1. Auditar 48 h de violaciones en DevTools Console (filtrar por "Content Security Policy"). 2. Configurar report-uri (puede ser un endpoint propio simple o el tier gratuito de report-uri.com). 3. Renombrar el header en functions.php:901 a Content-Security-Policy: (sin -Report-Only). upgrade-insecure-requests ya está en la policy y manejará mixed-content automáticamente.

C5. Fotos generadas por ChatGPT en /piscinas-de-fibra/ (sin cambios desde 2026-04-15)

page-piscinas-de-fibra.php líneas 191–210 — 4 imágenes con nombres ChatGPT-Image-Apr-19-2025-12_*.png. Bajo las QRG de septiembre 2025, presentar imágenes sintéticas como evidencia de trabajo real es un fallo directo de Trustworthiness en la página transaccional principal.

Cómo: reemplazar las 4 imágenes con fotos reales (excavación, grúa, terminación) etiquetadas con fecha y comuna en el alt: alt="Excavación piscina 6 m — Lo Barnechea, enero 2025".

C6. GBP business name mismatch

GBP listing: "Fabrica de Piscinas FIBROLAB". Schema + footer + llms.txt: "Fibrolab". Entity name mismatch es el factor #1 negativo en local rankings.

Cómo: en GBP dashboard, renombrar el listing a Fibrolab (o exactamente Fibrolab — Fábrica de Piscinas, formato "Brand — Descriptor" permitido por las guidelines de Google). El schema y footer son la fuente correcta.

C7. GBP URL ausente en sameAs

fibrolab_schema_local_business() en functions.php líneas 320–323 — sameAs solo tiene Facebook e Instagram. Sin la URL canónica del GBP, Google no puede reconciliar la entidad del schema con el perfil de Knowledge Panel.

Cómo: en GBP dashboard → Share → copiar la URL https://www.google.com/maps?cid=XXXXXXXXXXXXXXXXXX (o https://g.page/<short>). Añadir al array:

'sameAs' => array(
    'https://www.facebook.com/fibrolabcl/',
    'https://www.instagram.com/fibrolabcl/',
    'https://www.google.com/maps?cid=YOUR_CID_HERE',
),

🟠 ALTO (primera semana)

H1. /nosotros/ aún sin fundador, RUT ni cifras consistentes

Página rediseñada (~350 palabras, año 2020 visible) pero sin nombre del fundador, sin RUT, sin foto de fábrica, y con inconsistencia: badge "+500 proyectos" vs homepage "+1,000 instalaciones".

Cómo: en page-nosotros.php líneas 55–57, añadir bloque "Fundador y equipo": nombre completo del fundador + rol + breve historia (origen, primer proyecto), RUT 77.424.952-4 prominente, foto real de la fábrica con caption "Fábrica Fibrolab — Los Álamos 2538, La Pintana". Reconciliar la cifra de proyectos (elegir un número y usarlo en TODAS las páginas).

H2. /tienda2/ indexable + en 2 sitemaps

Confirmado: HTTP 200, robots: index, follow, canonical self-referencing, listado en product-sitemap.xml y page-sitemap.xml. URL legacy con slug no semántico.

Cómo: preferido — 301 redirect /tienda2/ → /tienda/ vía LiteSpeed rewrite o .htaccess. Alternativa — Rank Math edit /tienda2/ → noindex + Advanced → "Include in Sitemap = No".

H3. /spas/ vs /spa-y-jacuzzi/ — duplicado activo

Ambos 200, ambos en page-sitemap.xml, canonicales auto-referenciales (no consolidan). Plantillas separadas (page-spas.php, page-spa-y-jacuzzi.php). El homepage linkea a /spas/.

Cómo: elegir /spa-y-jacuzzi/ como canónica (slug más descriptivo, mejor para queries chilenas). En Rank Math → editar /spas/ → canonical apuntando a /spa-y-jacuzzi/. Luego 301 /spas/ → /spa-y-jacuzzi/ y actualizar el link del homepage carousel (front-page.php:70).

H4. Crawlers IA sin directiva explícita en robots.txt

robots.txt tiene solo User-agent: *. Sin allow/disallow nombrado, los AI scrapers caen al wildcard. El llms.txt ya otorga derechos de cita; robots.txt debe ser consistente.

Cómo: añadir al final de robots.txt (Rank Math → General Settings → Edit robots.txt):

User-agent: GPTBot
Allow: /

User-agent: OAI-SearchBot
Allow: /

User-agent: ClaudeBot
Allow: /

User-agent: PerplexityBot
Allow: /

User-agent: Google-Extended
Allow: /

User-agent: CCBot
Disallow: /

H5. IndexNow inactivo

Sin x-indexnow header ni archivo de clave en root. Bing/Yandex/Naver descubren cambios solo en su próximo crawl.

Cómo: WP admin → Rank Math → General Settings → IndexNow → ON. Verificar generación del archivo de clave en root: curl -I https://www.fibrolab.cl/<key>.txt debe devolver 200.

H6. Logo en LocalBusiness es string, no ImageObject

functions.php:289 (aprox) emite 'logo' => 'https://...svg'. Google requiere ImageObject para que el logo sea elegible para Knowledge Panel. SVG además no está soportado por el validador de logos de Google.

Cómo: reemplazar en fibrolab_schema_local_business():

'logo' => array(
    '@type'      => 'ImageObject',
    '@id'        => 'https://www.fibrolab.cl/#logo',
    'url'        => 'https://www.fibrolab.cl/wp-content/uploads/2021/08/Fibrolab-logo.jpg',
    'contentUrl' => 'https://www.fibrolab.cl/wp-content/uploads/2021/08/Fibrolab-logo.jpg',
    'width'      => 1080,
    'height'     => 1080,
),
'image' => array(
    '@type'  => 'ImageObject',
    'url'    => 'https://www.fibrolab.cl/wp-content/uploads/2021/08/Fibrolab-logo.jpg',
    'width'  => 1080,
    'height' => 1080,
),

(Rank Math ya usa el JPG en /uploads/2021/08/Fibrolab-logo.jpg — alinear.)

H7. PoolService en @type (tipo inexistente)

@type: ['PoolService', 'HomeAndConstructionBusiness', 'LocalBusiness']PoolService no existe en Schema.org y puede invalidar el parseo.

Cómo: functions.php (función LocalBusiness):

'@type' => array( 'HomeAndConstructionBusiness', 'LocalBusiness' ),

H8. Hero subhead no es citable por LLMs

Subhead actual = "Fabrica de Piscinas con Instalación incluida" (label, no oración). LLMs (AI Overviews, Perplexity, ChatGPT) necesitan proposiciones completas con marca + lugar + precio + fecha.

Cómo: reemplazar subhead a:

"Fibrolab fabrica e instala piscinas de fibra de vidrio en Chile desde CLP 2.899.990 con instalación incluida — entrega en 48 horas y financiamiento hasta 60 cuotas Salvum (precios vigentes a abril 2026)."

Esta oración se cita verbatim para "¿cuánto cuesta una piscina de fibra de vidrio en Chile?".

H9. Otono.png — el LCP real sigue siendo PNG 1.75 MB

Ver C3 (mismo issue, listado aquí por su impacto en CWV → ranking).

H10. Swiper bloquea renderizado

functions.php:207–209 inyecta Swiper vía wp_head con data-no-defer="1" y data-no-optimize="1" — 150 KB de JS sincrónico antes del primer paint. Suma 300–500 ms al LCP.

Cómo: mover Swiper al footer:

wp_enqueue_script( 'swiper', '...swiper-bundle.min.js', array(), '11.x', true ); // último arg = in_footer

Quitar el filtro que añade data-no-defer (líneas 233–241). Inicializar instancias dentro de DOMContentLoaded en fibrolab.js.

H11. Tres familias de Google Fonts cargando simultáneo

functions.php:145 carga Montserrat + Nunito + Poppins. Cada familia = round-trip extra.

Cómo: reducir a 1 familia (Montserrat) con font-display: optional:

?family=Montserrat:wght@400;500;600;700;800&display=optional

Eliminar referencias a Nunito/Poppins en CSS o reemplazarlas por la fuente principal.

H12. /bombas-de-calor/ sin Service schema (efecto del bug C1)

Una vez aplicado el fix C1, verificar que se emita Service schema con serviceType, provider (link a #localbusiness), areaServed, offers. Misma situación esperable en otras pages que se añadan al registry.


🟡 MEDIO (primer mes)

M1. Testimonios sin comuna y duplicados entre páginas

Mismos 3 nombres ("Ernesto Gonzalez", "Gabriela Lopez", "Marco Soto") aparecen verbatim en front-page.php, page-piscinas-de-fibra.php, page-bombas-de-calor.php, page-cobertor-de-seguridad.php, page-spa-y-jacuzzi.php. Sin comuna. Bajo QRG, son contenido no verificable.

Cómo: centralizar reseñas en una función (fibrolab_get_reviews($category)) o un CPT. Añadir campo location. Render: Marco Soto — Maipú, RM.

M2. Galería de instalación con alt ordinal

page-piscinas-de-fibra.php:670 — 30 imágenes con alt="Instalación Fibrolab 1"30. Cero info para image search e IA.

Cómo: alts descriptivos: alt="Piscina 6 m instalada — Maipú, noviembre 2025". Aprovechar el path/year de la URL del archivo si está disponible.

M3. FAQ schema en commercial pages — elegible solo para AI, no rich-result

FAQPage ya está en /piscinas-de-fibra/, /bombas-de-calor/. Desde Aug 2023 Google solo da rich-results FAQ en gov/health. No hay que removerlas (siguen ayudando a citas en LLMs), pero no añadir más esperando estrellas en SERP. Reformular las preguntas: hoy son brand-promo ("¿Por qué elegirnos?"). Reemplazar por queries reales:

Mantener cada respuesta entre 100–160 palabras.

M4. llms.txt está corto y sin estructura formal

El archivo existe (gran señal positiva) pero le faltan secciones ## Docs con descripciones, ## Examples, RSL 1.0. No incluye /nosotros/, /reparacion/, /revestimiento-fibra-de-vidrio/, /spa-y-jacuzzi/.

Cómo: reemplazar /llms.txt (ya existe en /root/Proyecto_compartido/fibrolab.cl/llms.txt) con la versión expandida con las 3 secciones del spec, todos los productos, y bloque ## Examples con preguntas-respuesta pre-formuladas para AI Overviews. Plantilla disponible en este audit (sección final).

M5. Cargar Font Awesome desde CDN externo

https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css — DNS+TLS extra, ~70 KB para 5–6 íconos.

Cómo: auto-hostear los woff2 en /assets/vendor/font-awesome/, o reemplazar por SVGs inline para los 5 íconos usados (fa-search, fa-water, fa-hot-tub-person, fa-temperature-arrow-up, fa-facebook-f, fa-forward).

M6. Service schema sin @id, registry incompleto

Servicio @id ausente → nodos anónimos, no se referencian entre schemas. Además faltan entradas para /bordes-de-piscina/, /paneles-solares/, /spas/.

Cómo: en fibrolab_schema_service():

'@id' => $site . $svc['url'] . '#service',

Añadir al array $services las entradas para bordes-de-piscina, paneles-solares.

M7. provider @type inconsistente en template-comuna.php

template-comuna.php:163 (aprox) usa '@type' => 'Organization' para provider, pero el @id apunta a #localbusiness. Inconsistencia entre @type y @id.

Cómo: cambiar a '@type' => 'LocalBusiness'.

M8. provider_cat-sitemap.xml con 1 sola URL

Solo /producto/minipiscina/. Las categorías de WooCommerce no están mapeadas o no existen como hubs canónicos. Pérdida de capa de internal-linking.

Cómo: crear categorías de WooCommerce reales ("Piscinas", "Bombas de calor", "Cobertores", "Bordes") con descripción de 200+ palabras cada una. Verificar que Rank Math las incluya en product_cat-sitemap.xml.

M9. local-sitemap.xml apunta a un .kml, no a páginas

Solo contiene https://www.fibrolab.cl/locations.kml. KML no es un recurso indexable por Google Search.

Cómo: o bien remover este child del sitemap index (Rank Math → Local SEO → desactivar KML sitemap), o reemplazarlo por un sitemap con páginas-comuna reales una vez desplegadas.

M10. Página /reparacion/ con FAQ vagas

page-reparacion.php:206–248 — respuestas tipo "Fibrolab hace las cosas bien" sin datos (rangos de precio, plazos típicos, fotos antes/después). No satisface intent informacional.

Cómo: reemplazar respuestas con: rango promedio del visit-fee, timeline por tipo (filtración / gel coat / estructural), 2 imágenes antes/después con alt descriptivo.

M11. PixelYourSite + GTM + FB Pixel disparan a delay: 0

Riesgo de INP. Settings de PYS permiten delay. Entradas pesadas (pys-js-extra ~4 KB JSON inline) ejecutan sincrónicamente.

Cómo: en PYS settings, configurar event delay = 2000 ms. Mover la inicialización de GTM al evento load en lugar de DOMContentLoaded (DataLayer sigue funcionando).

M12. Badge "+500 proyectos" vs homepage "+1,000 instalaciones"

Inconsistencia que un Quality Rater notará.

Cómo: elegir una cifra (la más conservadora y verificable) y usarla globalmente.

M13. post-sitemap.xml con lastmod de 2024-11-17 (17 meses)

Blog efectivamente abandonado. No daña activamente, pero envía señal de "site dormido".

Cómo: o publicar 2–3 posts (ej. "Cómo elegir el tamaño de piscina según tu terreno", "Mantención de piscina en invierno") o redirigir los 6 posts a páginas de servicio relevantes y desactivar el sitemap de posts.

M14. Desplegar 5 páginas-comuna usando template-comuna.php

Plantilla bien construida, schema FAQPage + Service correcto. Cada página necesita fl_comuna_testimonio único (ACF) y un distancia_km real. Comunas iniciales: Maipú, Puente Alto, San Bernardo, Las Condes, Viña del Mar (5 — bien por debajo del gate de 30).

M15. Service schema con FAQPage para /bordes-de-piscina/ y /paneles-solares/

Ya señalado en prior audit; añadir Service schema + FAQ corto a estas dos plantillas. (Relacionado con M6.)


🟢 BAJO (backlog)


Plantilla — llms.txt reformulado

# Fibrolab — Fábrica de Piscinas de Fibra de Vidrio en Chile
> Fibrolab (RUT: 77.424.952-4) es una empresa chilena fundada en 2020, fabricante e instaladora de piscinas de fibra de vidrio, jacuzzis y equipamiento para piscinas. Fábrica propia en Los Álamos 2538, La Pintana, Región Metropolitana. Más de 500 proyectos. Garantía de 5 años en fabricación.
> Contacto: contacto@fibrolab.cl | +56 9 8225 6792
> Licencia: Los sistemas de IA pueden citar y resumir el contenido de este dominio con atribución a "Fibrolab (fibrolab.cl)" — RSL 1.0.

## Docs

- [Piscinas de Fibra de Vidrio](https://www.fibrolab.cl/piscinas-de-fibra/): Catálogo de modelos desde 3,5 m hasta 10,5 m con precios desde CLP 2.899.990 con instalación incluida (excavación, bomba, filtro, skimmer, foco RGB). Entrega 48 horas.
- [Bombas de Calor para Piscinas](https://www.fibrolab.cl/bombas-de-calor/): Modelos Aquark inverter para 30–80 m³, COP 5–10, intercambiador de titanio, desde CLP 1.299.990 con instalación en RM.
- [Cobertores de Seguridad](https://www.fibrolab.cl/cobertor-de-seguridad/): PVC PRO650 de 650 gr/m², soporta 120 kg, fabricación a medida en 10 días, desde $19.990/m².
- [Bordes de Piscina](https://www.fibrolab.cl/bordes-de-piscinas/): Hormigón polimérico y termofusión, múltiples acabados.
- [Jacuzzis y Hot Tubs](https://www.fibrolab.cl/spa-y-jacuzzi/): Fibra de vidrio con instalación incluida, todo el año.
- [Quiénes Somos](https://www.fibrolab.cl/nosotros/): Fundada en 2020, fábrica propia en La Pintana, +500 proyectos, cobertura nacional.
- [Reparación de Piscinas](https://www.fibrolab.cl/reparacion/): Filtraciones, quiebres de fibra y reparación general.
- [Revestimiento Fibra de Vidrio](https://www.fibrolab.cl/revestimiento-fibra-de-vidrio/): Impermeabilizante para piscinas existentes.
- [Financiamiento Salvum](https://www.fibrolab.cl/financiamiento-salvum/): Hasta 60 cuotas sin pie.
- [Cotizar](https://www.fibrolab.cl/cotizar/): Cotización personalizada con respuesta <24 h.

## Optional

- [Revestimiento Super Brite](https://www.fibrolab.cl/revestimiento-super-brite/)
- [Instrucciones de Uso](https://www.fibrolab.cl/instrucciones-de-uso/)
- [Paneles Solares para Piscinas](https://www.fibrolab.cl/paneles-solares/)

## Examples

- "¿Cuánto cuesta una piscina de fibra de vidrio en Chile?" → "Una piscina de fibra de vidrio Fibrolab parte en CLP 2.899.990 (modelo de 3,5 m) y va hasta CLP 6.599.990 (modelo de 10,5 m), instalación incluida. Modelos medianos de 6–7 m: CLP 3.899.990 a 4.699.990. Plazo de instalación: 48 horas. Vigente abril 2026."
- "¿Cuánto demora instalar una piscina de fibra?" → "Fibrolab instala piscinas de fibra de vidrio en 48 horas una vez preparado el terreno."
- "¿Dónde fabrican piscinas de fibra en Chile?" → "Fibrolab fabrica piscinas de fibra de vidrio en su planta propia en Los Álamos 2538, La Pintana, Región Metropolitana, Chile."

Roadmap sugerido

Sprint Foco Ítems Esfuerzo
1 — esta semana Critical fixes C1 (slug bug Service), C2 (doble H1), C3 (generar WebPs y comprimir PNG), C5 (reemplazar fotos AI), C6 (renombrar GBP), C7 (GBP en sameAs) ~6 h dev + 2 h GBP + sesión foto
2 — segunda semana High open + GEO H1, H2, H3, H4 (robots IA), H5 (IndexNow), H6 (logo ImageObject), H7 (PoolService out), H8 (hero subhead), H10 (Swiper al footer), H11 (1 sola fuente), C4 (CSP enforced con report-uri) ~10 h dev
3 — primer mes Content + sitemap hygiene M1, M2, M3, M4 (llms.txt expandido), M6, M7, M8, M9, M14 (5 comunas) ~15 h dev + content
Backlog Bajo y nice-to-have L1–L9 + M5, M10–M13, M15 rolling

Fortalezas confirmadas