Auditoría SEO — fibrolab.cl (re-audit v3)

Fecha: 2026-04-29 (tercera corrida del día) URL: https://www.fibrolab.cl/ Tipo de negocio: Hybrid — Manufacturer + LocalBusiness + HomeAndConstructionBusiness + SAB nacional. Fábrica en La Pintana, instalación en todo Chile. Stack: WordPress + WooCommerce + Rank Math + LiteSpeed Cache + GTM-W6DGGKK + PixelYourSite Free 11.2.0.4 Idioma: es-CL (hreflang es-CL + x-default autorreferenciados) NAP: Fibrolab · Los Álamos 2538, La Pintana, Región Metropolitana · +56 9 8225 6792 · contacto@fibrolab.cl · RUT 77.424.952-4

Metodología: auditoría fresca independiente con 8 subagentes en paralelo (technical, content, schema, sitemap, performance, visual, geo, local) + verificación manual cruzada con curl/Python contra el HTML live. Algunos subagentes (performance, geo, local) no completaron entrega: sus áreas se cubrieron con verificación manual y consolidación con findings de v2.


SEO Health Score — 64 / 100 (↑ 1 vs v2 = 63)

Categoría Peso Score Ponderado
Technical SEO 22% 74 16.28
Content Quality / E-E-A-T 23% 59 13.57
On-Page SEO 20% 62 12.40
Schema / Datos estructurados 10% 61 6.10
Performance (CWV proxy) 10% 70 7.00
AI Search Readiness (GEO) 10% 50 5.00
Imágenes 5% 75 3.75
Total ~64

Local SEO (informativo, fuera de fórmula): 49/100 (↓ 9 vs v2 informativo de 58) — el agente local detectó que template-comuna.php ya está construido completo (con h1 dinámico, FAQ localizado, schema Service + FAQPage con AdministrativeArea, WhatsApp pre-filled, distancia desde fábrica) pero 0 páginas comunales publicadas — el factor #1 de ranking en local pack según Whitespark 2026. Además: testimonios hardcoded sin importar como WC reviews (AggregateRating omitido), hasMap ausente en schema, sin SEC license number.

Lectura: el sitio mejoró marginalmente. Varios fixes de la v2 sí aterrizaron en código, pero los 9 issues críticos clave que bloquean rich results y compliance regulatorio chileno siguen abiertos. Score plano refleja un avance en backend/seguridad sin progreso en compliance/Merchant Center/AI citation.


Estado de fixes pendientes desde v2 (verificación live HTML)

❌ NO FIXEADOS (siguen igual que v2)

  1. Title sin tilde<title>Fabrica de Piscinas FIBROLAB...</title> aún sin "Fábrica". OG arrastra el error.
  2. Meta description "más de 6 años" vs OG description "6 años" coherente entre sí pero contradice foundingDate: 2020 (~6 años). Aceptable; pero si la lectura es "experiencia previa del equipo" hay que decirlo.
  3. hasMerchantReturnPolicy + shippingDetails ausentes en Product Offer — confirmado en /modelo/piscina-4-8-metros/. Bloquea Google Merchant Center.
  4. @type LocalBusiness sin Manufacturerfunctions.php:300 sigue ['HomeAndConstructionBusiness', 'LocalBusiness'].
  5. postalCode 8830000 no verificado contra Correos de Chile.
  6. sameAs sin URL del Google Business Profile — solo Facebook + Instagram.
  7. Embed Google Maps ausente en todos los templates.
  8. /contacto/ 301→home — la página de contacto sigue sin existir.
  9. Páginas legales 404/politica-de-privacidad/, /terminos-y-condiciones/, /privacidad/ siguen devolviendo 404.
  10. Sin mención Sernac / Ley 19.496 / CAE en home, /financiamiento-salvum/ ni /nosotros/. Riesgo activo con Sernac.
  11. BreadcrumbList de producto incompleto/modelo/piscina-4-8-metros/ aún emite solo "Inicio → Piscina 4.8 Metros".
  12. og:type "article" en /spas/, /jacuzzi/, /piscinas-de-fibra/ — debería ser "website" o "product".
  13. URL incorrecta en llms.txt — sigue listando /spa-y-jacuzzi/ en lugar de /jacuzzi/. La URL ahora hace 301 (mejora vs v2 que decía que estaba rota), pero llms.txt debe apuntar a la canónica.
  14. Speakable schema ausente en todas las páginas — 0 ocurrencias en HTML live.
  15. Pasajes "first-40-words" definitorios faltan en /piscinas-de-fibra/, /spas/, /jacuzzi/, /reparacion/.

✅ NUEVOS HALLAZGOS NO DETECTADOS EN V2

  1. Type-collision en JSON-LD del home (NEW) — Block 1 (Rank Math) emite "@type": "Organization" con "@id": "https://www.fibrolab.cl/#localbusiness". Block 2 (custom theme) emite "@type": ["HomeAndConstructionBusiness", "LocalBusiness"] con el mismo @id. El alias @id es intencional (v2 lo cita como fix correcto), pero los dos nodos publicados con el mismo @id deberían tener tipos compatibles. Solución: agregar "Organization" al array de tipos del block 2 → ["Organization", "Manufacturer", "HomeAndConstructionBusiness", "LocalBusiness"]. Esto unifica la entidad, agrega Manufacturer y elimina la colisión. (Severidad: HIGH)

  2. /paneles-solares/ devuelve 404 (NEW) — la URL retorna 404 con <title>Página no encontrada | Fibrolab</title> y meta robots="follow, noindex". El template page-paneles-solares.php aún existe en el tema (visible en git status), pero la página WP fue eliminada. El footer en v2 ya tenía el enlace comentado. Si el servicio sigue activo, recrear la página; si fue descontinuado, remover el archivo PHP. (Severidad: HIGH — pérdida de tráfico orgánico potencial)

  3. Font Awesome cargado externo desde cdnjs.cloudflare.com (NEW) — verificado en HTML live: <link rel='stylesheet' id='font-awesome-css' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css'>. Render-blocking + RTT DNS+TLS al critical path, pese a tener preconnect. Self-hostal junto a Swiper para que LiteSpeed lo combine. (Severidad: HIGH — LCP -200/-300ms en mobile 3G/4G)

  4. CSS principal 271KB sin defer aplicado en código (NEW) — el comentario en functions.php:142-150 describe la estrategia media='print' onload, pero el filtro style_loader_tag que la aplica no está implementado en el código actual. LiteSpeed Cache combina el CSS en un único archivo hasheado (/wp-content/litespeed/css/8ba678a6be1fe2d796dc0afd41af5f98.css), pero el atributo media="print" no aparece en el HTML live. Resultado: render-blocking efectivo. (Severidad: HIGH — verificar y aplicar filtro)

  5. OpenReplay tracker en wp_head priority 1 (NEW)functions.php:1461. El bootstrap inline ocupa el slot más alto del head, antes de los preloads del LCP hero. Mover a footer priority 20. (Severidad: HIGH)

  6. Hero de páginas de servicio como background-image CSS (NEW)page-piscinas-de-fibra.php:28, page-nosotros.php:20, page-jacuzzi.php. El preload scanner del navegador no detecta imágenes en background-image, retrasando LCP 400-800ms. La home sí usa <img fetchpriority="high">. (Severidad: HIGH)

  7. Hero del home en mobile sin texto ni CTA (NEW)<picture> puro con aspect-ratio: 768/900 (~117vw) y H1 en última sección. El usuario móvil ve solo una foto sin value prop ni CTA above-the-fold. (Severidad: CRITICAL UX — bloquea conversión móvil directa)

  8. .fibrolab-product-card__title { font-size: 9px } en mobile (NEW) — viola mínimo de legibilidad Google (12px) y estándar UX (14-16px). Aplica a home, /piscinas-de-fibra/, /spas/. Una línea de CSS arregla. (Severidad: CRITICAL)

  9. 30 imágenes con loading="eager" + data-no-lazy="1" en #fl-cat-gallery (NEW)/piscinas-de-fibra/ carga 30 imágenes en paralelo al LCP, saturando bandwidth. Cambiar a loading="lazy". (Severidad: HIGH)

  10. post-sitemap.xml con lastmod 2024-11-17 (NEW) — el sub-sitemap de blog está congelado hace 17 meses, sugiere que el blog no se actualiza. Crawl budget desperdiciado. (Severidad: MEDIUM — más de UX/contenido que técnico)

  11. Logs accesibles en uploads (NEW)csp-violations.log e indexnow.log en /wp-content/uploads/ no bloqueados en robots.txt y potencialmente indexables. Fuente: agente technical. (Severidad: MEDIUM)

  12. Bots IA importantes faltantes en robots.txt (NEW) — robots.txt declara reglas para GPTBot/OAI-SearchBot/ClaudeBot/PerplexityBot/Google-Extended/CCBot, pero falta Google-CloudVertexBot (Gemini), anthropic-ai, Bytespider. (Severidad: LOW)

  13. template-comuna.php completamente construido, 0 páginas comunales publicadas (NEW) — el template tiene h1 dinámico, FAQ localizado por comuna, schema Service + FAQPage con AdministrativeArea, WhatsApp pre-filled CTA, campo distancia desde fábrica. Listo para publicar. Cero usos en producción (verificado en page-sitemap.xml con 11 URLs, ninguna /piscinas-en-*/). El factor #1 de ranking en local pack es páginas dedicadas por área de servicio (Whitespark 2026). Comunas prioritarias por volumen de búsqueda: Maipú, Puente Alto, San Bernardo, Las Condes, Providencia, Ñuñoa, Peñalolén, Vitacura. (Severidad: HIGH — máximo ROI local)

  14. 10 testimonios hardcoded en front-page.php:208-268 no importados como WC reviews (NEW) — la lógica fibrolab_get_aggregate_rating() (functions.php:388-416) emite aggregateRating solo si hay reviews aprobadas en WooCommerce. Los 10 clientes reales (Felipe Faundez, Katherine Meller, etc.) aparecen visualmente pero no en schema. Sin estrellas en SERP. Importarlos vía admin (inc/fl-reviews.php) los expone al schema sin escribir contenido nuevo. (Severidad: HIGH)

  15. hasMap ausente en LocalBusiness schema (NEW) — agregar 'hasMap' => 'https://maps.app.goo.gl/[PLACE_ID]' al schema. Combinado con A2 (sameAs GBP), refuerza la disambiguación de la entidad local. (Severidad: HIGH)

  16. SEC license number ausente / sin hasCredential (NEW)/nosotros/ no muestra el N° SEC y el schema LocalBusiness no incluye hasCredential. Para una empresa que instala piscinas de fibra (sistema eléctrico de la bomba + iluminación), la inscripción SEC es regulatoria. (Severidad: MEDIUM)

✅ FIXES CONFIRMADOS DESDE V2 (siguen estables)


Plan de acción priorizado

CRÍTICO (esta semana — bloqueadores de revenue / compliance)

# Acción Archivo:Línea Esfuerzo
C1 Agregar hasMerchantReturnPolicy + shippingDetails al $offer array en fibrolab_schema_product() functions.php:595-608 30 min — bloquea Google Shopping
C2 Crear /contacto/ (eliminar el 301 a home) con NAP completo + iframe Maps + formulario + schema ContactPage + Organization.contactPoint nueva página 2-3h
C3 Crear /politica-de-privacidad/ (Ley 19.628) y /terminos-y-condiciones/ (Ley 19.496); enlazar en footer nuevas páginas + footer.php:73-88 3h (texto plantilla + revisión)
C4 Agregar CAE + ejemplo representativo + RUT/CMF de Forum Servicios Financieros en /financiamiento-salvum/ (Art. 37 Ley 19.496) page-financiamiento-salvum.php 1h
C5 Hero del home mobile: añadir capa absoluta con H1 + value prop + botón "Cotizar" sobre .fibrolab-hero__slide.is-active front-page.php + CSS 1h
C6 Subir font-size de .fibrolab-product-card__title de 9px a 13px en mobile assets/css/fibrolab.css (regla @media (max-width: 768px)) 5 min
C7 Corregir title sin tilde + unificar copy "fundada 2020" / "experiencia 6 años": en Rank Math → Inicio → Título SEO + Descripción + Social Rank Math admin 15 min
C8 Corregir URL /spa-y-jacuzzi//jacuzzi/ en /llms.txt archivo en raíz 2 min
C9 Resolver /paneles-solares/ 404: recrear página WP o eliminar page-paneles-solares.php y templates/sections/financiamiento-salvum.php (?) decisión de producto 30 min-2h
C10 Publicar 8 páginas comunales usando template-comuna.php (Maipú, Puente Alto, San Bernardo, Las Condes, Providencia, Ñuñoa, Peñalolén, Vitacura). Llenar campos ACF: fl_comuna_nombre, fl_comuna_region, fl_comuna_lat, fl_comuna_lng, fl_comuna_testimonio, fl_comuna_distancia_km template ya existe 1-2 días — máximo ROI local pack
C11 Importar los 10 testimonios del home como reviews WooCommerce vía admin (inc/fl-reviews.php → "Importar reseñas"). Activa aggregateRating y estrellas en SERP sin escribir contenido nuevo WP Admin 1h

ALTO (próximas 2 semanas)

# Acción Archivo:Línea Esfuerzo
A1 @type LocalBusiness: agregar Organization + Manufacturer['Organization', 'Manufacturer', 'HomeAndConstructionBusiness', 'LocalBusiness'] (resuelve type-collision con Rank Math) functions.php:300 5 min
A2 sameAs agregar URL pública del Google Business Profile (formato https://maps.app.goo.gl/...). Prerequisito: reclamar/verificar GBP functions.php:348-351 30 min admin + 5 min código
A3 Verificar postalCode La Pintana en Correos de Chile y reemplazar 8830000 si es incorrecto functions.php:326 10 min
A4 BreadcrumbList producto: agregar nivel intermedio Piscinas de Fibra → /piscinas-de-fibra/ (lógica de mapeo product_cat → página hub) functions.php:680-686 (snippet en sección "Schema fixes" abajo) 1h
A5 Self-host Font Awesome 6.5.1 en /assets/vendor/fontawesome/ (eliminar dependencia cdnjs) functions.php:182-188 30 min
A6 Implementar filtro style_loader_tag para defer real de fibrolab.css (media='print' onload) functions.php (snippet abajo) 15 min
A7 Mover OpenReplay tracker de wp_head priority 1 → wp_footer priority 20 functions.php:1461 5 min
A8 Convertir hero background-image en /piscinas-de-fibra/ y /nosotros/ a <img fetchpriority="high"> con preload page-piscinas-de-fibra.php:28, page-nosotros.php:20 2h
A9 loading="lazy" en las 30 imágenes de #fl-cat-gallery (eliminar data-no-lazy="1") page-piscinas-de-fibra.php (galería) 15 min
A10 og:type "article" → "website" en /spas/, /jacuzzi/, /piscinas-de-fibra/ Rank Math por página → Social → OG Type 10 min
A11 Agregar Speakable schema en home (cssSelector apuntando a H1 + hero subtitle) functions.php (snippet abajo) 20 min
A12 Agregar WebSite + SearchAction para Sitelinks Searchbox (verificar si Rank Math ya lo emite) Rank Math o functions.php 30 min
A13 Agregar AboutPage schema en /nosotros/ functions.php (snippet abajo) 15 min
A14 Agregar CollectionPage schema en archives /producto-categoria/*/ functions.php (snippet abajo) 30 min
A15 Pasajes "first-40-words" definitorios en /piscinas-de-fibra/, /spas/, /jacuzzi/, /reparacion/ — abrir cada página con definición técnica citable, no banner promocional templates page-*.php 3-4h (4 páginas × 45 min)
A16 Tabla comparativa fibra vs hormigón vs proyectado en /piscinas-de-fibra/ + replicar en llms.txt page-piscinas-de-fibra.php + llms.txt 2h
A17 Definición spa vs jacuzzi + tabla diferencial en /spas/ o /jacuzzi/ template 1.5h
A18 Specs técnicas (jets, capacidad, kW, voltaje, dimensiones) en /spas/ y /jacuzzi/; mover modal JS de equipamiento /piscinas-de-fibra/ a tabla HTML estática templates 3h
A19 Equipo nombrado + bio fundador + foto + certificaciones en /nosotros/ (target 600 palabras vs 310 actuales) page-nosotros.php 4h (texto + foto)
A20 Reescribir FAQs /piscinas-de-fibra/ (eliminar "muchos años en el mercado", reescribir con datos: 1.000+ instalaciones, ISO-NPG, etc.) page-piscinas-de-fibra.php:765-790 2h
A21 Testimonios: agregar campo location (comuna) al array de front-page.php:208-268 front-page.php 30 min
A22 IndexNow: agregar hook woocommerce_update_product para cubrir cambios de precio sin transición de status functions.php:1583 15 min
A23 Agregar hasMap a LocalBusiness: 'hasMap' => 'https://maps.app.goo.gl/[PLACE_ID]' functions.php:297 5 min
A24 Embed Google Maps en footer.php (CSP ya tiene frame-src https://www.google.com) + link "Cómo llegar" footer.php 30 min
A25 Agregar hasCredential con N° SEC a LocalBusiness schema functions.php:297 30 min
A26 FAQPage schema en page-piscinas-de-fibra.php, page-bombas-de-calor.php, page-jacuzzi.php (ya está en /reparacion/ y /financiamiento-salvum/) — beneficio GEO/AI, no rich result Google templates 2h

MEDIO (siguiente mes)

# Acción Detalle
M1 Bloquear csp-violations.log e indexnow.log en robots.txt o moverlos a wp-content/logs/ con .htaccess Deny from all 15 min
M2 Agregar Google-CloudVertexBot, anthropic-ai (Allow), Bytespider (Disallow) a robots.txt 5 min
M3 Refrescar blog (post-sitemap.xml lastmod 2024-11-17 — 17 meses sin update). Mínimo: 1 post mensual con datos técnicos chilenos continuo
M4 priceValidUntil con timezone explícita: cambiar date('Y-12-31') por date('Y-12-31\TH:i:sP') ISO 8601 con offset functions.php:602
M5 Product agregar manufacturer apuntando a #localbusiness functions.php:572
M6 Agregar LoanOrCredit schema en /financiamiento-salvum/ (beneficio GEO, no rich result Google) page-financiamiento-salvum.php
M7 Mejorar tap targets a 48px+ (.fl-mobile-cta__btn, .fibrolab-menu-toggle) CSS
M8 min-height en .fl-cat-hero--visual para prevenir CLS si imagen tarda CSS
M9 Single product mobile: order: 1 en .fl-single__summary para que H1+precio+CTA aparezcan antes que galería CSS
M10 Fallback CSS para elementos [data-animate]: html:not(.js-animate-ready) [data-animate] { opacity: 1 !important; } CSS
M11 Body padding-bottom: 56px incondicional en mobile (eliminar dependencia de JS para sticky CTA, evita CLS) CSS
M12 URL en shortcode [cotizar] con rawurlencode() functions.php:1146

BAJO (backlog)

# Acción
L1 Header X-XSS-Protection deprecado — remover (LiteSpeed config)
L2 Directivas residuales fonts.googleapis.com en CSP — remover (functions.php:1031)
L3 og:locale es_CL no en lista oficial Facebook — usar es_LA o sin locale
L4 Anuncios bar font-size:11px mobile → 12px
L5 /tienda2/ configurar redirect 301 explícito o noindex

Snippets de fix listos para copy-paste

A1 — @type LocalBusiness con Organization + Manufacturer

// functions.php:300 — cambiar de:
'@type' => array( 'HomeAndConstructionBusiness', 'LocalBusiness' ),
// a:
'@type' => array( 'Organization', 'Manufacturer', 'HomeAndConstructionBusiness', 'LocalBusiness' ),

C1 — hasMerchantReturnPolicy + shippingDetails en Product Offer

// functions.php — dentro del array $offer en fibrolab_schema_product(), después de 'seller':
'hasMerchantReturnPolicy' => array(
    '@type'                => 'MerchantReturnPolicy',
    '@id'                  => 'https://www.fibrolab.cl/#return-policy',
    'applicableCountry'    => 'CL',
    'returnPolicyCategory' => 'https://schema.org/MerchantReturnNotPermitted',
    'merchantReturnDays'   => 0,
),
'shippingDetails' => array(
    '@type'               => 'OfferShippingDetails',
    'shippingRate'        => array(
        '@type'    => 'MonetaryAmount',
        'value'    => '0',
        'currency' => 'CLP',
    ),
    'shippingDestination' => array(
        '@type'          => 'DefinedRegion',
        'addressCountry' => 'CL',
    ),
    'deliveryTime' => array(
        '@type'        => 'ShippingDeliveryTime',
        'handlingTime' => array(
            '@type'    => 'QuantitativeValue',
            'minValue' => 1,
            'maxValue' => 3,
            'unitCode' => 'DAY',
        ),
        'transitTime'  => array(
            '@type'    => 'QuantitativeValue',
            'minValue' => 1,
            'maxValue' => 2,
            'unitCode' => 'DAY',
        ),
    ),
),

Nota legal: Ley 19.496 (Chile) Art. 3 lit. e) garantiza derecho de retracto en compras online por 10 días. Para piscinas instaladas (servicio prestado y bienes personalizados Art. 3 ter), la categoría correcta puede ser MerchantReturnFiniteReturnWindow con merchantReturnDays: 10 y aclaración. Confirmar con asesor legal antes de subir.

A6 — Defer real de fibrolab.css

// functions.php — agregar después del enqueue de fibrolab-style:
add_filter( 'style_loader_tag', function ( $tag, $handle ) {
    if ( in_array( $handle, array( 'fibrolab-style', 'swiper' ), true ) ) {
        $tag = str_replace( "media='all'", "media='print' onload=\"this.media='all'\"", $tag );
        $tag .= '<noscript>' . str_replace( "media='print' onload=\"this.media='all'\"", "media='all'", $tag ) . '</noscript>';
    }
    return $tag;
}, 10, 2 );

A11 — Speakable schema en home

// functions.php — nuevo hook (o dentro de fibrolab_schema_local_business cuando is_front_page()):
add_action( 'wp_head', function () {
    if ( ! is_front_page() ) return;
    $speakable = array(
        '@context'  => 'https://schema.org',
        '@type'     => 'WebPage',
        '@id'       => 'https://www.fibrolab.cl/#webpage',
        'speakable' => array(
            '@type'       => 'SpeakableSpecification',
            'cssSelector' => array( 'h1', '.fl-ns-hero__subtitle', '.fibrolab-intro p:first-of-type' ),
        ),
    );
    echo '<script type="application/ld+json">' . wp_json_encode( $speakable, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . '</script>' . "\n";
}, 25 );

A4 — BreadcrumbList con categoría intermedia

// functions.php — reemplazar el bloque is_singular('product') en fibrolab_schema_breadcrumbs() (~L680):
if ( is_singular( 'product' ) ) {
    global $product;
    if ( ! $product ) $product = wc_get_product( get_the_ID() );
    $cat_map = array(
        'piscinas-de-fibra' => array( 'name' => 'Piscinas de Fibra', 'url' => '/piscinas-de-fibra/' ),
        'jacuzzi'           => array( 'name' => 'Jacuzzis',           'url' => '/jacuzzi/' ),
        'spa'               => array( 'name' => 'Spas',               'url' => '/spas/' ),
        'bombas-de-calor'   => array( 'name' => 'Bombas de Calor',    'url' => '/bombas-de-calor/' ),
    );
    $terms = get_the_terms( get_the_ID(), 'product_cat' );
    if ( $terms && ! is_wp_error( $terms ) ) {
        $primary = $terms[0];
        if ( isset( $cat_map[ $primary->slug ] ) ) {
            $items[] = array(
                '@type'    => 'ListItem',
                'position' => $pos++,
                'name'     => $cat_map[ $primary->slug ]['name'],
                'item'     => 'https://www.fibrolab.cl' . $cat_map[ $primary->slug ]['url'],
            );
        }
    }
    $items[] = array(
        '@type'    => 'ListItem',
        'position' => $pos++,
        'name'     => get_the_title(),
        'item'     => get_permalink(),
    );
}

A13 — AboutPage en /nosotros/

add_action( 'wp_head', function () {
    if ( ! is_page( 'nosotros' ) ) return;
    $schema = array(
        '@context'    => 'https://schema.org',
        '@type'       => 'AboutPage',
        '@id'         => 'https://www.fibrolab.cl/nosotros/#aboutpage',
        'url'         => 'https://www.fibrolab.cl/nosotros/',
        'name'        => 'Nosotros — Fibrolab',
        'description' => 'Fábrica e instalación de piscinas de fibra de vidrio desde 2020. Más de 1.000 instalaciones en todo Chile.',
        'inLanguage'  => 'es-CL',
        'about'       => array( '@id' => 'https://www.fibrolab.cl/#localbusiness' ),
    );
    echo '<script type="application/ld+json">' . wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . '</script>' . "\n";
}, 25 );

C6 — Font size product card mobile

/* assets/css/fibrolab.css — dentro de @media (max-width: 768px): */
.fibrolab-product-card__title { font-size: 13px; line-height: 1.3; }  /* era 9px */
.fibrolab-label { font-size: 10px; }                                   /* era 9px */

Resumen ejecutivo (TL;DR)

Score 64/100 (+1 vs v2). El sitio mejoró en backend (security headers, IndexNow, dedup schema) pero 9 de los issues críticos de v2 siguen sin fixear: title sin tilde, Merchant Center bloqueado por Offer incompleto, /contacto/ inexistente, páginas legales 404, sin CAE/Sernac, Manufacturer ausente del @type, postalCode no verificado, GBP no enlazado, breadcrumb producto incompleto.

Hallazgos NUEVOS (12) detectados en esta corrida que v2 no listó:

  1. Type-collision en JSON-LD home (Organization vs LocalBusiness con mismo @id)
  2. /paneles-solares/ 404 (probable página WP eliminada, template aún existe)
  3. Font Awesome cargado externo desde cdnjs (LCP -200/-300ms)
  4. fibrolab.css 271KB sin defer en código (filtro style_loader_tag no implementado)
  5. OpenReplay en wp_head priority 1 (impacta critical path)
  6. Hero background-image en /piscinas-de-fibra/ y /nosotros/ (preload scanner ciego)
  7. Hero del home mobile sin texto/CTA (above-the-fold huérfano)
  8. font-size: 9px en titulos de product cards mobile
  9. 30 imágenes loading="eager" en galería /piscinas-de-fibra/
  10. post-sitemap.xml con lastmod 2024-11-17 (blog congelado 17 meses)
  11. Logs en uploads accesibles (csp-violations.log, indexnow.log)
  12. Bots IA importantes faltantes en robots.txt (Google-CloudVertexBot, anthropic-ai, Bytespider)

Mayor ROI inmediato (priorizado): C1 (hasMerchantReturnPolicy), C7 (title tilde), C8 (llms.txt URL), C6 (font-size 9px), A1 (Manufacturer + Organization en @type), A6 (defer CSS), A5 (self-host Font Awesome). Total esfuerzo conjunto: ~3 horas; cubre Merchant Center, type-collision, LCP -500ms, AI citation y legibilidad mobile.

Mayor complejidad pero crítico: C2 (página /contacto/), C3 (legales), A19 (/nosotros/ con equipo nombrado). Total ~10 horas pero cierra el gap de Trustworthiness (30% del peso E-E-A-T) y compliance Sernac.

Mayor ROI local pack: C10 — publicar las 8 páginas comunales con template-comuna.php ya construido. Cero código nuevo (solo crear páginas WP y llenar 6 campos ACF por comuna). Es el único item del plan que ataca el factor #1 del local pack ranking (páginas dedicadas por área de servicio). 1-2 días de trabajo de contenido, no de código. Combinado con C11 (importar 10 testimonios → AggregateRating + estrellas en SERP) y A2 (GBP en sameAs), el Local SEO Score sube de 49 → ~75 en una sprint de tres días.


Verificación cruzada de hallazgos

Para evitar falsos positivos, los issues marcados ❌ NO FIXEADOS y los NUEVOS HALLAZGOS fueron verificados en dos fuentes mínimo:

Issue Fuente 1 Fuente 2
Title sin tilde curl <title> OG title meta
hasMerchantReturnPolicy ausente curl + Python parse JSON-LD /modelo/piscina-4-8-metros/ functions.php:595-608 (agente schema)
og:type article en categorías curl <meta property="og:type"> ×3 URLs agente schema
/contacto/ 301→home curl -IL agente local NAP audit
Páginas legales 404 curl HEAD ×3 URLs agente content + agente local
Type-collision JSON-LD home Python parse de los 2 bloques en home agente schema (SC-001)
/paneles-solares/ 404 curl HEAD + GET (redirect a página de error 404 noindex) agente content (footer.php:32 link comentado)
Font Awesome cdnjs curl <link rel='stylesheet'> agente technical (CWV-01)
llms.txt URL incorrecta curl /llms.txt grep "spa-y-jacuzzi" (era issue v2)
Hero mobile sin texto agente visual VIS-001 inspección de front-page.php (H1 al final)
font-size: 9px cards mobile agente visual VIS-005 (verificable abriendo assets/css/fibrolab.css @media (max-width: 768px))
template-comuna.php 0 páginas publicadas agente local page-sitemap.xml (11 URLs, ninguna /piscinas-en-*/)

Falsos positivos descartados durante el cruzado: