{
 "engine_version": 12,
 "as_of": "2026-10-24",
 "app_sha": "17a567b",
 "count": 111,
 "sections": {
  "render": {
   "en": "Content and readability",
   "fr": "Contenu et lisibilité",
   "nl": "Content en leesbaarheid",
   "de": "Inhalt und Lesbarkeit",
   "es": "Contenido y legibilidad"
  },
  "structure": {
   "en": "Titles, headings and schema",
   "fr": "Balises title, titres et données structurées",
   "nl": "Title-tags, koppen en schema",
   "de": "Titel, Überschriften und Schema",
   "es": "Títulos, encabezados y schema"
  },
  "technical": {
   "en": "Links, canonical and speed",
   "fr": "Liens, canonical et vitesse",
   "nl": "Links, canonical en snelheid",
   "de": "Links, Canonical und Geschwindigkeit",
   "es": "Enlaces, canonical y velocidad"
  },
  "access": {
   "en": "AI crawler access",
   "fr": "Accès des robots IA",
   "nl": "Toegang voor AI-crawlers",
   "de": "Zugriff der KI-Crawler",
   "es": "Acceso de crawlers de IA"
  },
  "answers": {
   "en": "Answerability",
   "fr": "Capacité à répondre",
   "nl": "Beantwoordbaarheid",
   "de": "Beantwortbarkeit",
   "es": "Capacidad de respuesta"
  }
 },
 "checks": [
  {
   "check": "robots_gptbot",
   "section": "access",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": "GPTBot",
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt blocks GPTBot",
     "why": "Blocks GPTBot, which collects training data. This keeps your pages out of future model training, not out of ChatGPT or other AI search.",
     "fix": "Only if you want your pages in future model training: remove the Disallow rule for GPTBot. ChatGPT search is governed by OAI-SearchBot."
    },
    "fr": {
     "title": "robots.txt bloque GPTBot",
     "why": "Bloque GPTBot, qui collecte des données d'entraînement. Vos pages restent hors de l'entraînement des futurs modèles, mais pas hors de ChatGPT ni des autres moteurs de recherche IA.",
     "fix": "Seulement si vous voulez vos pages dans l'entraînement des futurs modèles : supprimez la règle Disallow pour GPTBot. La recherche ChatGPT dépend d'OAI-SearchBot."
    },
    "nl": {
     "title": "robots.txt blokkeert GPTBot",
     "why": "Blokkeert GPTBot, die trainingsdata verzamelt. Zo blijven je pagina's buiten toekomstige modeltraining, maar niet buiten ChatGPT of andere AI-zoekmachines.",
     "fix": "Alleen als je wilt dat je pagina's in toekomstige modeltraining komen: verwijder de Disallow-regel voor GPTBot. ChatGPT-zoeken wordt bepaald door OAI-SearchBot."
    },
    "de": {
     "title": "robots.txt blockiert GPTBot",
     "why": "Blockiert GPTBot, der Trainingsdaten sammelt. Ihre Seiten bleiben so aus künftigem Modelltraining heraus, nicht aber aus ChatGPT oder anderer KI-Suche.",
     "fix": "Nur wenn Ihre Seiten in künftiges Modelltraining einfließen sollen: Entfernen Sie die Disallow-Regel für GPTBot. Die ChatGPT-Suche wird über OAI-SearchBot gesteuert."
    },
    "es": {
     "title": "robots.txt bloquea a GPTBot",
     "why": "Bloquea a GPTBot, que recopila datos de entrenamiento. Esto mantiene tus páginas fuera del entrenamiento de futuros modelos, no fuera de ChatGPT ni de otras búsquedas con IA.",
     "fix": "Solo si quieres que tus páginas entren en el entrenamiento de futuros modelos: elimina la regla Disallow para GPTBot. La búsqueda de ChatGPT depende de OAI-SearchBot."
    }
   }
  },
  {
   "check": "robots_claudebot",
   "section": "access",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": "ClaudeBot",
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt blocks ClaudeBot",
     "why": "Blocks ClaudeBot, which collects training data. This keeps your pages out of future model training, not out of ChatGPT or other AI search.",
     "fix": "Only if you want your pages in future model training: remove the Disallow rule for ClaudeBot. Search inclusion is governed by Claude-SearchBot."
    },
    "fr": {
     "title": "robots.txt bloque ClaudeBot",
     "why": "Bloque ClaudeBot, qui collecte des données d'entraînement. Vos pages restent hors de l'entraînement des futurs modèles, mais pas hors de ChatGPT ni des autres moteurs de recherche IA.",
     "fix": "Seulement si vous voulez vos pages dans l'entraînement des futurs modèles : supprimez la règle Disallow pour ClaudeBot. L'inclusion dans la recherche dépend de Claude-SearchBot."
    },
    "nl": {
     "title": "robots.txt blokkeert ClaudeBot",
     "why": "Blokkeert ClaudeBot, die trainingsdata verzamelt. Zo blijven je pagina's buiten toekomstige modeltraining, maar niet buiten ChatGPT of andere AI-zoekmachines.",
     "fix": "Alleen als je wilt dat je pagina's in toekomstige modeltraining komen: verwijder de Disallow-regel voor ClaudeBot. Opname in zoekresultaten wordt bepaald door Claude-SearchBot."
    },
    "de": {
     "title": "robots.txt blockiert ClaudeBot",
     "why": "Blockiert ClaudeBot, der Trainingsdaten sammelt. Ihre Seiten bleiben so aus künftigem Modelltraining heraus, nicht aber aus ChatGPT oder anderer KI-Suche.",
     "fix": "Nur wenn Ihre Seiten in künftiges Modelltraining einfließen sollen: Entfernen Sie die Disallow-Regel für ClaudeBot. Die Aufnahme in die Suche wird über Claude-SearchBot gesteuert."
    },
    "es": {
     "title": "robots.txt bloquea a ClaudeBot",
     "why": "Bloquea a ClaudeBot, que recopila datos de entrenamiento. Esto mantiene tus páginas fuera del entrenamiento de futuros modelos, no fuera de ChatGPT ni de otras búsquedas con IA.",
     "fix": "Solo si quieres que tus páginas entren en el entrenamiento de futuros modelos: elimina la regla Disallow para ClaudeBot. La inclusión en la búsqueda depende de Claude-SearchBot."
    }
   }
  },
  {
   "check": "robots_ccbot",
   "section": "access",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": "CCBot",
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt blocks CCBot",
     "why": "Blocks CCBot (Common Crawl), which collects training data. This keeps your pages out of future model training, not out of ChatGPT or other AI search.",
     "fix": "Only if you want your pages in open training datasets: remove the Disallow rule for CCBot."
    },
    "fr": {
     "title": "robots.txt bloque CCBot",
     "why": "Bloque CCBot (Common Crawl), qui collecte des données d'entraînement. Vos pages restent hors de l'entraînement des futurs modèles, mais pas hors de ChatGPT ni des autres moteurs de recherche IA.",
     "fix": "Seulement si vous voulez vos pages dans les jeux de données d'entraînement ouverts : supprimez la règle Disallow pour CCBot."
    },
    "nl": {
     "title": "robots.txt blokkeert CCBot",
     "why": "Blokkeert CCBot (Common Crawl), die trainingsdata verzamelt. Zo blijven je pagina's buiten toekomstige modeltraining, maar niet buiten ChatGPT of andere AI-zoekmachines.",
     "fix": "Alleen als je wilt dat je pagina's in open trainingsdatasets komen: verwijder de Disallow-regel voor CCBot."
    },
    "de": {
     "title": "robots.txt blockiert CCBot",
     "why": "Blockiert CCBot (Common Crawl), der Trainingsdaten sammelt. Ihre Seiten bleiben so aus künftigem Modelltraining heraus, nicht aber aus ChatGPT oder anderer KI-Suche.",
     "fix": "Nur wenn Ihre Seiten in offenen Trainingsdatensätzen erscheinen sollen: Entfernen Sie die Disallow-Regel für CCBot."
    },
    "es": {
     "title": "robots.txt bloquea a CCBot",
     "why": "Bloquea a CCBot (Common Crawl), que recopila datos de entrenamiento. Esto mantiene tus páginas fuera del entrenamiento de futuros modelos, no fuera de ChatGPT ni de otras búsquedas con IA.",
     "fix": "Solo si quieres que tus páginas estén en conjuntos de datos de entrenamiento abiertos: elimina la regla Disallow para CCBot."
    }
   }
  },
  {
   "check": "robots_perplexitybot",
   "section": "access",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": "PerplexityBot",
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt blocks PerplexityBot",
     "why": "PerplexityBot builds Perplexity's index. Blocked, you are not cited there.",
     "fix": "Remove the Disallow rule for PerplexityBot in robots.txt."
    },
    "fr": {
     "title": "robots.txt bloque PerplexityBot",
     "why": "PerplexityBot construit l'index de Perplexity. S'il est bloqué, vous n'y êtes pas cité.",
     "fix": "Supprimez la règle Disallow pour PerplexityBot dans robots.txt."
    },
    "nl": {
     "title": "robots.txt blokkeert PerplexityBot",
     "why": "PerplexityBot bouwt de index van Perplexity op. Als je die blokkeert, word je daar niet geciteerd.",
     "fix": "Verwijder de Disallow-regel voor PerplexityBot in robots.txt."
    },
    "de": {
     "title": "robots.txt blockiert PerplexityBot",
     "why": "PerplexityBot baut den Index von Perplexity auf. Ist er blockiert, werden Sie dort nicht zitiert.",
     "fix": "Entfernen Sie die Disallow-Regel für PerplexityBot in der robots.txt."
    },
    "es": {
     "title": "robots.txt bloquea a PerplexityBot",
     "why": "PerplexityBot construye el índice de Perplexity. Si lo bloqueas, no te citan allí.",
     "fix": "Elimina la regla Disallow para PerplexityBot en robots.txt."
    }
   }
  },
  {
   "check": "robots_oai_searchbot",
   "section": "access",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": "OAI-SearchBot",
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt blocks OAI-SearchBot",
     "why": "OAI-SearchBot decides whether ChatGPT search can show your site.",
     "fix": "Remove the Disallow rule for OAI-SearchBot in robots.txt."
    },
    "fr": {
     "title": "robots.txt bloque OAI-SearchBot",
     "why": "OAI-SearchBot détermine si la recherche ChatGPT peut afficher votre site.",
     "fix": "Supprimez la règle Disallow pour OAI-SearchBot dans robots.txt."
    },
    "nl": {
     "title": "robots.txt blokkeert OAI-SearchBot",
     "why": "OAI-SearchBot bepaalt of ChatGPT-zoeken je site kan tonen.",
     "fix": "Verwijder de Disallow-regel voor OAI-SearchBot in robots.txt."
    },
    "de": {
     "title": "robots.txt blockiert OAI-SearchBot",
     "why": "OAI-SearchBot entscheidet, ob die ChatGPT-Suche Ihre Website anzeigen darf.",
     "fix": "Entfernen Sie die Disallow-Regel für OAI-SearchBot in der robots.txt."
    },
    "es": {
     "title": "robots.txt bloquea a OAI-SearchBot",
     "why": "OAI-SearchBot decide si la búsqueda de ChatGPT puede mostrar tu sitio.",
     "fix": "Elimina la regla Disallow para OAI-SearchBot en robots.txt."
    }
   }
  },
  {
   "check": "robots_chatgpt_user",
   "section": "access",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": "ChatGPT-User",
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt blocks ChatGPT-User",
     "why": "ChatGPT-User fetches a page when a person asks ChatGPT about it. Blocked, ChatGPT cannot open your pages on request.",
     "fix": "Remove the Disallow rule for ChatGPT-User in robots.txt."
    },
    "fr": {
     "title": "robots.txt bloque ChatGPT-User",
     "why": "ChatGPT-User récupère une page lorsqu'une personne interroge ChatGPT à son sujet. S'il est bloqué, ChatGPT ne peut pas ouvrir vos pages à la demande.",
     "fix": "Supprimez la règle Disallow pour ChatGPT-User dans robots.txt."
    },
    "nl": {
     "title": "robots.txt blokkeert ChatGPT-User",
     "why": "ChatGPT-User haalt een pagina op wanneer iemand ChatGPT erover vraagt. Als je die blokkeert, kan ChatGPT je pagina's niet openen op verzoek.",
     "fix": "Verwijder de Disallow-regel voor ChatGPT-User in robots.txt."
    },
    "de": {
     "title": "robots.txt blockiert ChatGPT-User",
     "why": "ChatGPT-User ruft eine Seite ab, wenn jemand ChatGPT danach fragt. Ist er blockiert, kann ChatGPT Ihre Seiten auf Anfrage nicht öffnen.",
     "fix": "Entfernen Sie die Disallow-Regel für ChatGPT-User in der robots.txt."
    },
    "es": {
     "title": "robots.txt bloquea a ChatGPT-User",
     "why": "ChatGPT-User obtiene una página cuando una persona le pregunta a ChatGPT por ella. Si lo bloqueas, ChatGPT no puede abrir tus páginas a petición.",
     "fix": "Elimina la regla Disallow para ChatGPT-User en robots.txt."
    }
   }
  },
  {
   "check": "robots_perplexity_user",
   "section": "access",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": "Perplexity-User",
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt blocks Perplexity-User",
     "why": "Perplexity-User fetches a page when a person asks Perplexity about it.",
     "fix": "Remove the Disallow rule for Perplexity-User in robots.txt."
    },
    "fr": {
     "title": "robots.txt bloque Perplexity-User",
     "why": "Perplexity-User récupère une page lorsqu'une personne interroge Perplexity à son sujet.",
     "fix": "Supprimez la règle Disallow pour Perplexity-User dans robots.txt."
    },
    "nl": {
     "title": "robots.txt blokkeert Perplexity-User",
     "why": "Perplexity-User haalt een pagina op wanneer iemand Perplexity erover vraagt.",
     "fix": "Verwijder de Disallow-regel voor Perplexity-User in robots.txt."
    },
    "de": {
     "title": "robots.txt blockiert Perplexity-User",
     "why": "Perplexity-User ruft eine Seite ab, wenn jemand Perplexity danach fragt.",
     "fix": "Entfernen Sie die Disallow-Regel für Perplexity-User in der robots.txt."
    },
    "es": {
     "title": "robots.txt bloquea a Perplexity-User",
     "why": "Perplexity-User obtiene una página cuando una persona le pregunta a Perplexity por ella.",
     "fix": "Elimina la regla Disallow para Perplexity-User en robots.txt."
    }
   }
  },
  {
   "check": "robots_claude_searchbot",
   "section": "access",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": "Claude-SearchBot",
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt blocks Claude-SearchBot",
     "why": "Claude-SearchBot is the search crawler of one of the big AI assistants.",
     "fix": "Remove the Disallow rule for Claude-SearchBot in robots.txt."
    },
    "fr": {
     "title": "robots.txt bloque Claude-SearchBot",
     "why": "Claude-SearchBot est le robot de recherche de l'un des grands assistants IA.",
     "fix": "Supprimez la règle Disallow pour Claude-SearchBot dans robots.txt."
    },
    "nl": {
     "title": "robots.txt blokkeert Claude-SearchBot",
     "why": "Claude-SearchBot is de zoekcrawler van een van de grote AI-assistenten.",
     "fix": "Verwijder de Disallow-regel voor Claude-SearchBot in robots.txt."
    },
    "de": {
     "title": "robots.txt blockiert Claude-SearchBot",
     "why": "Claude-SearchBot ist der Such-Crawler eines der großen KI-Assistenten.",
     "fix": "Entfernen Sie die Disallow-Regel für Claude-SearchBot in der robots.txt."
    },
    "es": {
     "title": "robots.txt bloquea a Claude-SearchBot",
     "why": "Claude-SearchBot es el crawler de búsqueda de uno de los grandes asistentes de IA.",
     "fix": "Elimina la regla Disallow para Claude-SearchBot en robots.txt."
    }
   }
  },
  {
   "check": "robots_claude_user",
   "section": "access",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": "Claude-User",
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt blocks Claude-User",
     "why": "Claude-User fetches a page when a person asks that assistant about it.",
     "fix": "Remove the Disallow rule for Claude-User in robots.txt."
    },
    "fr": {
     "title": "robots.txt bloque Claude-User",
     "why": "Claude-User récupère une page lorsqu'une personne interroge cet assistant à son sujet.",
     "fix": "Supprimez la règle Disallow pour Claude-User dans robots.txt."
    },
    "nl": {
     "title": "robots.txt blokkeert Claude-User",
     "why": "Claude-User haalt een pagina op wanneer iemand die assistent erover vraagt.",
     "fix": "Verwijder de Disallow-regel voor Claude-User in robots.txt."
    },
    "de": {
     "title": "robots.txt blockiert Claude-User",
     "why": "Claude-User ruft eine Seite ab, wenn jemand diesen Assistenten danach fragt.",
     "fix": "Entfernen Sie die Disallow-Regel für Claude-User in der robots.txt."
    },
    "es": {
     "title": "robots.txt bloquea a Claude-User",
     "why": "Claude-User obtiene una página cuando una persona le pregunta a ese asistente por ella.",
     "fix": "Elimina la regla Disallow para Claude-User en robots.txt."
    }
   }
  },
  {
   "check": "robots_google_extended",
   "section": "access",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": "Google-Extended",
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt blocks Google-Extended",
     "why": "Google-Extended controls whether Google uses your content for Gemini training and grounding. Blocking it is a choice; it does not affect Google Search.",
     "fix": "Allow Google-Extended if you want your content used by Gemini."
    },
    "fr": {
     "title": "robots.txt bloque Google-Extended",
     "why": "Google-Extended détermine si Google utilise votre contenu pour l'entraînement et l'ancrage de Gemini. Le bloquer est un choix ; cela n'affecte pas Google Search.",
     "fix": "Autorisez Google-Extended si vous voulez que Gemini utilise votre contenu."
    },
    "nl": {
     "title": "robots.txt blokkeert Google-Extended",
     "why": "Google-Extended bepaalt of Google je content gebruikt voor training en grounding van Gemini. Blokkeren is een keuze; het heeft geen invloed op Google Search.",
     "fix": "Sta Google-Extended toe als je wilt dat Gemini je content gebruikt."
    },
    "de": {
     "title": "robots.txt blockiert Google-Extended",
     "why": "Google-Extended steuert, ob Google Ihre Inhalte für Training und Grounding von Gemini nutzt. Das Blockieren ist eine Entscheidung und wirkt sich nicht auf die Google-Suche aus.",
     "fix": "Erlauben Sie Google-Extended, wenn Gemini Ihre Inhalte nutzen soll."
    },
    "es": {
     "title": "robots.txt bloquea a Google-Extended",
     "why": "Google-Extended controla si Google usa tu contenido para el entrenamiento y el grounding de Gemini. Bloquearlo es una decisión tuya; no afecta a la Búsqueda de Google.",
     "fix": "Permite Google-Extended si quieres que Gemini use tu contenido."
    }
   }
  },
  {
   "check": "waf_blocks_bots",
   "section": "access",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Your firewall or CDN refuses AI search crawlers",
     "why": "Our test request with an AI search crawler's user agent was refused (403, 429, challenge page or timeout) while a browser got the page. Real crawlers may still get through if your CDN verifies them by IP, so check your CDN logs.",
     "fix": "In Cloudflare, Akamai, Sucuri or your host's WAF, allow the verified AI search crawlers (OAI-SearchBot, PerplexityBot, Claude-SearchBot) or turn off 'Block AI bots'."
    },
    "fr": {
     "title": "Votre pare-feu ou CDN refuse les robots de recherche IA",
     "why": "Notre requête de test avec le user agent d'un robot de recherche IA a été refusée (403, 429, page de vérification ou délai dépassé) alors qu'un navigateur obtenait la page. Les vrais robots peuvent encore passer si votre CDN les vérifie par IP : consultez les journaux de votre CDN.",
     "fix": "Dans Cloudflare, Akamai, Sucuri ou le WAF de votre hébergeur, autorisez les robots de recherche IA vérifiés (OAI-SearchBot, PerplexityBot, Claude-SearchBot) ou désactivez « Block AI bots »."
    },
    "nl": {
     "title": "Je firewall of CDN weigert AI-zoekcrawlers",
     "why": "Ons testverzoek met de user agent van een AI-zoekcrawler is geweigerd (403, 429, challenge-pagina of timeout), terwijl een browser de pagina wel kreeg. Echte crawlers komen er misschien toch door als je CDN ze via IP verifieert, dus controleer de logs van je CDN.",
     "fix": "Sta in Cloudflare, Akamai, Sucuri of de WAF van je host de geverifieerde AI-zoekcrawlers toe (OAI-SearchBot, PerplexityBot, Claude-SearchBot) of schakel 'Block AI bots' uit."
    },
    "de": {
     "title": "Ihre Firewall oder Ihr CDN weist KI-Such-Crawler ab",
     "why": "Unsere Testanfrage mit dem User-Agent eines KI-Such-Crawlers wurde abgewiesen (403, 429, Challenge-Seite oder Timeout), während ein Browser die Seite erhielt. Echte Crawler kommen eventuell trotzdem durch, wenn Ihr CDN sie per IP verifiziert. Prüfen Sie daher die Logs Ihres CDN.",
     "fix": "Erlauben Sie in Cloudflare, Akamai, Sucuri oder der WAF Ihres Hosters die verifizierten KI-Such-Crawler (OAI-SearchBot, PerplexityBot, Claude-SearchBot) oder deaktivieren Sie 'Block AI bots'."
    },
    "es": {
     "title": "Tu cortafuegos o CDN rechaza a los crawlers de búsqueda con IA",
     "why": "Nuestra petición de prueba con el user agent de un crawler de búsqueda con IA fue rechazada (403, 429, página de verificación o timeout), mientras que un navegador obtuvo la página. Los crawlers reales aún pueden pasar si tu CDN los verifica por IP, así que revisa los logs de tu CDN.",
     "fix": "En Cloudflare, Akamai, Sucuri o el WAF de tu hosting, permite los crawlers de búsqueda con IA verificados (OAI-SearchBot, PerplexityBot, Claude-SearchBot) o desactiva 'Block AI bots'."
    }
   }
  },
  {
   "check": "waf_blocks_training_bots",
   "section": "access",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Your firewall or CDN refuses AI training crawlers",
     "why": "Our test request with a training crawler's user agent (GPTBot, ClaudeBot) was refused while a browser got the page. This keeps pages out of model training, not out of AI search.",
     "fix": "Allow the verified crawler in your WAF only if you want your pages in model training."
    },
    "fr": {
     "title": "Votre pare-feu ou CDN refuse les robots d'entraînement IA",
     "why": "Notre requête de test avec le user agent d'un robot d'entraînement (GPTBot, ClaudeBot) a été refusée alors qu'un navigateur obtenait la page. Vos pages restent hors de l'entraînement des modèles, mais pas hors de la recherche IA.",
     "fix": "Autorisez le robot vérifié dans votre WAF uniquement si vous voulez vos pages dans l'entraînement des modèles."
    },
    "nl": {
     "title": "Je firewall of CDN weigert AI-trainingscrawlers",
     "why": "Ons testverzoek met de user agent van een trainingscrawler (GPTBot, ClaudeBot) is geweigerd, terwijl een browser de pagina wel kreeg. Zo blijven pagina's buiten modeltraining, maar niet buiten AI-zoekmachines.",
     "fix": "Sta de geverifieerde crawler alleen in je WAF toe als je wilt dat je pagina's in modeltraining komen."
    },
    "de": {
     "title": "Ihre Firewall oder Ihr CDN weist KI-Training-Crawler ab",
     "why": "Unsere Testanfrage mit dem User-Agent eines Training-Crawlers (GPTBot, ClaudeBot) wurde abgewiesen, während ein Browser die Seite erhielt. Ihre Seiten bleiben so aus dem Modelltraining heraus, nicht aber aus der KI-Suche.",
     "fix": "Erlauben Sie den verifizierten Crawler in Ihrer WAF nur, wenn Ihre Seiten in das Modelltraining einfließen sollen."
    },
    "es": {
     "title": "Tu cortafuegos o CDN rechaza a los crawlers de entrenamiento de IA",
     "why": "Nuestra petición de prueba con el user agent de un crawler de entrenamiento (GPTBot, ClaudeBot) fue rechazada, mientras que un navegador obtuvo la página. Esto mantiene las páginas fuera del entrenamiento de modelos, no fuera de la búsqueda con IA.",
     "fix": "Permite el crawler verificado en tu WAF solo si quieres que tus páginas entren en el entrenamiento de modelos."
    }
   }
  },
  {
   "check": "llms_txt_missing",
   "section": "access",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No llms.txt (optional)",
     "why": "llms.txt is a short map of your site written for AI assistants. No major assistant is confirmed to read it, so treat this as optional.",
     "fix": "Optional: publish /llms.txt. A draft built from your pages is in the fix box."
    },
    "fr": {
     "title": "Pas de llms.txt (facultatif)",
     "why": "llms.txt est un plan succinct de votre site écrit pour les assistants IA. Aucun grand assistant n'est confirmé comme le lisant : considérez-le comme facultatif.",
     "fix": "Facultatif : publiez /llms.txt. Un brouillon construit à partir de vos pages se trouve dans l'encadré de correction."
    },
    "nl": {
     "title": "Geen llms.txt (optioneel)",
     "why": "llms.txt is een korte plattegrond van je site, geschreven voor AI-assistenten. Er is geen grote assistent waarvan bevestigd is dat die het bestand leest, dus zie dit als optioneel.",
     "fix": "Optioneel: publiceer /llms.txt. Een concept op basis van je pagina's staat in het fixvak."
    },
    "de": {
     "title": "Keine llms.txt (optional)",
     "why": "Die llms.txt ist eine kurze Übersicht Ihrer Website, geschrieben für KI-Assistenten. Von keinem großen Assistenten ist bestätigt, dass er sie liest. Betrachten Sie sie daher als optional.",
     "fix": "Optional: Veröffentlichen Sie /llms.txt. Ein aus Ihren Seiten erstellter Entwurf liegt im Fix-Feld."
    },
    "es": {
     "title": "Sin llms.txt (opcional)",
     "why": "llms.txt es un mapa breve de tu sitio escrito para asistentes de IA. No se confirma que ningún asistente importante lo lea, así que considéralo opcional.",
     "fix": "Opcional: publica /llms.txt. En el cuadro de solución tienes un borrador creado a partir de tus páginas."
    }
   }
  },
  {
   "check": "llms_full_missing",
   "section": "access",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No llms-full.txt (optional)",
     "why": "llms-full.txt carries your key pages as plain text. No major assistant is confirmed to read it, so treat this as optional.",
     "fix": "Optional: publish /llms-full.txt with the text of your main pages."
    },
    "fr": {
     "title": "Pas de llms-full.txt (facultatif)",
     "why": "llms-full.txt présente vos pages clés en texte brut. Aucun grand assistant n'est confirmé comme le lisant : considérez-le comme facultatif.",
     "fix": "Facultatif : publiez /llms-full.txt avec le texte de vos pages principales."
    },
    "nl": {
     "title": "Geen llms-full.txt (optioneel)",
     "why": "llms-full.txt bevat je belangrijkste pagina's als platte tekst. Er is geen grote assistent waarvan bevestigd is dat die het bestand leest, dus zie dit als optioneel.",
     "fix": "Optioneel: publiceer /llms-full.txt met de tekst van je hoofdpagina's."
    },
    "de": {
     "title": "Keine llms-full.txt (optional)",
     "why": "Die llms-full.txt enthält Ihre wichtigsten Seiten als reinen Text. Von keinem großen Assistenten ist bestätigt, dass er sie liest. Betrachten Sie sie daher als optional.",
     "fix": "Optional: Veröffentlichen Sie /llms-full.txt mit dem Text Ihrer Hauptseiten."
    },
    "es": {
     "title": "Sin llms-full.txt (opcional)",
     "why": "llms-full.txt contiene tus páginas clave como texto plano. No se confirma que ningún asistente importante lo lea, así que considéralo opcional.",
     "fix": "Opcional: publica /llms-full.txt con el texto de tus páginas principales."
    }
   }
  },
  {
   "check": "page_status",
   "section": "access",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Pages return an error status",
     "why": "Pages that answer 4xx or 5xx (or do not answer at all) cannot be read, indexed or cited.",
     "fix": "Fix or redirect the page; remove links that point to it."
    },
    "fr": {
     "title": "Des pages renvoient un statut d'erreur",
     "why": "Les pages qui répondent 4xx ou 5xx (ou ne répondent pas du tout) ne peuvent être ni lues, ni indexées, ni citées.",
     "fix": "Corrigez la page ou redirigez-la ; supprimez les liens qui y mènent."
    },
    "nl": {
     "title": "Pagina's geven een foutstatus terug",
     "why": "Pagina's die 4xx of 5xx geven (of helemaal niet antwoorden) kunnen niet worden gelezen, geïndexeerd of geciteerd.",
     "fix": "Herstel de pagina of stuur door met een redirect; verwijder links naar de pagina."
    },
    "de": {
     "title": "Seiten liefern einen Fehlerstatus",
     "why": "Seiten, die mit 4xx oder 5xx antworten (oder gar nicht), können nicht gelesen, indexiert oder zitiert werden.",
     "fix": "Beheben Sie die Seite oder leiten Sie sie weiter. Entfernen Sie Links, die auf sie zeigen."
    },
    "es": {
     "title": "Páginas con estado de error",
     "why": "Las páginas que responden 4xx o 5xx (o que no responden) no se pueden leer, indexar ni citar.",
     "fix": "Corrige la página o redirígela; elimina los enlaces que apuntan a ella."
    }
   }
  },
  {
   "check": "https",
   "section": "access",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Site is not served over HTTPS",
     "why": "Crawlers and browsers distrust plain HTTP; some assistants skip it.",
     "fix": "Install a certificate and redirect all HTTP to HTTPS."
    },
    "fr": {
     "title": "Le site n'est pas servi en HTTPS",
     "why": "Les robots et les navigateurs se méfient du HTTP simple ; certains assistants l'ignorent.",
     "fix": "Installez un certificat et redirigez tout le HTTP vers HTTPS."
    },
    "nl": {
     "title": "Site wordt niet via HTTPS aangeboden",
     "why": "Crawlers en browsers wantrouwen gewoon HTTP; sommige assistenten slaan het over.",
     "fix": "Installeer een certificaat en stuur al het HTTP-verkeer door naar HTTPS."
    },
    "de": {
     "title": "Website wird nicht über HTTPS ausgeliefert",
     "why": "Crawler und Browser misstrauen reinem HTTP, manche Assistenten überspringen es.",
     "fix": "Installieren Sie ein Zertifikat und leiten Sie jeden HTTP-Aufruf auf HTTPS weiter."
    },
    "es": {
     "title": "El sitio no se sirve por HTTPS",
     "why": "Los crawlers y los navegadores desconfían del HTTP sin cifrar; algunos asistentes lo omiten.",
     "fix": "Instala un certificado y redirige todo el HTTP a HTTPS."
    }
   }
  },
  {
   "check": "js_empty",
   "section": "render",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Page is empty without JavaScript",
     "why": "AI crawlers do not run JavaScript. The server HTML has almost no text, so the crawler sees an empty page.",
     "fix": "Server-render or pre-render the page (SSR/SSG), or put the key text in the HTML."
    },
    "fr": {
     "title": "La page est vide sans JavaScript",
     "why": "Les robots IA n'exécutent pas JavaScript. Le HTML du serveur contient presque aucun texte : le robot voit une page vide.",
     "fix": "Générez la page côté serveur ou en pré-rendu (SSR/SSG), ou placez le texte clé dans le HTML."
    },
    "nl": {
     "title": "Pagina is leeg zonder JavaScript",
     "why": "AI-crawlers voeren geen JavaScript uit. De HTML van de server bevat bijna geen tekst, dus de crawler ziet een lege pagina.",
     "fix": "Render de pagina op de server of vooraf (SSR/SSG), of zet de belangrijkste tekst in de HTML."
    },
    "de": {
     "title": "Seite ist ohne JavaScript leer",
     "why": "KI-Crawler führen kein JavaScript aus. Das Server-HTML enthält fast keinen Text, der Crawler sieht also eine leere Seite.",
     "fix": "Rendern Sie die Seite serverseitig oder vorab (SSR/SSG) oder legen Sie den wichtigen Text ins HTML."
    },
    "es": {
     "title": "La página está vacía sin JavaScript",
     "why": "Los crawlers de IA no ejecutan JavaScript. El HTML del servidor casi no tiene texto, así que el crawler ve una página vacía.",
     "fix": "Renderiza la página en el servidor o prerenderízala (SSR/SSG), o pon el texto clave en el HTML."
    }
   }
  },
  {
   "check": "thin_content",
   "section": "render",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Thin content",
     "why": "Under 100 words of main text: nothing for an assistant to quote.",
     "fix": "Add a clear answer: who it is for, what it is, price, how it works."
    },
    "fr": {
     "title": "Contenu pauvre",
     "why": "Moins de 100 mots de texte principal : rien à citer pour un assistant.",
     "fix": "Ajoutez une réponse claire : à qui cela s'adresse, de quoi il s'agit, le prix, le fonctionnement."
    },
    "nl": {
     "title": "Dunne content",
     "why": "Minder dan 100 woorden hoofdtekst: er valt niets te citeren voor een assistent.",
     "fix": "Voeg een helder antwoord toe: voor wie het is, wat het is, prijs, hoe het werkt."
    },
    "de": {
     "title": "Dünner Inhalt",
     "why": "Weniger als 100 Wörter Haupttext: Ein Assistent hat nichts zum Zitieren.",
     "fix": "Ergänzen Sie eine klare Antwort: für wen es ist, was es ist, Preis, Funktionsweise."
    },
    "es": {
     "title": "Contenido escaso",
     "why": "Menos de 100 palabras de texto principal: no hay nada que un asistente pueda citar.",
     "fix": "Añade una respuesta clara: para quién es, qué es, precio y cómo funciona."
    }
   }
  },
  {
   "check": "noindex",
   "section": "render",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Page is set to noindex",
     "why": "noindex tells search engines, and many AI crawlers, to ignore the page.",
     "fix": "Remove noindex (meta robots or X-Robots-Tag) if the page should be found."
    },
    "fr": {
     "title": "La page est en noindex",
     "why": "noindex demande aux moteurs de recherche, et à de nombreux robots IA, d'ignorer la page.",
     "fix": "Supprimez noindex (balise meta robots ou X-Robots-Tag) si la page doit être trouvée."
    },
    "nl": {
     "title": "Pagina staat op noindex",
     "why": "noindex vertelt zoekmachines, en veel AI-crawlers, de pagina te negeren.",
     "fix": "Verwijder noindex (meta robots of X-Robots-Tag) als de pagina gevonden moet worden."
    },
    "de": {
     "title": "Seite ist auf noindex gesetzt",
     "why": "noindex weist Suchmaschinen und viele KI-Crawler an, die Seite zu ignorieren.",
     "fix": "Entfernen Sie noindex (Meta-Robots oder X-Robots-Tag), wenn die Seite gefunden werden soll."
    },
    "es": {
     "title": "La página está marcada como noindex",
     "why": "noindex indica a los buscadores, y a muchos crawlers de IA, que ignoren la página.",
     "fix": "Elimina noindex (meta robots o X-Robots-Tag) si quieres que la página se encuentre."
    }
   }
  },
  {
   "check": "redirect_chain",
   "section": "render",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Long redirect chain",
     "why": "Three or more redirects before the page: crawlers give up or lose the signal.",
     "fix": "Link straight to the final URL; one redirect at most."
    },
    "fr": {
     "title": "Longue chaîne de redirections",
     "why": "Trois redirections ou plus avant la page : les robots abandonnent ou perdent le signal.",
     "fix": "Faites pointer les liens directement vers l'URL finale ; une seule redirection au maximum."
    },
    "nl": {
     "title": "Lange redirectketen",
     "why": "Drie of meer redirects voor je bij de pagina bent: crawlers haken af of verliezen het signaal.",
     "fix": "Link rechtstreeks naar de eind-URL; hooguit één redirect."
    },
    "de": {
     "title": "Lange Weiterleitungskette",
     "why": "Drei oder mehr Weiterleitungen vor der Seite: Crawler geben auf oder verlieren das Signal.",
     "fix": "Verlinken Sie direkt auf die finale URL, höchstens eine Weiterleitung."
    },
    "es": {
     "title": "Cadena de redirecciones larga",
     "why": "Tres o más redirecciones antes de llegar a la página: los crawlers abandonan o pierden la señal.",
     "fix": "Enlaza directamente a la URL final; como máximo una redirección."
    }
   }
  },
  {
   "check": "title_missing",
   "section": "structure",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Missing title",
     "why": "The title is the first thing an assistant reads to decide what the page is.",
     "fix": "Add a unique <title> that says what the page is."
    },
    "fr": {
     "title": "Balise title manquante",
     "why": "Le title est la première chose qu'un assistant lit pour savoir ce qu'est la page.",
     "fix": "Ajoutez un <title> unique qui indique ce qu'est la page."
    },
    "nl": {
     "title": "Title ontbreekt",
     "why": "De title is het eerste wat een assistent leest om te bepalen wat de pagina is.",
     "fix": "Voeg een unieke <title> toe die zegt wat de pagina is."
    },
    "de": {
     "title": "Title-Tag fehlt",
     "why": "Der Title ist das Erste, was ein Assistent liest, um die Seite einzuordnen.",
     "fix": "Fügen Sie einen eindeutigen <title> hinzu, der sagt, worum es auf der Seite geht."
    },
    "es": {
     "title": "Falta la etiqueta title",
     "why": "El title es lo primero que lee un asistente para decidir qué es la página.",
     "fix": "Añade un <title> único que diga qué es la página."
    }
   }
  },
  {
   "check": "title_length",
   "section": "structure",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Title too short or too long",
     "why": "Titles outside 15 to 65 characters are cut off or say too little.",
     "fix": "Reword the title so the whole phrase fits in 15-65 characters, key words first and brand last. Do not cut it off and do not end it with …."
    },
    "fr": {
     "title": "Balise title trop courte ou trop longue",
     "why": "Les titles de moins de 15 ou de plus de 65 caractères sont tronqués ou en disent trop peu.",
     "fix": "Reformulez le title pour que la phrase entière tienne en 15 à 65 caractères, mots-clés en premier et marque en dernier. Ne le coupez pas et ne le terminez pas par « … »."
    },
    "nl": {
     "title": "Title te kort of te lang",
     "why": "Titles buiten 15 tot 65 tekens worden afgekapt of zeggen te weinig.",
     "fix": "Herschrijf de title zodat de hele zin in 15-65 tekens past, belangrijkste woorden eerst en merknaam laatst. Knip hem niet af en eindig niet met …"
    },
    "de": {
     "title": "Title zu kurz oder zu lang",
     "why": "Titel außerhalb von 15 bis 65 Zeichen werden abgeschnitten oder sagen zu wenig.",
     "fix": "Formulieren Sie den Title so um, dass der ganze Satz in 15-65 Zeichen passt, wichtige Begriffe zuerst und die Marke zuletzt. Schneiden Sie ihn nicht ab und enden Sie nicht mit …"
    },
    "es": {
     "title": "Title demasiado corto o demasiado largo",
     "why": "Los title de menos de 15 o más de 65 caracteres se cortan o dicen muy poco.",
     "fix": "Reescribe el title para que la frase entera quepa en 15-65 caracteres, con las palabras clave al principio y la marca al final. No lo cortes ni lo termines con …"
    }
   }
  },
  {
   "check": "title_duplicate",
   "section": "structure",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Duplicate titles",
     "why": "Several pages share one title, so assistants cannot tell them apart.",
     "fix": "Give each page its own title."
    },
    "fr": {
     "title": "Balises title en double",
     "why": "Plusieurs pages partagent un même title : les assistants ne peuvent pas les distinguer.",
     "fix": "Donnez à chaque page son propre title."
    },
    "nl": {
     "title": "Dubbele titles",
     "why": "Meerdere pagina's delen één title, waardoor assistenten ze niet uit elkaar kunnen houden.",
     "fix": "Geef elke pagina een eigen title."
    },
    "de": {
     "title": "Doppelte Titel",
     "why": "Mehrere Seiten teilen sich einen Title, sodass Assistenten sie nicht unterscheiden können.",
     "fix": "Geben Sie jeder Seite einen eigenen Title."
    },
    "es": {
     "title": "Etiquetas title duplicadas",
     "why": "Varias páginas comparten el mismo title, así que los asistentes no pueden distinguirlas.",
     "fix": "Da a cada página su propio title."
    }
   }
  },
  {
   "check": "description_missing",
   "section": "structure",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Missing meta description",
     "why": "The description is the summary an assistant and a search result reuse.",
     "fix": "Add a 70-160 character meta description that answers the page's main question."
    },
    "fr": {
     "title": "Méta description manquante",
     "why": "La description est le résumé que réutilisent un assistant et un résultat de recherche.",
     "fix": "Ajoutez une méta description de 70 à 160 caractères qui répond à la question principale de la page."
    },
    "nl": {
     "title": "Metabeschrijving ontbreekt",
     "why": "De beschrijving is de samenvatting die een assistent en een zoekresultaat hergebruiken.",
     "fix": "Voeg een metabeschrijving van 70-160 tekens toe die de hoofdvraag van de pagina beantwoordt."
    },
    "de": {
     "title": "Meta-Description fehlt",
     "why": "Die Description ist die Zusammenfassung, die ein Assistent und ein Suchergebnis übernehmen.",
     "fix": "Fügen Sie eine Meta-Description mit 70-160 Zeichen hinzu, die die Hauptfrage der Seite beantwortet."
    },
    "es": {
     "title": "Falta la meta descripción",
     "why": "La descripción es el resumen que reutilizan los asistentes y los resultados de búsqueda.",
     "fix": "Añade una meta descripción de 70-160 caracteres que responda a la pregunta principal de la página."
    }
   }
  },
  {
   "check": "description_duplicate",
   "section": "structure",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Duplicate meta descriptions",
     "why": "Pages share one description.",
     "fix": "Write a distinct description per page."
    },
    "fr": {
     "title": "Méta descriptions en double",
     "why": "Des pages partagent une même description.",
     "fix": "Rédigez une description distincte par page."
    },
    "nl": {
     "title": "Dubbele metabeschrijvingen",
     "why": "Pagina's delen één beschrijving.",
     "fix": "Schrijf per pagina een eigen beschrijving."
    },
    "de": {
     "title": "Doppelte Meta-Descriptions",
     "why": "Seiten teilen sich eine Description.",
     "fix": "Schreiben Sie für jede Seite eine eigene Description."
    },
    "es": {
     "title": "Meta descripciones duplicadas",
     "why": "Varias páginas comparten la misma descripción.",
     "fix": "Escribe una descripción distinta para cada página."
    }
   }
  },
  {
   "check": "h1_missing",
   "section": "structure",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Missing H1",
     "why": "The H1 states the page's topic for readers and crawlers.",
     "fix": "Add one H1 that names the page's subject."
    },
    "fr": {
     "title": "H1 manquant",
     "why": "Le H1 énonce le sujet de la page pour les lecteurs et les robots.",
     "fix": "Ajoutez un seul H1 qui nomme le sujet de la page."
    },
    "nl": {
     "title": "H1 ontbreekt",
     "why": "De H1 geeft het onderwerp van de pagina aan voor lezers en crawlers.",
     "fix": "Voeg één H1 toe die het onderwerp van de pagina benoemt."
    },
    "de": {
     "title": "H1 fehlt",
     "why": "Die H1 nennt das Thema der Seite für Leser und Crawler.",
     "fix": "Fügen Sie eine H1 hinzu, die das Thema der Seite benennt."
    },
    "es": {
     "title": "Falta el H1",
     "why": "El H1 indica el tema de la página a lectores y crawlers.",
     "fix": "Añade un único H1 que nombre el tema de la página."
    }
   }
  },
  {
   "check": "h1_multiple",
   "section": "structure",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "More than one H1",
     "why": "Several H1s blur what the page is about.",
     "fix": "Keep one H1; make the others H2."
    },
    "fr": {
     "title": "Plus d'un H1",
     "why": "Plusieurs H1 brouillent le sujet de la page.",
     "fix": "Gardez un seul H1 ; passez les autres en H2."
    },
    "nl": {
     "title": "Meer dan één H1",
     "why": "Meerdere H1's maken onduidelijk waar de pagina over gaat.",
     "fix": "Houd één H1; maak de andere H2."
    },
    "de": {
     "title": "Mehr als eine H1",
     "why": "Mehrere H1 verwischen, worum es auf der Seite geht.",
     "fix": "Behalten Sie eine H1 und machen Sie die anderen zu H2."
    },
    "es": {
     "title": "Más de un H1",
     "why": "Varios H1 desdibujan de qué trata la página.",
     "fix": "Deja un solo H1 y convierte los demás en H2."
    }
   }
  },
  {
   "check": "heading_order",
   "section": "structure",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Headings skip a level",
     "why": "Jumping from H1 to H3 breaks the outline that crawlers use to find answers.",
     "fix": "Use H2 under H1, H3 under H2."
    },
    "fr": {
     "title": "Niveaux de titres sautés",
     "why": "Passer de H1 à H3 casse le plan que les robots utilisent pour trouver des réponses.",
     "fix": "Utilisez H2 sous H1, H3 sous H2."
    },
    "nl": {
     "title": "Koppen slaan een niveau over",
     "why": "Springen van H1 naar H3 doorbreekt de structuur die crawlers gebruiken om antwoorden te vinden.",
     "fix": "Gebruik H2 onder H1, H3 onder H2."
    },
    "de": {
     "title": "Überschriften überspringen eine Ebene",
     "why": "Der Sprung von H1 zu H3 zerstört die Gliederung, mit der Crawler Antworten finden.",
     "fix": "Verwenden Sie H2 unter H1 und H3 unter H2."
    },
    "es": {
     "title": "Los encabezados se saltan un nivel",
     "why": "Pasar de H1 a H3 rompe el esquema que los crawlers usan para encontrar respuestas.",
     "fix": "Usa H2 bajo H1 y H3 bajo H2."
    }
   }
  },
  {
   "check": "schema_missing",
   "section": "structure",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No structured data (schema)",
     "why": "JSON-LD tells assistants exactly what the page is: organisation, product, FAQ, article.",
     "fix": "Add JSON-LD that matches the page."
    },
    "fr": {
     "title": "Pas de données structurées (schema)",
     "why": "JSON-LD indique précisément aux assistants ce qu'est la page : organisation, produit, FAQ, article.",
     "fix": "Ajoutez un JSON-LD adapté à la page."
    },
    "nl": {
     "title": "Geen gestructureerde data (schema)",
     "why": "JSON-LD vertelt assistenten precies wat de pagina is: organisatie, product, FAQ, artikel.",
     "fix": "Voeg JSON-LD toe die bij de pagina past."
    },
    "de": {
     "title": "Keine strukturierten Daten (Schema)",
     "why": "JSON-LD sagt Assistenten genau, was die Seite ist: Organisation, Produkt, FAQ, Artikel.",
     "fix": "Fügen Sie passendes JSON-LD hinzu."
    },
    "es": {
     "title": "Sin datos estructurados (schema)",
     "why": "JSON-LD indica a los asistentes qué es exactamente la página: organización, producto, FAQ, artículo.",
     "fix": "Añade JSON-LD que corresponda a la página."
    }
   }
  },
  {
   "check": "schema_org_missing",
   "section": "structure",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Home page has no Organization schema",
     "why": "Organization/LocalBusiness schema is how assistants confirm who you are, and avoid mixing you up with a namesake.",
     "fix": "Add the Organization JSON-LD from the fix box to the home page."
    },
    "fr": {
     "title": "La page d'accueil n'a pas de schema Organization",
     "why": "Le schema Organization/LocalBusiness permet aux assistants de confirmer qui vous êtes et d'éviter de vous confondre avec un homonyme.",
     "fix": "Ajoutez à la page d'accueil le JSON-LD Organization de l'encadré de correction."
    },
    "nl": {
     "title": "Homepage heeft geen Organization-schema",
     "why": "Met Organization/LocalBusiness-schema bevestigen assistenten wie je bent en voorkomen ze verwarring met een naamgenoot.",
     "fix": "Voeg de Organization JSON-LD uit het fixvak toe aan de homepage."
    },
    "de": {
     "title": "Startseite ohne Organization-Schema",
     "why": "Über Organization-/LocalBusiness-Schema bestätigen Assistenten, wer Sie sind, und verwechseln Sie nicht mit einem Namensvetter.",
     "fix": "Fügen Sie der Startseite das Organization-JSON-LD aus dem Fix-Feld hinzu."
    },
    "es": {
     "title": "La página de inicio no tiene schema Organization",
     "why": "El schema Organization/LocalBusiness es como los asistentes confirman quién eres y evitan confundirte con un homónimo.",
     "fix": "Añade a la página de inicio el JSON-LD de Organization del cuadro de solución."
    }
   }
  },
  {
   "check": "schema_product_missing",
   "section": "structure",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Product page without Product schema",
     "why": "Product schema carries price and availability in a form assistants can quote.",
     "fix": "Add Product JSON-LD with name, description, price and availability."
    },
    "fr": {
     "title": "Page produit sans schema Product",
     "why": "Le schema Product transmet prix et disponibilité sous une forme que les assistants peuvent citer.",
     "fix": "Ajoutez un JSON-LD Product avec nom, description, prix et disponibilité."
    },
    "nl": {
     "title": "Productpagina zonder Product-schema",
     "why": "Product-schema bevat prijs en beschikbaarheid in een vorm die assistenten kunnen citeren.",
     "fix": "Voeg Product JSON-LD toe met naam, beschrijving, prijs en beschikbaarheid."
    },
    "de": {
     "title": "Produktseite ohne Product-Schema",
     "why": "Product-Schema liefert Preis und Verfügbarkeit in einer Form, die Assistenten zitieren können.",
     "fix": "Fügen Sie Product-JSON-LD mit Name, Beschreibung, Preis und Verfügbarkeit hinzu."
    },
    "es": {
     "title": "Página de producto sin schema Product",
     "why": "El schema Product incluye precio y disponibilidad en un formato que los asistentes pueden citar.",
     "fix": "Añade JSON-LD de Product con nombre, descripción, precio y disponibilidad."
    }
   }
  },
  {
   "check": "schema_faq_missing",
   "section": "structure",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Questions and answers without FAQ schema",
     "why": "The page asks and answers questions but does not mark them up. Google now shows FAQ rich results only for well-known government and health sites, so expect no extra search result; the markup still helps assistants read each question with its answer.",
     "fix": "Add FAQPage JSON-LD for the questions on this page."
    },
    "fr": {
     "title": "Questions et réponses sans schema FAQ",
     "why": "La page pose et résout des questions sans les baliser. Google n'affiche désormais les résultats enrichis FAQ que pour des sites officiels et de santé reconnus : n'attendez pas de résultat de recherche supplémentaire ; le balisage aide tout de même les assistants à lire chaque question avec sa réponse.",
     "fix": "Ajoutez un JSON-LD FAQPage pour les questions de cette page."
    },
    "nl": {
     "title": "Vragen en antwoorden zonder FAQ-schema",
     "why": "De pagina stelt en beantwoordt vragen maar markeert ze niet. Google toont FAQ-rijke resultaten nu alleen voor bekende overheids- en gezondheidssites, verwacht dus geen extra zoekresultaat; de markup helpt assistenten wel elke vraag met haar antwoord te lezen.",
     "fix": "Voeg FAQPage JSON-LD toe voor de vragen op deze pagina."
    },
    "de": {
     "title": "Fragen und Antworten ohne FAQ-Schema",
     "why": "Die Seite stellt und beantwortet Fragen, markiert sie aber nicht. Google zeigt FAQ-Rich-Results nur noch für bekannte Behörden- und Gesundheitsseiten, erwarten Sie also kein zusätzliches Suchergebnis; das Markup hilft Assistenten aber, jede Frage mit ihrer Antwort zu lesen.",
     "fix": "Fügen Sie FAQPage-JSON-LD für die Fragen auf dieser Seite hinzu."
    },
    "es": {
     "title": "Preguntas y respuestas sin schema FAQ",
     "why": "La página plantea y responde preguntas pero no las marca. Google solo muestra resultados enriquecidos de FAQ para sitios oficiales y de salud conocidos, así que no esperes un resultado de búsqueda extra; el marcado sí ayuda a los asistentes a leer cada pregunta con su respuesta.",
     "fix": "Añade JSON-LD de FAQPage para las preguntas de esta página."
    }
   }
  },
  {
   "check": "schema_article_missing",
   "section": "structure",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Article without Article schema",
     "why": "Article schema gives author and date, which assistants weigh when citing.",
     "fix": "Add Article or BlogPosting JSON-LD with headline, author and datePublished."
    },
    "fr": {
     "title": "Article sans schema Article",
     "why": "Le schema Article fournit l'auteur et la date, que les assistants prennent en compte pour citer.",
     "fix": "Ajoutez un JSON-LD Article ou BlogPosting avec headline, author et datePublished."
    },
    "nl": {
     "title": "Artikel zonder Article-schema",
     "why": "Article-schema geeft auteur en datum, die assistenten meewegen bij het citeren.",
     "fix": "Voeg Article- of BlogPosting-JSON-LD toe met headline, author en datePublished."
    },
    "de": {
     "title": "Artikel ohne Article-Schema",
     "why": "Article-Schema liefert Autor und Datum, die Assistenten beim Zitieren gewichten.",
     "fix": "Fügen Sie Article- oder BlogPosting-JSON-LD mit headline, author und datePublished hinzu."
    },
    "es": {
     "title": "Artículo sin schema Article",
     "why": "El schema Article aporta autor y fecha, que los asistentes valoran al citar.",
     "fix": "Añade JSON-LD de Article o BlogPosting con headline, author y datePublished."
    }
   }
  },
  {
   "check": "og_missing",
   "section": "structure",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No Open Graph tags",
     "why": "Open Graph tags control how the page appears when shared and are read by some assistants.",
     "fix": "Add og:title, og:description and og:image."
    },
    "fr": {
     "title": "Pas de balises Open Graph",
     "why": "Les balises Open Graph contrôlent l'aspect de la page lors d'un partage et sont lues par certains assistants.",
     "fix": "Ajoutez og:title, og:description et og:image."
    },
    "nl": {
     "title": "Geen Open Graph-tags",
     "why": "Open Graph-tags bepalen hoe de pagina eruitziet als je hem deelt en worden door sommige assistenten gelezen.",
     "fix": "Voeg og:title, og:description en og:image toe."
    },
    "de": {
     "title": "Keine Open-Graph-Tags",
     "why": "Open-Graph-Tags steuern, wie die Seite beim Teilen erscheint, und werden von einigen Assistenten gelesen.",
     "fix": "Fügen Sie og:title, og:description und og:image hinzu."
    },
    "es": {
     "title": "Sin etiquetas Open Graph",
     "why": "Las etiquetas Open Graph controlan cómo se ve la página al compartirla, y algunos asistentes las leen.",
     "fix": "Añade og:title, og:description y og:image."
    }
   }
  },
  {
   "check": "canonical_missing",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No canonical URL",
     "why": "Without a canonical, duplicates of this page can compete with each other.",
     "fix": "Add <link rel=\"canonical\"> pointing at the page's preferred URL."
    },
    "fr": {
     "title": "Pas d'URL canonique",
     "why": "Sans canonical, les doublons de cette page peuvent se concurrencer.",
     "fix": "Ajoutez <link rel=\"canonical\"> pointant vers l'URL préférée de la page."
    },
    "nl": {
     "title": "Geen canonical-URL",
     "why": "Zonder canonical kunnen duplicaten van deze pagina met elkaar concurreren.",
     "fix": "Voeg <link rel=\"canonical\"> toe die naar de voorkeurs-URL van de pagina verwijst."
    },
    "de": {
     "title": "Keine Canonical-URL",
     "why": "Ohne Canonical können Duplikate dieser Seite miteinander konkurrieren.",
     "fix": "Fügen Sie <link rel=\"canonical\"> hinzu, das auf die bevorzugte URL der Seite zeigt."
    },
    "es": {
     "title": "Sin URL canonical",
     "why": "Sin canonical, los duplicados de esta página pueden competir entre sí.",
     "fix": "Añade <link rel=\"canonical\"> apuntando a la URL preferida de la página."
    }
   }
  },
  {
   "check": "canonical_other",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Canonical points to another page",
     "why": "This page tells crawlers a different URL is the real one, so this one is ignored.",
     "fix": "Make the canonical point to the page itself unless this is a deliberate duplicate."
    },
    "fr": {
     "title": "La canonical pointe vers une autre page",
     "why": "Cette page indique aux robots qu'une autre URL est la bonne : celle-ci est donc ignorée.",
     "fix": "Faites pointer la canonical vers la page elle-même, sauf s'il s'agit d'un doublon volontaire."
    },
    "nl": {
     "title": "Canonical verwijst naar een andere pagina",
     "why": "Deze pagina vertelt crawlers dat een andere URL de echte is, dus deze wordt genegeerd.",
     "fix": "Laat de canonical naar de pagina zelf verwijzen, tenzij dit bewust een duplicaat is."
    },
    "de": {
     "title": "Canonical zeigt auf eine andere Seite",
     "why": "Diese Seite teilt Crawlern mit, dass eine andere URL die maßgebliche ist, daher wird diese ignoriert.",
     "fix": "Lassen Sie das Canonical auf die Seite selbst zeigen, außer es handelt sich um ein gewolltes Duplikat."
    },
    "es": {
     "title": "El canonical apunta a otra página",
     "why": "Esta página indica a los crawlers que la URL real es otra, así que esta se ignora.",
     "fix": "Haz que el canonical apunte a la propia página, salvo que sea un duplicado deliberado."
    }
   }
  },
  {
   "check": "hreflang_invalid",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Invalid hreflang",
     "why": "Language alternates that are malformed or not reciprocal are ignored.",
     "fix": "Use valid codes (en, fr-BE, x-default) with absolute URLs."
    },
    "fr": {
     "title": "hreflang invalide",
     "why": "Les alternatives de langue mal formées ou non réciproques sont ignorées.",
     "fix": "Utilisez des codes valides (en, fr-BE, x-default) avec des URL absolues."
    },
    "nl": {
     "title": "Ongeldige hreflang",
     "why": "Taalalternatieven die verkeerd zijn opgemaakt of niet wederkerig zijn, worden genegeerd.",
     "fix": "Gebruik geldige codes (en, fr-BE, x-default) met absolute URL's."
    },
    "de": {
     "title": "Ungültiges hreflang",
     "why": "Sprachalternativen, die fehlerhaft oder nicht wechselseitig sind, werden ignoriert.",
     "fix": "Verwenden Sie gültige Codes (en, fr-BE, x-default) mit absoluten URLs."
    },
    "es": {
     "title": "hreflang no válido",
     "why": "Las alternativas de idioma mal formadas o no recíprocas se ignoran.",
     "fix": "Usa códigos válidos (en, fr-BE, x-default) con URL absolutas."
    }
   }
  },
  {
   "check": "broken_internal_link",
   "section": "technical",
   "severity": "error",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Broken internal links",
     "why": "Pages link to URLs that return 4xx or 5xx.",
     "fix": "Update or remove the link."
    },
    "fr": {
     "title": "Liens internes cassés",
     "why": "Des pages renvoient vers des URL qui répondent 4xx ou 5xx.",
     "fix": "Mettez le lien à jour ou supprimez-le."
    },
    "nl": {
     "title": "Kapotte interne links",
     "why": "Pagina's linken naar URL's die 4xx of 5xx teruggeven.",
     "fix": "Pas de link aan of verwijder hem."
    },
    "de": {
     "title": "Defekte interne Links",
     "why": "Seiten verlinken auf URLs, die 4xx oder 5xx liefern.",
     "fix": "Aktualisieren oder entfernen Sie den Link."
    },
    "es": {
     "title": "Enlaces internos rotos",
     "why": "Hay páginas que enlazan a URL que devuelven 4xx o 5xx.",
     "fix": "Actualiza o elimina el enlace."
    }
   }
  },
  {
   "check": "orphan_page",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Orphan pages",
     "why": "Listed in the sitemap but no page links to them, so crawlers rarely find them.",
     "fix": "Link to the page from a relevant page or the navigation."
    },
    "fr": {
     "title": "Pages orphelines",
     "why": "Présentes dans le sitemap mais sans aucun lien depuis une autre page : les robots les trouvent rarement.",
     "fix": "Ajoutez un lien vers la page depuis une page pertinente ou la navigation."
    },
    "nl": {
     "title": "Wezenpagina's",
     "why": "Staan in de sitemap, maar geen enkele pagina linkt ernaar, dus crawlers vinden ze zelden.",
     "fix": "Link naar de pagina vanaf een relevante pagina of vanuit het menu."
    },
    "de": {
     "title": "Verwaiste Seiten",
     "why": "In der Sitemap aufgeführt, aber keine Seite verlinkt sie, daher finden Crawler sie selten.",
     "fix": "Verlinken Sie die Seite von einer passenden Seite oder aus der Navigation."
    },
    "es": {
     "title": "Páginas huérfanas",
     "why": "Aparecen en el sitemap, pero ninguna página enlaza a ellas, así que los crawlers rara vez las encuentran.",
     "fix": "Enlaza la página desde una página relevante o desde el menú de navegación."
    }
   }
  },
  {
   "check": "sitemap_missing",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No sitemap.xml",
     "why": "A sitemap lists every page you want crawled.",
     "fix": "Publish /sitemap.xml and add a Sitemap: line to robots.txt."
    },
    "fr": {
     "title": "Pas de sitemap.xml",
     "why": "Un sitemap liste toutes les pages que vous voulez faire explorer.",
     "fix": "Publiez /sitemap.xml et ajoutez une ligne Sitemap: dans robots.txt."
    },
    "nl": {
     "title": "Geen sitemap.xml",
     "why": "Een sitemap toont alle pagina's die je gecrawld wilt hebben.",
     "fix": "Publiceer /sitemap.xml en voeg een Sitemap:-regel toe aan robots.txt."
    },
    "de": {
     "title": "Keine sitemap.xml",
     "why": "Eine Sitemap listet jede Seite auf, die gecrawlt werden soll.",
     "fix": "Veröffentlichen Sie /sitemap.xml und fügen Sie der robots.txt eine Zeile Sitemap: hinzu."
    },
    "es": {
     "title": "Sin sitemap.xml",
     "why": "Un sitemap enumera todas las páginas que quieres que se rastreen.",
     "fix": "Publica /sitemap.xml y añade una línea Sitemap: a robots.txt."
    }
   }
  },
  {
   "check": "sitemap_entries_invalid",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Sitemap has invalid entries",
     "why": "Sitemap entries that are not full addresses on your own site are ignored by crawlers, so those pages are not announced.",
     "fix": "Remove the entry or write it as a full https:// address on your own domain."
    },
    "fr": {
     "title": "Le sitemap contient des entrées invalides",
     "why": "Les entrées du sitemap qui ne sont pas des adresses complètes de votre site sont ignorées par les robots : ces pages ne sont pas annoncées.",
     "fix": "Supprimez l'entrée ou écrivez-la comme une adresse complète https:// sur votre propre domaine."
    },
    "nl": {
     "title": "Sitemap bevat ongeldige items",
     "why": "Sitemap-items die geen volledig adres op je eigen site zijn, worden door crawlers genegeerd, dus die pagina's worden niet aangekondigd.",
     "fix": "Verwijder het item of schrijf het als een volledig https://-adres op je eigen domein."
    },
    "de": {
     "title": "Sitemap enthält ungültige Einträge",
     "why": "Sitemap-Einträge, die keine vollständigen Adressen Ihrer eigenen Website sind, werden von Crawlern ignoriert; diese Seiten werden nicht gemeldet.",
     "fix": "Entfernen Sie den Eintrag oder schreiben Sie ihn als vollständige https://-Adresse auf Ihrer eigenen Domain."
    },
    "es": {
     "title": "El sitemap tiene entradas no válidas",
     "why": "Los rastreadores ignoran las entradas del sitemap que no son direcciones completas de tu propio sitio, así que esas páginas no se anuncian.",
     "fix": "Elimina la entrada o escríbela como una dirección completa https:// en tu propio dominio."
    }
   }
  },
  {
   "check": "schema_org_links",
   "section": "structure",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Organization schema has broken links",
     "why": "The Organization markup names a web address, logo or profile that does not load, so assistants cannot confirm who you are.",
     "fix": "Correct or remove the broken address in the Organization JSON-LD on the home page."
    },
    "fr": {
     "title": "Le schéma Organization contient des liens cassés",
     "why": "Le balisage Organization cite une adresse web, un logo ou un profil qui ne se charge pas : les assistants ne peuvent pas confirmer qui vous êtes.",
     "fix": "Corrigez ou supprimez l'adresse cassée dans le JSON-LD Organization de la page d'accueil."
    },
    "nl": {
     "title": "Organization-schema bevat verbroken links",
     "why": "De Organization-markup noemt een webadres, logo of profiel dat niet laadt, dus assistenten kunnen niet bevestigen wie je bent.",
     "fix": "Corrigeer of verwijder het kapotte adres in de Organization-JSON-LD op de startpagina."
    },
    "de": {
     "title": "Organization-Schema enthält defekte Links",
     "why": "Das Organization-Markup nennt eine Webadresse, ein Logo oder ein Profil, die nicht laden; Assistenten können so nicht bestätigen, wer Sie sind.",
     "fix": "Korrigieren oder entfernen Sie die defekte Adresse im Organization-JSON-LD der Startseite."
    },
    "es": {
     "title": "El esquema Organization tiene enlaces rotos",
     "why": "El marcado Organization nombra una dirección web, un logo o un perfil que no carga, así que los asistentes no pueden confirmar quién eres.",
     "fix": "Corrige o elimina la dirección rota en el JSON-LD Organization de la página de inicio."
    }
   }
  },
  {
   "check": "sitemap_not_in_robots",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "robots.txt does not name your sitemap",
     "why": "Google, Bing and AI crawlers read the Sitemap: line in robots.txt first. Without it your sitemap is found only if a crawler guesses /sitemap.xml.",
     "fix": "Add one Sitemap: line to robots.txt."
    },
    "fr": {
     "title": "robots.txt ne nomme pas votre sitemap",
     "why": "Google, Bing et les robots d'IA lisent d'abord la ligne Sitemap: de robots.txt. Sans elle, votre sitemap n'est trouvé que si un robot devine /sitemap.xml.",
     "fix": "Ajoutez une ligne Sitemap: à robots.txt."
    },
    "nl": {
     "title": "robots.txt noemt je sitemap niet",
     "why": "Google, Bing en AI-crawlers lezen eerst de regel Sitemap: in robots.txt. Zonder die regel wordt je sitemap alleen gevonden als een crawler /sitemap.xml raadt.",
     "fix": "Voeg een regel Sitemap: toe aan robots.txt."
    },
    "de": {
     "title": "robots.txt nennt Ihre Sitemap nicht",
     "why": "Google, Bing und KI-Crawler lesen zuerst die Zeile Sitemap: in der robots.txt. Ohne sie wird Ihre Sitemap nur gefunden, wenn ein Crawler /sitemap.xml errät.",
     "fix": "Fügen Sie der robots.txt eine Zeile Sitemap: hinzu."
    },
    "es": {
     "title": "robots.txt no nombra tu sitemap",
     "why": "Google, Bing y los rastreadores de IA leen primero la línea Sitemap: de robots.txt. Sin ella, tu sitemap solo se encuentra si un rastreador adivina /sitemap.xml.",
     "fix": "Añade una línea Sitemap: a robots.txt."
    }
   }
  },
  {
   "check": "sitemap_lastmod",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Sitemap has no useful last-modified dates",
     "why": "Crawlers use lastmod to decide which pages to fetch again. Missing dates, or one date on every URL, tell them nothing.",
     "fix": "Write each URL's real last-changed date in <lastmod>."
    },
    "fr": {
     "title": "Le sitemap n'a pas de dates de modification utiles",
     "why": "Les robots utilisent lastmod pour choisir les pages à revisiter. Des dates absentes, ou une même date sur chaque URL, ne leur apprennent rien.",
     "fix": "Indiquez dans <lastmod> la vraie date de dernière modification de chaque URL."
    },
    "nl": {
     "title": "Sitemap heeft geen bruikbare wijzigingsdatums",
     "why": "Crawlers gebruiken lastmod om te kiezen welke pagina's ze opnieuw ophalen. Ontbrekende datums, of één datum op elke URL, zeggen ze niets.",
     "fix": "Zet bij elke URL in <lastmod> de echte datum van de laatste wijziging."
    },
    "de": {
     "title": "Die Sitemap hat keine brauchbaren Änderungsdaten",
     "why": "Crawler nutzen lastmod, um zu entscheiden, welche Seiten sie erneut abrufen. Fehlende Daten oder dasselbe Datum für jede URL sagen ihnen nichts.",
     "fix": "Tragen Sie in <lastmod> das echte Datum der letzten Änderung jeder URL ein."
    },
    "es": {
     "title": "El sitemap no tiene fechas de modificación útiles",
     "why": "Los rastreadores usan lastmod para decidir qué páginas volver a pedir. Las fechas ausentes, o una misma fecha en cada URL, no les dicen nada.",
     "fix": "Escribe en <lastmod> la fecha real del último cambio de cada URL."
    }
   }
  },
  {
   "check": "sitemap_stale",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Sitemap and site disagree",
     "why": "Sitemap URLs that return errors or redirect, or pages found by crawling that the sitemap omits.",
     "fix": "Regenerate the sitemap from the live pages."
    },
    "fr": {
     "title": "Le sitemap et le site ne concordent pas",
     "why": "URL du sitemap qui renvoient des erreurs ou des redirections, ou pages trouvées à l'exploration que le sitemap omet.",
     "fix": "Régénérez le sitemap à partir des pages en ligne."
    },
    "nl": {
     "title": "Sitemap en site komen niet overeen",
     "why": "Sitemap-URL's die fouten geven of doorsturen, of gecrawlde pagina's die in de sitemap ontbreken.",
     "fix": "Genereer de sitemap opnieuw op basis van de live pagina's."
    },
    "de": {
     "title": "Sitemap und Website passen nicht zusammen",
     "why": "Sitemap-URLs, die Fehler liefern oder weiterleiten, oder per Crawl gefundene Seiten, die in der Sitemap fehlen.",
     "fix": "Erzeugen Sie die Sitemap aus den Live-Seiten neu."
    },
    "es": {
     "title": "El sitemap y el sitio no coinciden",
     "why": "URL del sitemap que devuelven errores o redirigen, o páginas encontradas al rastrear que el sitemap omite.",
     "fix": "Regenera el sitemap a partir de las páginas activas."
    }
   }
  },
  {
   "check": "slow_page",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Slow page",
     "why": "The page took over 3 seconds to load for our crawler. Crawlers have time budgets and drop slow sites.",
     "fix": "Cache the page, use a CDN, reduce server work."
    },
    "fr": {
     "title": "Page lente",
     "why": "La page a mis plus de 3 secondes à se charger pour notre robot. Les robots ont un temps limité et abandonnent les sites lents.",
     "fix": "Mettez la page en cache, utilisez un CDN, réduisez le travail du serveur."
    },
    "nl": {
     "title": "Trage pagina",
     "why": "De pagina deed er meer dan 3 seconden over om te laden voor onze crawler. Crawlers hebben een tijdsbudget en laten trage sites links liggen.",
     "fix": "Cache de pagina, gebruik een CDN, verminder het werk van de server."
    },
    "de": {
     "title": "Langsame Seite",
     "why": "Die Seite brauchte für unseren Crawler über 3 Sekunden zum Laden. Crawler haben Zeitbudgets und lassen langsame Websites links liegen.",
     "fix": "Cachen Sie die Seite, nutzen Sie ein CDN, reduzieren Sie die Serverlast."
    },
    "es": {
     "title": "Página lenta",
     "why": "La página tardó más de 3 segundos en cargar para nuestro crawler. Los crawlers tienen presupuestos de tiempo y descartan los sitios lentos.",
     "fix": "Usa caché para la página, una CDN y reduce el trabajo del servidor."
    }
   }
  },
  {
   "check": "heavy_page",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Very large HTML",
     "why": "HTML over 500 KB is slow to download and parse, and over 1 MB some crawlers cut it off.",
     "fix": "Trim inline data and scripts; paginate long lists."
    },
    "fr": {
     "title": "HTML très volumineux",
     "why": "Un HTML de plus de 500 Ko est lent à télécharger et à analyser, et au-delà de 1 Mo certains robots le tronquent.",
     "fix": "Allégez les données et scripts en ligne ; paginez les longues listes."
    },
    "nl": {
     "title": "Zeer grote HTML",
     "why": "HTML van meer dan 500 KB is traag om te downloaden en te verwerken, en boven 1 MB kappen sommige crawlers het af.",
     "fix": "Snoei inline data en scripts; pagineer lange lijsten."
    },
    "de": {
     "title": "Sehr großes HTML",
     "why": "HTML über 500 KB ist langsam zu laden und zu verarbeiten, und über 1 MB schneiden manche Crawler es ab.",
     "fix": "Kürzen Sie Inline-Daten und Skripte, paginieren Sie lange Listen."
    },
    "es": {
     "title": "HTML muy grande",
     "why": "Un HTML de más de 500 KB es lento de descargar y analizar, y por encima de 1 MB algunos rastreadores lo cortan.",
     "fix": "Reduce los datos y scripts incrustados; pagina las listas largas."
    }
   }
  },
  {
   "check": "img_alt_missing",
   "section": "structure",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Images without alt text",
     "why": "Alt text is how assistants read images.",
     "fix": "Add a short alt to every meaningful image."
    },
    "fr": {
     "title": "Images sans texte alternatif",
     "why": "Le texte alternatif est la façon dont les assistants lisent les images.",
     "fix": "Ajoutez un alt court à chaque image significative."
    },
    "nl": {
     "title": "Afbeeldingen zonder alt-tekst",
     "why": "Met alt-tekst lezen assistenten afbeeldingen.",
     "fix": "Voeg een korte alt toe aan elke relevante afbeelding."
    },
    "de": {
     "title": "Bilder ohne Alt-Text",
     "why": "Über den Alt-Text lesen Assistenten Bilder.",
     "fix": "Fügen Sie jedem relevanten Bild einen kurzen Alt-Text hinzu."
    },
    "es": {
     "title": "Imágenes sin texto alternativo",
     "why": "El texto alternativo es como los asistentes leen las imágenes.",
     "fix": "Añade un alt breve a cada imagen relevante."
    }
   }
  },
  {
   "check": "js_listing",
   "section": "render",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "inferred",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Product or item list loads with JavaScript",
     "why": "In the HTML AI crawlers receive, this page lists no products or items: the list is added by JavaScript after the page loads, so a crawler sees an empty category.",
     "fix": "Render the list on the server (SSR/SSG) or include the item names, prices and links in the HTML."
    },
    "fr": {
     "title": "La liste de produits ou d'articles se charge avec JavaScript",
     "why": "Dans le HTML que reçoivent les robots IA, cette page ne liste aucun produit ni article : la liste est ajoutée par JavaScript après le chargement, et le robot voit donc une catégorie vide.",
     "fix": "Générez la liste côté serveur (SSR/SSG) ou incluez les noms, prix et liens des articles dans le HTML."
    },
    "nl": {
     "title": "Product- of itemlijst laadt via JavaScript",
     "why": "In de HTML die AI-crawlers ontvangen, staan op deze pagina geen producten of items: de lijst wordt door JavaScript toegevoegd nadat de pagina is geladen, dus een crawler ziet een lege categorie.",
     "fix": "Render de lijst op de server (SSR/SSG) of zet de namen, prijzen en links van de items in de HTML."
    },
    "de": {
     "title": "Produkt- oder Artikelliste wird per JavaScript geladen",
     "why": "Im HTML, das KI-Crawler erhalten, listet diese Seite keine Produkte oder Artikel: Die Liste wird nach dem Laden per JavaScript ergänzt, daher sieht ein Crawler eine leere Kategorie.",
     "fix": "Rendern Sie die Liste auf dem Server (SSR/SSG) oder nehmen Sie Namen, Preise und Links der Einträge ins HTML auf."
    },
    "es": {
     "title": "La lista de productos o elementos se carga con JavaScript",
     "why": "En el HTML que reciben los crawlers de IA, esta página no lista ningún producto ni elemento: la lista la añade JavaScript tras cargar la página, así que el crawler ve una categoría vacía.",
     "fix": "Renderiza la lista en el servidor (SSR/SSG) o incluye en el HTML los nombres, precios y enlaces de los elementos."
    }
   }
  },
  {
   "check": "not_answer_first",
   "section": "answers",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "inferred",
   "measured": false,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Page does not answer the question first",
     "why": "The answer a buyer wants is not in the first screen of text.",
     "fix": "Open with the answer in the first two sentences."
    },
    "fr": {
     "title": "La page ne répond pas d'abord à la question",
     "why": "La réponse que cherche un acheteur ne figure pas dans le premier écran de texte.",
     "fix": "Commencez par la réponse, dans les deux premières phrases."
    },
    "nl": {
     "title": "Pagina beantwoordt de vraag niet als eerste",
     "why": "Het antwoord dat een koper zoekt, staat niet in het eerste scherm tekst.",
     "fix": "Begin met het antwoord in de eerste twee zinnen."
    },
    "de": {
     "title": "Seite beantwortet die Frage nicht zuerst",
     "why": "Die Antwort, die ein Käufer sucht, steht nicht im ersten Textabschnitt.",
     "fix": "Beginnen Sie mit der Antwort in den ersten zwei Sätzen."
    },
    "es": {
     "title": "La página no responde primero a la pregunta",
     "why": "La respuesta que busca un comprador no está en la primera pantalla de texto.",
     "fix": "Empieza con la respuesta en las dos primeras frases."
    }
   }
  },
  {
   "check": "no_faq",
   "section": "answers",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No FAQ",
     "why": "No page answers common buyer questions in question-and-answer form.",
     "fix": "Add an FAQ with the real questions customers ask."
    },
    "fr": {
     "title": "Pas de FAQ",
     "why": "Aucune page ne répond aux questions courantes des acheteurs sous forme de questions-réponses.",
     "fix": "Ajoutez une FAQ avec les vraies questions que posent vos clients."
    },
    "nl": {
     "title": "Geen FAQ",
     "why": "Geen enkele pagina beantwoordt veelgestelde koperskvragen in vraag-en-antwoordvorm.",
     "fix": "Voeg een FAQ toe met de echte vragen van je klanten."
    },
    "de": {
     "title": "Keine FAQ",
     "why": "Keine Seite beantwortet häufige Käuferfragen in Frage-Antwort-Form.",
     "fix": "Ergänzen Sie eine FAQ mit den echten Fragen Ihrer Kunden."
    },
    "es": {
     "title": "Sin FAQ",
     "why": "Ninguna página responde a las preguntas habituales de los compradores en formato de pregunta y respuesta.",
     "fix": "Añade una FAQ con las preguntas reales que hacen tus clientes."
    }
   }
  },
  {
   "check": "not_quotable",
   "section": "answers",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "inferred",
   "measured": false,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Page is hard to quote",
     "why": "We could not find a self-contained sentence an assistant could lift as an answer.",
     "fix": "Add short factual sentences: what it is, who it is for, price, limits."
    },
    "fr": {
     "title": "La page est difficile à citer",
     "why": "Nous n'avons pas trouvé de phrase autonome qu'un assistant pourrait reprendre comme réponse.",
     "fix": "Ajoutez des phrases courtes et factuelles : de quoi il s'agit, à qui cela s'adresse, le prix, les limites."
    },
    "nl": {
     "title": "Pagina is moeilijk te citeren",
     "why": "We vonden geen op zichzelf staande zin die een assistent als antwoord kan overnemen.",
     "fix": "Voeg korte, feitelijke zinnen toe: wat het is, voor wie het is, prijs, beperkingen."
    },
    "de": {
     "title": "Seite ist schwer zu zitieren",
     "why": "Wir fanden keinen eigenständigen Satz, den ein Assistent als Antwort übernehmen könnte.",
     "fix": "Ergänzen Sie kurze, sachliche Sätze: was es ist, für wen, Preis, Grenzen."
    },
    "es": {
     "title": "La página es difícil de citar",
     "why": "No encontramos ninguna frase autónoma que un asistente pueda usar como respuesta.",
     "fix": "Añade frases breves y factuales: qué es, para quién es, precio y límites."
    }
   }
  },
  {
   "check": "buyer_question_unanswered",
   "section": "answers",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "inferred",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Buyer questions the site does not answer",
     "why": "These questions are what customers ask assistants; no page on your site answers them.",
     "fix": "Write a page or section for each (suggested answers in the fix box)."
    },
    "fr": {
     "title": "Questions d'acheteurs sans réponse sur le site",
     "why": "Ce sont les questions que les clients posent aux assistants ; aucune page de votre site n'y répond.",
     "fix": "Rédigez une page ou une section pour chacune (réponses suggérées dans l'encadré de correction)."
    },
    "nl": {
     "title": "Koperskvragen die de site niet beantwoordt",
     "why": "Dit zijn de vragen die klanten aan assistenten stellen; geen enkele pagina op je site beantwoordt ze.",
     "fix": "Schrijf voor elke vraag een pagina of sectie (voorgestelde antwoorden staan in het fixvak)."
    },
    "de": {
     "title": "Käuferfragen, die die Website nicht beantwortet",
     "why": "Diese Fragen stellen Kunden Assistenten, aber keine Seite Ihrer Website beantwortet sie.",
     "fix": "Schreiben Sie zu jeder eine Seite oder einen Abschnitt (Antwortvorschläge im Fix-Feld)."
    },
    "es": {
     "title": "Preguntas de compradores que el sitio no responde",
     "why": "Son las preguntas que los clientes hacen a los asistentes; ninguna página de tu sitio las responde.",
     "fix": "Escribe una página o sección para cada una (respuestas sugeridas en el cuadro de solución)."
    }
   }
  },
  {
   "check": "no_pricing_page",
   "section": "answers",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No pricing page found",
     "why": "Buyers ask assistants what it costs. Without a price page the assistant guesses or names a rival.",
     "fix": "Add a /pricing page with real prices or ranges."
    },
    "fr": {
     "title": "Aucune page de tarifs trouvée",
     "why": "Les acheteurs demandent aux assistants combien cela coûte. Sans page de tarifs, l'assistant devine ou cite un concurrent.",
     "fix": "Ajoutez une page /pricing avec de vrais prix ou des fourchettes."
    },
    "nl": {
     "title": "Geen prijspagina gevonden",
     "why": "Kopers vragen assistenten wat het kost. Zonder prijspagina gokt de assistent of noemt hij een concurrent.",
     "fix": "Voeg een /pricing-pagina toe met echte prijzen of prijsranges."
    },
    "de": {
     "title": "Keine Preisseite gefunden",
     "why": "Käufer fragen Assistenten, was es kostet. Ohne Preisseite rät der Assistent oder nennt einen Wettbewerber.",
     "fix": "Fügen Sie eine Seite /pricing mit echten Preisen oder Preisspannen hinzu."
    },
    "es": {
     "title": "No se encontró página de precios",
     "why": "Los compradores preguntan a los asistentes cuánto cuesta. Sin una página de precios, el asistente adivina o nombra a un competidor.",
     "fix": "Añade una página /pricing con precios o rangos reales."
    }
   }
  },
  {
   "check": "no_comparison_page",
   "section": "answers",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No comparison or alternatives page",
     "why": "'X vs Y' and 'alternatives to X' are the questions assistants answer most.",
     "fix": "Add an honest comparison page."
    },
    "fr": {
     "title": "Aucune page de comparaison ou d'alternatives",
     "why": "« X vs Y » et « alternatives à X » sont les questions auxquelles les assistants répondent le plus.",
     "fix": "Ajoutez une page de comparaison honnête."
    },
    "nl": {
     "title": "Geen vergelijkings- of alternatievenpagina",
     "why": "'X vs Y' en 'alternatieven voor X' zijn de vragen die assistenten het vaakst beantwoorden.",
     "fix": "Voeg een eerlijke vergelijkingspagina toe."
    },
    "de": {
     "title": "Keine Vergleichs- oder Alternativenseite",
     "why": "'X vs Y' und 'Alternativen zu X' sind die Fragen, die Assistenten am häufigsten beantworten.",
     "fix": "Fügen Sie eine ehrliche Vergleichsseite hinzu."
    },
    "es": {
     "title": "Sin página de comparativa o alternativas",
     "why": "'X vs Y' y 'alternativas a X' son las preguntas que más responden los asistentes.",
     "fix": "Añade una página de comparativa honesta."
    }
   }
  },
  {
   "check": "no_about_page",
   "section": "answers",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No about page found",
     "why": "Assistants check who is behind a business before recommending it.",
     "fix": "Add an about page: who you are, where, since when."
    },
    "fr": {
     "title": "Aucune page « À propos » trouvée",
     "why": "Les assistants vérifient qui est derrière une entreprise avant de la recommander.",
     "fix": "Ajoutez une page « À propos » : qui vous êtes, où, depuis quand."
    },
    "nl": {
     "title": "Geen over-ons-pagina gevonden",
     "why": "Assistenten controleren wie achter een bedrijf zit voordat ze het aanbevelen.",
     "fix": "Voeg een over-ons-pagina toe: wie je bent, waar, sinds wanneer."
    },
    "de": {
     "title": "Keine Über-uns-Seite gefunden",
     "why": "Assistenten prüfen, wer hinter einem Unternehmen steht, bevor sie es empfehlen.",
     "fix": "Fügen Sie eine Über-uns-Seite hinzu: wer Sie sind, wo, seit wann."
    },
    "es": {
     "title": "No se encontró página «Quiénes somos»",
     "why": "Los asistentes comprueban quién está detrás de un negocio antes de recomendarlo.",
     "fix": "Añade una página «Quiénes somos»: quién eres, dónde estás y desde cuándo."
    }
   }
  },
  {
   "check": "description_length",
   "section": "structure",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Meta description too short or too long",
     "why": "Search results and assistants show about 155 characters. Under 50 says too little; over 160 is cut off mid-sentence.",
     "fix": "Reword the description so the whole sentence fits in 50-160 characters: what the page offers and for whom. Do not cut it off and do not end it with …."
    },
    "fr": {
     "title": "Méta description trop courte ou trop longue",
     "why": "Les résultats de recherche et les assistants affichent environ 155 caractères. En dessous de 50, elle en dit trop peu ; au-delà de 160, elle est coupée en pleine phrase.",
     "fix": "Reformulez la description pour que la phrase entière tienne en 50 à 160 caractères : ce que la page propose et pour qui. Ne la coupez pas et ne la terminez pas par « … »."
    },
    "nl": {
     "title": "Metabeschrijving te kort of te lang",
     "why": "Zoekresultaten en assistenten tonen ongeveer 155 tekens. Onder 50 is te weinig; boven 160 wordt midden in een zin afgekapt.",
     "fix": "Herschrijf de beschrijving zodat de hele zin in 50-160 tekens past: wat de pagina biedt en voor wie. Knip hem niet af en eindig niet met …"
    },
    "de": {
     "title": "Meta-Description zu kurz oder zu lang",
     "why": "Suchergebnisse und Assistenten zeigen etwa 155 Zeichen. Unter 50 sagt zu wenig, über 160 wird mitten im Satz abgeschnitten.",
     "fix": "Formulieren Sie die Description so um, dass der ganze Satz in 50-160 Zeichen passt: was die Seite bietet und für wen. Schneiden Sie sie nicht ab und enden Sie nicht mit …"
    },
    "es": {
     "title": "Meta descripción demasiado corta o demasiado larga",
     "why": "Los resultados de búsqueda y los asistentes muestran unos 155 caracteres. Menos de 50 dice muy poco; más de 160 se corta a mitad de frase.",
     "fix": "Reescribe la descripción para que la frase entera quepa en 50-160 caracteres: qué ofrece la página y para quién. No la cortes ni la termines con …"
    }
   }
  },
  {
   "check": "lang_missing",
   "section": "structure",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No language declared",
     "why": "Without <html lang>, crawlers guess the language, and answers in the wrong language are less likely to cite you.",
     "fix": "Add the page language to the html tag, for example <html lang=\"en\">."
    },
    "fr": {
     "title": "Aucune langue déclarée",
     "why": "Sans <html lang>, les robots devinent la langue, et les réponses dans la mauvaise langue ont moins de chances de vous citer.",
     "fix": "Ajoutez la langue de la page à la balise html, par exemple <html lang=\"fr\">."
    },
    "nl": {
     "title": "Geen taal opgegeven",
     "why": "Zonder <html lang> raden crawlers de taal, en antwoorden in de verkeerde taal citeren je minder snel.",
     "fix": "Voeg de paginataal toe aan de html-tag, bijvoorbeeld <html lang=\"nl\">."
    },
    "de": {
     "title": "Keine Sprache angegeben",
     "why": "Ohne <html lang> raten Crawler die Sprache, und Antworten in der falschen Sprache zitieren Sie seltener.",
     "fix": "Geben Sie die Seitensprache im html-Tag an, zum Beispiel <html lang=\"de\">."
    },
    "es": {
     "title": "Idioma no declarado",
     "why": "Sin <html lang>, los crawlers adivinan el idioma, y es menos probable que te citen en respuestas en otro idioma.",
     "fix": "Añade el idioma de la página a la etiqueta html, por ejemplo <html lang=\"es\">."
    }
   }
  },
  {
   "check": "og_image_missing",
   "section": "structure",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "page",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No social image (og:image)",
     "why": "Links shared in chats, social networks and some assistants show a blank card without og:image.",
     "fix": "Add an og:image of at least 1200 x 630 pixels."
    },
    "fr": {
     "title": "Pas d'image sociale (og:image)",
     "why": "Les liens partagés dans les messageries, les réseaux sociaux et certains assistants affichent une carte vide sans og:image.",
     "fix": "Ajoutez une og:image d'au moins 1200 x 630 pixels."
    },
    "nl": {
     "title": "Geen socialmedia-afbeelding (og:image)",
     "why": "Links die gedeeld worden in chats, sociale netwerken en sommige assistenten tonen zonder og:image een lege kaart.",
     "fix": "Voeg een og:image toe van minstens 1200 x 630 pixels."
    },
    "de": {
     "title": "Kein Social-Bild (og:image)",
     "why": "Links, die in Chats, sozialen Netzwerken und einigen Assistenten geteilt werden, zeigen ohne og:image eine leere Karte.",
     "fix": "Fügen Sie ein og:image mit mindestens 1200 x 630 Pixeln hinzu."
    },
    "es": {
     "title": "Sin imagen para redes sociales (og:image)",
     "why": "Los enlaces compartidos en chats, redes sociales y algunos asistentes muestran una tarjeta en blanco sin og:image.",
     "fix": "Añade un og:image de al menos 1200 x 630 píxeles."
    }
   }
  },
  {
   "check": "schema_rejected",
   "section": "structure",
   "severity": "warning",
   "added_version": 4,
   "added": "2026-10-21",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Structured data Google detects but rejects",
     "why": "The markup parses, but a type Google builds search results from is missing a property it requires, so Google reports the page as failing its rich-result check. Schema is not a ranking lever; a rejected block is just an error in your Search Console report.",
     "fix": "Add the missing properties named below, or use a type with no required properties for what the page is (a subscription service is a Service, not a Product), then re-test at search.google.com/test/rich-results."
    },
    "fr": {
     "title": "Données structurées que Google détecte mais rejette",
     "why": "Le balisage est lisible, mais un type dont Google tire des résultats enrichis n'a pas une propriété obligatoire : Google signale la page comme échouant au test des résultats enrichis. Le balisage n'améliore pas le classement ; un bloc rejeté est simplement une erreur dans votre rapport Search Console.",
     "fix": "Ajoutez les propriétés manquantes indiquées ci-dessous, ou utilisez un type sans propriété obligatoire pour ce qu'est la page (un abonnement est un Service, pas un Product), puis testez à nouveau sur search.google.com/test/rich-results."
    },
    "nl": {
     "title": "Gestructureerde data die Google ziet maar afwijst",
     "why": "De markup is leesbaar, maar bij een type waarmee Google zoekresultaten opbouwt ontbreekt een verplichte eigenschap, dus Google meldt de pagina als mislukt voor de rich-resultcontrole. Schema is geen rankinghefboom; een afgewezen blok is gewoon een fout in je Search Console-rapport.",
     "fix": "Voeg de hieronder genoemde ontbrekende eigenschappen toe, of gebruik een type zonder verplichte eigenschappen voor wat de pagina is (een abonnementsdienst is een Service, geen Product) en test opnieuw op search.google.com/test/rich-results."
    },
    "de": {
     "title": "Strukturierte Daten, die Google erkennt, aber ablehnt",
     "why": "Das Markup lässt sich lesen, aber bei einem Typ, aus dem Google Suchergebnisse baut, fehlt eine Pflichtangabe; Google meldet die Seite deshalb als durchgefallen bei der Rich-Results-Prüfung. Schema ist kein Ranking-Hebel; ein abgelehnter Block ist nur ein Fehler in Ihrem Search-Console-Bericht.",
     "fix": "Ergänzen Sie die unten genannten fehlenden Angaben oder nehmen Sie einen Typ ohne Pflichtangaben für das, was die Seite ist (ein Abo-Dienst ist ein Service, kein Product), und testen Sie erneut unter search.google.com/test/rich-results."
    },
    "es": {
     "title": "Datos estructurados que Google detecta pero rechaza",
     "why": "El marcado se lee bien, pero a un tipo con el que Google construye resultados le falta una propiedad obligatoria, así que Google marca la página como fallida en la prueba de resultados enriquecidos. El marcado no mejora el posicionamiento; un bloque rechazado es solo un error en tu informe de Search Console.",
     "fix": "Añade las propiedades que faltan indicadas abajo, o usa un tipo sin propiedades obligatorias para lo que es la página (un servicio de suscripción es un Service, no un Product) y vuelve a probar en search.google.com/test/rich-results."
    }
   }
  },
  {
   "check": "schema_invalid",
   "section": "structure",
   "severity": "warning",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Structured data does not parse",
     "why": "A JSON-LD block on the page is not valid JSON, so crawlers ignore it completely.",
     "fix": "Fix the JSON syntax (a missing comma or quote) and validate it at validator.schema.org."
    },
    "fr": {
     "title": "Les données structurées ne sont pas analysables",
     "why": "Un bloc JSON-LD de la page n'est pas du JSON valide : les robots l'ignorent complètement.",
     "fix": "Corrigez la syntaxe JSON (une virgule ou un guillemet manquant) et validez-la sur validator.schema.org."
    },
    "nl": {
     "title": "Gestructureerde data kan niet worden gelezen",
     "why": "Een JSON-LD-blok op de pagina is geen geldige JSON, dus crawlers negeren het volledig.",
     "fix": "Herstel de JSON-syntaxis (een ontbrekende komma of aanhalingsteken) en valideer op validator.schema.org."
    },
    "de": {
     "title": "Strukturierte Daten lassen sich nicht parsen",
     "why": "Ein JSON-LD-Block auf der Seite ist kein gültiges JSON, daher ignorieren Crawler ihn vollständig.",
     "fix": "Korrigieren Sie die JSON-Syntax (ein fehlendes Komma oder Anführungszeichen) und prüfen Sie sie auf validator.schema.org."
    },
    "es": {
     "title": "Los datos estructurados no se pueden interpretar",
     "why": "Un bloque JSON-LD de la página no es un JSON válido, así que los crawlers lo ignoran por completo.",
     "fix": "Corrige la sintaxis JSON (falta una coma o unas comillas) y valídala en validator.schema.org."
    }
   }
  },
  {
   "check": "mixed_content",
   "section": "technical",
   "severity": "warning",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Mixed content (HTTP resources on an HTTPS page)",
     "why": "Browsers block or flag scripts, styles and images loaded over plain HTTP on a secure page; the page can break or show a warning.",
     "fix": "Load every resource over https:// (or a protocol-relative path)."
    },
    "fr": {
     "title": "Contenu mixte (ressources HTTP sur une page HTTPS)",
     "why": "Les navigateurs bloquent ou signalent les scripts, styles et images chargés en HTTP simple sur une page sécurisée ; la page peut s'afficher mal ou afficher un avertissement.",
     "fix": "Chargez chaque ressource en https:// (ou avec un chemin relatif au protocole)."
    },
    "nl": {
     "title": "Mixed content (HTTP-bronnen op een HTTPS-pagina)",
     "why": "Browsers blokkeren of markeren scripts, stijlen en afbeeldingen die via gewoon HTTP op een beveiligde pagina worden geladen; de pagina kan kapotgaan of een waarschuwing tonen.",
     "fix": "Laad elke bron via https:// (of een protocol-relatief pad)."
    },
    "de": {
     "title": "Mixed Content (HTTP-Ressourcen auf einer HTTPS-Seite)",
     "why": "Browser blockieren oder markieren Skripte, Styles und Bilder, die auf einer sicheren Seite über reines HTTP geladen werden. Die Seite kann dadurch fehlerhaft sein oder eine Warnung zeigen.",
     "fix": "Laden Sie jede Ressource über https:// (oder einen protokollrelativen Pfad)."
    },
    "es": {
     "title": "Contenido mixto (recursos HTTP en una página HTTPS)",
     "why": "Los navegadores bloquean o señalan los scripts, estilos e imágenes cargados por HTTP sin cifrar en una página segura; la página puede fallar o mostrar un aviso.",
     "fix": "Carga todos los recursos por https:// (o con una ruta relativa al protocolo)."
    }
   }
  },
  {
   "check": "render_blocking",
   "section": "technical",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Render-blocking scripts and styles",
     "why": "Scripts without async/defer and stylesheets in <head> must load before anything is shown, which slows the first paint for visitors and crawlers that render.",
     "fix": "Add defer to scripts in <head>, inline critical CSS and load the rest without blocking."
    },
    "fr": {
     "title": "Scripts et styles bloquant le rendu",
     "why": "Les scripts sans async/defer et les feuilles de style dans <head> doivent se charger avant tout affichage, ce qui ralentit le premier rendu pour les visiteurs et les robots qui effectuent le rendu.",
     "fix": "Ajoutez defer aux scripts dans <head>, intégrez le CSS critique en ligne et chargez le reste sans blocage."
    },
    "nl": {
     "title": "Renderblokkerende scripts en stijlen",
     "why": "Scripts zonder async/defer en stylesheets in <head> moeten laden voordat er iets wordt getoond, wat de eerste weergave vertraagt voor bezoekers en crawlers die renderen.",
     "fix": "Voeg defer toe aan scripts in <head>, zet kritieke CSS inline en laad de rest zonder te blokkeren."
    },
    "de": {
     "title": "Render-blockierende Skripte und Styles",
     "why": "Skripte ohne async/defer und Stylesheets im <head> müssen geladen sein, bevor etwas angezeigt wird. Das verlangsamt die erste Darstellung für Besucher und für Crawler, die rendern.",
     "fix": "Fügen Sie Skripten im <head> defer hinzu, binden Sie kritisches CSS inline ein und laden Sie den Rest ohne Blockade."
    },
    "es": {
     "title": "Scripts y estilos que bloquean el renderizado",
     "why": "Los scripts sin async/defer y las hojas de estilo en <head> deben cargarse antes de mostrar nada, lo que retrasa el primer renderizado para visitantes y crawlers que renderizan.",
     "fix": "Añade defer a los scripts de <head>, incluye el CSS crítico en línea y carga el resto sin bloquear."
    }
   }
  },
  {
   "check": "low_text_ratio",
   "section": "render",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Very little text compared with code",
     "why": "Under 5% of the HTML is readable text: crawlers download a lot of markup to find a little content.",
     "fix": "Move inline scripts and styles to files and make sure the main content is in the HTML."
    },
    "fr": {
     "title": "Très peu de texte par rapport au code",
     "why": "Moins de 5 % du HTML est du texte lisible : les robots téléchargent beaucoup de balisage pour trouver peu de contenu.",
     "fix": "Déplacez les scripts et styles en ligne vers des fichiers et vérifiez que le contenu principal est dans le HTML."
    },
    "nl": {
     "title": "Weinig tekst ten opzichte van code",
     "why": "Minder dan 5% van de HTML is leesbare tekst: crawlers downloaden veel markup om weinig content te vinden.",
     "fix": "Verplaats inline scripts en stijlen naar bestanden en zorg dat de hoofdcontent in de HTML staat."
    },
    "de": {
     "title": "Sehr wenig Text im Verhältnis zum Code",
     "why": "Unter 5 % des HTML sind lesbarer Text: Crawler laden viel Markup herunter, um wenig Inhalt zu finden.",
     "fix": "Lagern Sie Inline-Skripte und -Styles in Dateien aus und stellen Sie sicher, dass der Hauptinhalt im HTML steht."
    },
    "es": {
     "title": "Muy poco texto en comparación con el código",
     "why": "Menos del 5% del HTML es texto legible: los crawlers descargan mucho código para encontrar poco contenido.",
     "fix": "Mueve los scripts y estilos en línea a archivos y asegúrate de que el contenido principal esté en el HTML."
    }
   }
  },
  {
   "check": "url_format",
   "section": "technical",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "URL is hard to read or share",
     "why": "Upper-case letters, underscores, spaces or very long URLs (over 115 characters) cause duplicate URLs and are cut off in results.",
     "fix": "Use short, lower-case URLs with hyphens; redirect the old address to the new one."
    },
    "fr": {
     "title": "URL difficile à lire ou à partager",
     "why": "Les majuscules, tirets bas, espaces ou URL très longues (plus de 115 caractères) créent des URL en double et sont coupées dans les résultats.",
     "fix": "Utilisez des URL courtes, en minuscules, avec des tirets ; redirigez l'ancienne adresse vers la nouvelle."
    },
    "nl": {
     "title": "URL is moeilijk te lezen of te delen",
     "why": "Hoofdletters, underscores, spaties of zeer lange URL's (meer dan 115 tekens) veroorzaken dubbele URL's en worden in resultaten afgekapt.",
     "fix": "Gebruik korte URL's in kleine letters met koppeltekens; stuur het oude adres door naar het nieuwe."
    },
    "de": {
     "title": "URL ist schwer lesbar oder teilbar",
     "why": "Großbuchstaben, Unterstriche, Leerzeichen oder sehr lange URLs (über 115 Zeichen) erzeugen doppelte URLs und werden in Ergebnissen abgeschnitten.",
     "fix": "Verwenden Sie kurze URLs in Kleinbuchstaben mit Bindestrichen und leiten Sie die alte Adresse auf die neue weiter."
    },
    "es": {
     "title": "URL difícil de leer o compartir",
     "why": "Las mayúsculas, los guiones bajos, los espacios o las URL muy largas (más de 115 caracteres) generan URL duplicadas y se cortan en los resultados.",
     "fix": "Usa URL cortas, en minúsculas y con guiones; redirige la dirección antigua a la nueva."
    }
   }
  },
  {
   "check": "meta_refresh",
   "section": "technical",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Meta refresh redirect",
     "why": "A <meta http-equiv=refresh> redirect is slow and not every crawler follows it.",
     "fix": "Replace it with a server-side 301 redirect."
    },
    "fr": {
     "title": "Redirection par meta refresh",
     "why": "Une redirection <meta http-equiv=refresh> est lente et tous les robots ne la suivent pas.",
     "fix": "Remplacez-la par une redirection 301 côté serveur."
    },
    "nl": {
     "title": "Meta refresh-redirect",
     "why": "Een <meta http-equiv=refresh>-redirect is traag en niet elke crawler volgt hem.",
     "fix": "Vervang hem door een 301-redirect op de server."
    },
    "de": {
     "title": "Meta-Refresh-Weiterleitung",
     "why": "Eine <meta http-equiv=refresh>-Weiterleitung ist langsam, und nicht jeder Crawler folgt ihr.",
     "fix": "Ersetzen Sie sie durch eine serverseitige 301-Weiterleitung."
    },
    "es": {
     "title": "Redirección con meta refresh",
     "why": "Una redirección <meta http-equiv=refresh> es lenta y no todos los crawlers la siguen.",
     "fix": "Sustitúyela por una redirección 301 en el servidor."
    }
   }
  },
  {
   "check": "redirect_loop",
   "section": "technical",
   "severity": "error",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Redirect loop",
     "why": "The URL redirects back to itself, so no crawler or browser ever reaches a page.",
     "fix": "Fix the redirect rules so the URL ends on one page that answers 200."
    },
    "fr": {
     "title": "Boucle de redirection",
     "why": "L'URL se redirige vers elle-même : aucun robot ni navigateur n'atteint jamais une page.",
     "fix": "Corrigez les règles de redirection pour que l'URL aboutisse à une page qui répond 200."
    },
    "nl": {
     "title": "Redirectlus",
     "why": "De URL stuurt terug naar zichzelf, dus geen enkele crawler of browser bereikt een pagina.",
     "fix": "Herstel de redirectregels zodat de URL op één pagina eindigt die 200 geeft."
    },
    "de": {
     "title": "Weiterleitungsschleife",
     "why": "Die URL leitet auf sich selbst zurück, sodass weder Crawler noch Browser je eine Seite erreichen.",
     "fix": "Korrigieren Sie die Weiterleitungsregeln, sodass die URL auf einer Seite endet, die mit 200 antwortet."
    },
    "es": {
     "title": "Bucle de redirecciones",
     "why": "La URL se redirige a sí misma, así que ningún crawler ni navegador llega nunca a una página.",
     "fix": "Corrige las reglas de redirección para que la URL termine en una página que responda 200."
    }
   }
  },
  {
   "check": "img_oversized",
   "section": "technical",
   "severity": "warning",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Oversized images",
     "why": "Images over 300 KB slow the page for visitors and crawlers on mobile connections.",
     "fix": "Compress the image, serve WebP or AVIF and size it to the space it fills."
    },
    "fr": {
     "title": "Images trop lourdes",
     "why": "Les images de plus de 300 Ko ralentissent la page pour les visiteurs et les robots sur connexion mobile.",
     "fix": "Compressez l'image, servez du WebP ou de l'AVIF et dimensionnez-la à l'espace qu'elle occupe."
    },
    "nl": {
     "title": "Te grote afbeeldingen",
     "why": "Afbeeldingen boven 300 KB vertragen de pagina voor bezoekers en crawlers op mobiele verbindingen.",
     "fix": "Comprimeer de afbeelding, lever WebP of AVIF en pas het formaat aan de ruimte aan die hij inneemt."
    },
    "de": {
     "title": "Überdimensionierte Bilder",
     "why": "Bilder über 300 KB verlangsamen die Seite für Besucher und Crawler bei mobilen Verbindungen.",
     "fix": "Komprimieren Sie das Bild, liefern Sie WebP oder AVIF aus und passen Sie es an den Platz an, den es füllt."
    },
    "es": {
     "title": "Imágenes demasiado pesadas",
     "why": "Las imágenes de más de 300 KB ralentizan la página para visitantes y crawlers con conexiones móviles.",
     "fix": "Comprime la imagen, sirve WebP o AVIF y ajústala al tamaño del espacio que ocupa."
    }
   }
  },
  {
   "check": "canonical_broken",
   "section": "technical",
   "severity": "error",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Canonical points to a broken or redirecting URL",
     "why": "The canonical tells crawlers to index a URL that errors or redirects, so neither page is indexed reliably.",
     "fix": "Point the canonical at the final URL that answers 200, usually the page itself."
    },
    "fr": {
     "title": "La canonical pointe vers une URL cassée ou redirigée",
     "why": "La canonical demande aux robots d'indexer une URL qui renvoie une erreur ou une redirection : aucune des deux pages n'est indexée de façon fiable.",
     "fix": "Faites pointer la canonical vers l'URL finale qui répond 200, en général la page elle-même."
    },
    "nl": {
     "title": "Canonical verwijst naar een kapotte of doorsturende URL",
     "why": "De canonical zegt tegen crawlers dat ze een URL moeten indexeren die een fout geeft of doorstuurt, dus geen van beide pagina's wordt betrouwbaar geïndexeerd.",
     "fix": "Laat de canonical verwijzen naar de eind-URL die 200 geeft, meestal de pagina zelf."
    },
    "de": {
     "title": "Canonical zeigt auf eine defekte oder weiterleitende URL",
     "why": "Das Canonical weist Crawler an, eine URL zu indexieren, die Fehler liefert oder weiterleitet, daher wird keine der beiden Seiten zuverlässig indexiert.",
     "fix": "Lassen Sie das Canonical auf die finale URL zeigen, die mit 200 antwortet, meist die Seite selbst."
    },
    "es": {
     "title": "El canonical apunta a una URL rota o que redirige",
     "why": "El canonical indica a los crawlers que indexen una URL que da error o redirige, así que ninguna de las dos páginas se indexa de forma fiable.",
     "fix": "Haz que el canonical apunte a la URL final que responde 200, normalmente la propia página."
    }
   }
  },
  {
   "check": "canonical_noindex",
   "section": "technical",
   "severity": "warning",
   "added_version": 5,
   "added": "2026-10-23",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Canonical points to a noindex page",
     "why": "The page names a URL as the real one, but that URL tells search engines not to index it, so neither page can be indexed.",
     "fix": "Point the canonical at an indexable URL, usually the page itself, or remove the noindex from the target."
    },
    "fr": {
     "title": "La canonical pointe vers une page noindex",
     "why": "La page désigne une URL comme référence, mais cette URL demande aux moteurs de ne pas l'indexer : aucune des deux ne peut être indexée.",
     "fix": "Faites pointer la canonical vers une URL indexable, en général la page elle-même, ou retirez le noindex de la cible."
    },
    "nl": {
     "title": "Canonical verwijst naar een noindex-pagina",
     "why": "De pagina noemt een URL als origineel, maar die URL vraagt zoekmachines haar niet te indexeren, dus geen van beide pagina's kan worden geïndexeerd.",
     "fix": "Laat de canonical naar een indexeerbare URL verwijzen, meestal de pagina zelf, of haal de noindex bij het doel weg."
    },
    "de": {
     "title": "Canonical zeigt auf eine noindex-Seite",
     "why": "Die Seite nennt eine URL als Original, doch diese URL weist Suchmaschinen an, sie nicht zu indexieren. Keine der beiden Seiten kann indexiert werden.",
     "fix": "Lassen Sie das Canonical auf eine indexierbare URL zeigen, meist die Seite selbst, oder entfernen Sie noindex beim Ziel."
    },
    "es": {
     "title": "El canonical apunta a una página noindex",
     "why": "La página señala una URL como la original, pero esa URL pide a los buscadores que no la indexen, así que ninguna de las dos puede indexarse.",
     "fix": "Haz que el canonical apunte a una URL indexable, normalmente la propia página, o quita el noindex del destino."
    }
   }
  },
  {
   "check": "hreflang_not_reciprocal",
   "section": "technical",
   "severity": "warning",
   "added_version": 5,
   "added": "2026-10-23",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "hreflang alternate does not link back",
     "why": "This page lists a language version, but that version does not list this page back, or it is noindex or redirects. Google ignores alternates that are not reciprocal.",
     "fix": "On each alternate, add the return hreflang to this page, and make sure every alternate answers 200 and is indexable."
    },
    "fr": {
     "title": "L'alternative hreflang ne renvoie pas vers la page",
     "why": "Cette page cite une version linguistique, mais celle-ci ne la cite pas en retour, ou elle est en noindex ou redirigée. Google ignore les alternatives non réciproques.",
     "fix": "Sur chaque alternative, ajoutez le hreflang de retour vers cette page et vérifiez que chacune répond 200 et reste indexable."
    },
    "nl": {
     "title": "hreflang-alternatief verwijst niet terug",
     "why": "Deze pagina noemt een taalversie, maar die versie noemt deze pagina niet terug, of is noindex of verwijst door. Google negeert alternatieven zonder terugverwijzing.",
     "fix": "Voeg bij elk alternatief de terugverwijzende hreflang naar deze pagina toe en zorg dat elk 200 geeft en indexeerbaar is."
    },
    "de": {
     "title": "hreflang-Alternative verweist nicht zurück",
     "why": "Diese Seite nennt eine Sprachversion, doch diese nennt die Seite nicht zurück, oder sie ist noindex oder leitet um. Google ignoriert Alternativen ohne Gegenverweis.",
     "fix": "Fügen Sie bei jeder Alternative das Rück-hreflang auf diese Seite ein und prüfen Sie, dass jede 200 liefert und indexierbar ist."
    },
    "es": {
     "title": "La alternativa hreflang no enlaza de vuelta",
     "why": "Esta página lista una versión de idioma, pero esa versión no la lista a ella, o es noindex o redirige. Google ignora las alternativas que no son recíprocas.",
     "fix": "En cada alternativa, añade el hreflang de vuelta a esta página y comprueba que responde 200 y es indexable."
    }
   }
  },
  {
   "check": "internal_param_links",
   "section": "technical",
   "severity": "warning",
   "added_version": 6,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Internal links carry tracking or language parameters",
     "why": "Links such as /pricing?src=nav or /?lang=es make a new address for the same page. Crawlers see many copies, split the page's links between them, and search engines can pick the tagged copy as the page to show.",
     "fix": "Link to the clean address. Track clicks with an event, not a parameter, and switch language with a path (/es/), not ?lang=. Keep each page's canonical on the clean address."
    },
    "fr": {
     "title": "Des liens internes portent des paramètres de suivi ou de langue",
     "why": "Des liens comme /pricing?src=nav ou /?lang=es créent une nouvelle adresse pour la même page. Les robots voient plusieurs copies, répartissent entre elles les liens de la page, et les moteurs peuvent choisir la copie balisée comme page à afficher.",
     "fix": "Liez vers l'adresse propre. Mesurez les clics avec un événement, pas un paramètre, et changez de langue avec un chemin (/es/), pas avec ?lang=. Gardez le canonical de chaque page sur l'adresse propre."
    },
    "nl": {
     "title": "Interne links dragen tracking- of taalparameters",
     "why": "Links zoals /pricing?src=nav of /?lang=es maken een nieuw adres voor dezelfde pagina. Crawlers zien meerdere kopieën, verdelen de links van de pagina daarover, en zoekmachines kunnen de gelabelde kopie als te tonen pagina kiezen.",
     "fix": "Link naar het schone adres. Meet klikken met een event, niet met een parameter, en wissel van taal met een pad (/es/), niet met ?lang=. Houd de canonical van elke pagina op het schone adres."
    },
    "de": {
     "title": "Interne Links tragen Tracking- oder Sprachparameter",
     "why": "Links wie /pricing?src=nav oder /?lang=es erzeugen für dieselbe Seite eine neue Adresse. Crawler sehen mehrere Kopien, verteilen die Links der Seite darauf, und Suchmaschinen können die getaggte Kopie als anzuzeigende Seite wählen.",
     "fix": "Verlinken Sie auf die saubere Adresse. Messen Sie Klicks mit einem Event statt mit einem Parameter und wechseln Sie die Sprache über einen Pfad (/es/), nicht über ?lang=. Lassen Sie den Canonical jeder Seite auf der sauberen Adresse."
    },
    "es": {
     "title": "Enlaces internos con parámetros de seguimiento o de idioma",
     "why": "Enlaces como /pricing?src=nav o /?lang=es crean una dirección nueva para la misma página. Los rastreadores ven varias copias, reparten entre ellas los enlaces de la página, y los buscadores pueden elegir la copia etiquetada como la página a mostrar.",
     "fix": "Enlace a la dirección limpia. Mida los clics con un evento, no con un parámetro, y cambie de idioma con una ruta (/es/), no con ?lang=. Mantenga el canonical de cada página en la dirección limpia."
    }
   }
  },
  {
   "check": "internal_hash_links",
   "section": "technical",
   "severity": "warning",
   "added_version": 6,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Internal links use #/ routes",
     "why": "A link to /#/pass is the home page to a crawler: the fragment is dropped, so the page behind it has no address of its own and cannot be indexed or cited.",
     "fix": "Give each view its own path (/pass) that answers with its own HTML, and link to that path."
    },
    "fr": {
     "title": "Des liens internes utilisent des routes #/",
     "why": "Pour un robot, un lien vers /#/pass est la page d'accueil : le fragment est ignoré, donc la page qu'il ouvre n'a pas d'adresse propre et ne peut être ni indexée ni citée.",
     "fix": "Donnez à chaque vue son propre chemin (/pass) qui répond avec son propre HTML, et liez vers ce chemin."
    },
    "nl": {
     "title": "Interne links gebruiken #/-routes",
     "why": "Een link naar /#/pass is voor een crawler de homepage: het fragment valt weg, dus de pagina erachter heeft geen eigen adres en kan niet worden geïndexeerd of geciteerd.",
     "fix": "Geef elke weergave een eigen pad (/pass) dat met eigen HTML antwoordt, en link naar dat pad."
    },
    "de": {
     "title": "Interne Links nutzen #/-Routen",
     "why": "Ein Link auf /#/pass ist für einen Crawler die Startseite: Das Fragment wird verworfen, die Seite dahinter hat also keine eigene Adresse und kann weder indexiert noch zitiert werden.",
     "fix": "Geben Sie jeder Ansicht einen eigenen Pfad (/pass), der mit eigenem HTML antwortet, und verlinken Sie auf diesen Pfad."
    },
    "es": {
     "title": "Enlaces internos con rutas #/",
     "why": "Para un rastreador, un enlace a /#/pass es la página de inicio: el fragmento se descarta, así que la página de detrás no tiene dirección propia y no puede indexarse ni citarse.",
     "fix": "Dé a cada vista su propia ruta (/pass) que responda con su propio HTML, y enlace a esa ruta."
    }
   }
  },
  {
   "check": "snippet_cut",
   "section": "structure",
   "severity": "warning",
   "added_version": 7,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Title or description is cut off",
     "why": "A title or description that ends in \"…\", on a connecting word or inside an open bracket shows in search results and AI answers as a broken sentence. A length check that shortens text makes this worse: the length passes and the words are lost.",
     "fix": "Rewrite it so the whole phrase fits: titles 15-65 characters, descriptions 50-160, the words that name the page first and the brand last. Do not cut it, and do not end it with …."
    },
    "fr": {
     "title": "Le titre ou la description est coupé(e)",
     "why": "Un titre ou une description qui se termine par « … », sur un mot de liaison ou dans une parenthèse ouverte apparaît dans les résultats de recherche et les réponses d'IA comme une phrase brisée. Un contrôle de longueur qui raccourcit le texte aggrave le problème : la longueur passe et les mots sont perdus.",
     "fix": "Réécrivez-le pour que la phrase entière tienne : titres de 15 à 65 caractères, descriptions de 50 à 160, les mots qui nomment la page en premier et la marque en dernier. Ne le coupez pas et ne le terminez pas par « … »."
    },
    "nl": {
     "title": "Title of beschrijving is afgekapt",
     "why": "Een title of beschrijving die eindigt op \"…\", op een verbindingswoord of binnen een open haakje, verschijnt in zoekresultaten en AI-antwoorden als een gebroken zin. Een lengtecontrole die tekst inkort maakt het erger: de lengte klopt en de woorden zijn weg.",
     "fix": "Herschrijf hem zodat de hele zin past: titels van 15-65 tekens, beschrijvingen van 50-160, de woorden die de pagina benoemen eerst en de merknaam laatst. Knip hem niet af en eindig niet met …"
    },
    "de": {
     "title": "Title oder Description ist abgeschnitten",
     "why": "Ein Title oder eine Description, die auf „…“, auf einem Bindewort oder in einer offenen Klammer endet, erscheint in Suchergebnissen und KI-Antworten als zerbrochener Satz. Eine Längenprüfung, die Text kürzt, macht es schlimmer: Die Länge stimmt und die Worte fehlen.",
     "fix": "Formulieren Sie ihn so um, dass der ganze Satz passt: Titles mit 15-65 Zeichen, Descriptions mit 50-160, die Worte, die die Seite benennen, zuerst und die Marke zuletzt. Schneiden Sie ihn nicht ab und enden Sie nicht mit …"
    },
    "es": {
     "title": "El title o la descripción está cortado",
     "why": "Un title o una descripción que termina en «…», en una palabra de enlace o dentro de un paréntesis abierto aparece en los resultados de búsqueda y en las respuestas de IA como una frase rota. Un control de longitud que acorta el texto lo empeora: la longitud pasa y las palabras se pierden.",
     "fix": "Reescríbelo para que quepa la frase entera: titles de 15-65 caracteres, descripciones de 50-160, las palabras que nombran la página primero y la marca al final. No lo cortes ni lo termines con …"
    }
   }
  },
  {
   "check": "title_brand_first",
   "section": "structure",
   "severity": "notice",
   "added_version": 7,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Title starts with the brand, so the topic is cut first",
     "why": "When most titles open with the same brand name and run past 60 characters, search results cut the end, which is the part that says what this page is about.",
     "fix": "Keep the whole title within 60 characters so no part is cut. Where it has to be longer, put the page's own key words first and the brand after them (Topic | Brand)."
    },
    "fr": {
     "title": "Le titre commence par la marque : le sujet est coupé en premier",
     "why": "Quand la plupart des titres s'ouvrent sur le même nom de marque et dépassent 60 caractères, les résultats de recherche coupent la fin, c'est-à-dire la partie qui dit de quoi parle la page.",
     "fix": "Gardez le titre entier sous 60 caractères pour que rien ne soit coupé. S'il doit être plus long, mettez d'abord les mots-clés propres à la page, puis la marque (Sujet | Marque)."
    },
    "nl": {
     "title": "Title begint met de merknaam, dus het onderwerp wordt eerst afgekapt",
     "why": "Als de meeste titles met dezelfde merknaam beginnen en langer zijn dan 60 tekens, kappen zoekresultaten het einde af, en dat is het deel dat zegt waar de pagina over gaat.",
     "fix": "Houd de hele title binnen 60 tekens, zodat er niets wordt afgekapt. Moet hij langer zijn, zet dan de eigen kernwoorden van de pagina eerst en de merknaam erna (Onderwerp | Merk)."
    },
    "de": {
     "title": "Der Title beginnt mit der Marke, das Thema wird zuerst abgeschnitten",
     "why": "Beginnen die meisten Titles mit demselben Markennamen und sind länger als 60 Zeichen, schneiden Suchergebnisse das Ende ab, also den Teil, der sagt, worum es auf der Seite geht.",
     "fix": "Halten Sie den ganzen Title bei höchstens 60 Zeichen, damit nichts abgeschnitten wird. Muss er länger sein, setzen Sie zuerst die eigenen Schlüsselwörter der Seite und danach die Marke (Thema | Marke)."
    },
    "es": {
     "title": "El title empieza por la marca, así que el tema se corta primero",
     "why": "Cuando la mayoría de los titles empiezan por el mismo nombre de marca y pasan de 60 caracteres, los resultados de búsqueda cortan el final, que es la parte que dice de qué trata la página.",
     "fix": "Mantén el title entero por debajo de 60 caracteres para que no se corte nada. Si tiene que ser más largo, pon primero las palabras clave propias de la página y después la marca (Tema | Marca)."
    }
   }
  },
  {
   "check": "crawl_refused",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Pages refuse or do not answer our crawler",
     "why": "Some pages of the site answered 429 (too many requests), refused the crawler (401, 403 or a challenge page), or did not answer in time on a second try. Search engines and AI crawlers meet the same walls: repeated 429 or timeouts make them slow down or stop crawling the site, and refused pages are not read. We left these pages out of the page checks, so this is the only place they show.",
     "fix": "Match the fix to what the page did. 429: serve the pages from a cache or a static result and raise the rate limit for crawlers; keep Retry-After short. 401, 403 or a challenge page: allow CitedBot in the firewall rule that blocks it; the bot test on this report shows which crawlers get through. No answer: find the route that computes a live result on the first request and serve a stored result or a form instead. If verified Googlebot and OAI-SearchBot get a 200 on these pages and only our crawler is refused, the wall is a rule against unknown bots, and you can leave it."
    },
    "fr": {
     "title": "Des pages refusent notre robot ou ne répondent pas",
     "why": "Certaines pages du site ont répondu 429 (trop de requêtes), ont refusé le robot (401, 403 ou une page de vérification) ou n'ont pas répondu à temps au second essai. Les moteurs de recherche et les robots d'IA se heurtent aux mêmes murs : des 429 ou des délais répétés les poussent à ralentir ou à cesser d'explorer le site, et les pages refusées ne sont pas lues. Nous les avons écartées des contrôles de page : c'est le seul endroit où elles apparaissent.",
     "fix": "Adaptez le correctif à ce que la page a fait. 429 : servez ces pages depuis un cache ou un résultat statique et relevez la limite de débit pour les robots ; gardez un Retry-After court. 401, 403 ou page de vérification : autorisez CitedBot dans la règle du pare-feu qui le bloque ; le test des robots de ce rapport montre lesquels passent. Pas de réponse : trouvez la route qui calcule un résultat en direct à la première requête et servez à la place un résultat enregistré ou un formulaire. Si Googlebot et OAI-SearchBot vérifiés obtiennent un 200 sur ces pages et que seul notre robot est refusé, le mur est une règle contre les robots inconnus, et vous pouvez le laisser."
    },
    "nl": {
     "title": "Pagina's weigeren onze crawler of antwoorden niet",
     "why": "Sommige pagina's van de site gaven 429 (te veel verzoeken), weigerden de crawler (401, 403 of een controlepagina) of antwoordden bij een tweede poging niet op tijd. Zoekmachines en AI-crawlers lopen tegen dezelfde muren aan: herhaalde 429's of time-outs laten ze vertragen of de site niet meer crawlen, en geweigerde pagina's worden niet gelezen. We hebben ze uit de paginacontroles gelaten, dus dit is de enige plek waar ze verschijnen.",
     "fix": "Pas de oplossing aan op wat de pagina deed. 429: lever deze pagina's uit een cache of een statisch resultaat en verhoog de limiet voor crawlers; houd Retry-After kort. 401, 403 of een controlepagina: sta CitedBot toe in de firewallregel die hem blokkeert; de bottest in dit rapport laat zien welke crawlers erdoor komen. Geen antwoord: zoek de route die bij het eerste verzoek een live resultaat berekent en lever in plaats daarvan een opgeslagen resultaat of een formulier. Krijgen geverifieerde Googlebot en OAI-SearchBot op deze pagina's een 200 en wordt alleen onze crawler geweigerd, dan is de muur een regel tegen onbekende bots en kun je hem laten staan."
    },
    "de": {
     "title": "Seiten verweigern unseren Crawler oder antworten nicht",
     "why": "Einige Seiten der Website antworteten mit 429 (zu viele Anfragen), wiesen den Crawler ab (401, 403 oder eine Prüfseite) oder antworteten beim zweiten Versuch nicht rechtzeitig. Suchmaschinen und KI-Crawler stoßen auf dieselben Mauern: wiederholte 429 oder Zeitüberschreitungen lassen sie langsamer werden oder das Crawlen der Website einstellen, und abgewiesene Seiten werden nicht gelesen. Wir haben sie aus den Seitenprüfungen herausgenommen, daher erscheinen sie nur hier.",
     "fix": "Passen Sie die Lösung an das an, was die Seite getan hat. 429: Liefern Sie die Seiten aus einem Cache oder einem statischen Ergebnis aus und erhöhen Sie das Limit für Crawler; halten Sie Retry-After kurz. 401, 403 oder eine Prüfseite: Erlauben Sie CitedBot in der Firewall-Regel, die ihn blockiert; der Bot-Test in diesem Bericht zeigt, welche durchkommen. Keine Antwort: Finden Sie die Route, die bei der ersten Anfrage ein Live-Ergebnis berechnet, und liefern Sie stattdessen ein gespeichertes Ergebnis oder ein Formular. Erhalten verifizierte Googlebot und OAI-SearchBot auf diesen Seiten ein 200 und wird nur unser Crawler abgewiesen, ist die Sperre eine Regel gegen unbekannte Bots, und Sie können sie lassen."
    },
    "es": {
     "title": "Páginas que rechazan a nuestro rastreador o no responden",
     "why": "Algunas páginas del sitio respondieron 429 (demasiadas peticiones), rechazaron al rastreador (401, 403 o una página de verificación) o no respondieron a tiempo en un segundo intento. Los buscadores y los rastreadores de IA se topan con los mismos muros: 429 o tiempos de espera repetidos les hacen ir más despacio o dejar de rastrear el sitio, y las páginas rechazadas no se leen. Las dejamos fuera de las comprobaciones de página, así que este es el único sitio donde aparecen.",
     "fix": "Ajusta la solución a lo que hizo la página. 429: sirve esas páginas desde una caché o un resultado estático y sube el límite de peticiones para rastreadores; mantén Retry-After corto. 401, 403 o una página de verificación: permite a CitedBot en la regla del cortafuegos que lo bloquea; la prueba de bots de este informe muestra cuáles pasan. Sin respuesta: busca la ruta que calcula un resultado en vivo en la primera solicitud y sirve en su lugar un resultado guardado o un formulario. Si Googlebot y OAI-SearchBot verificados reciben un 200 en estas páginas y solo se rechaza a nuestro rastreador, el muro es una regla contra bots desconocidos, y puedes dejarlo."
    }
   }
  },
  {
   "check": "llms_txt_conflicts",
   "section": "access",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "llms.txt points at pages that crawlers cannot use",
     "why": "The addresses in llms.txt are the pages you tell assistants to read. Some of them are noindex, blocked by robots.txt, redirect, answer an error, or no page links to them, so the map contradicts the site.",
     "fix": "Remove those addresses from llms.txt, or fix the page: drop the noindex or the robots rule, link to the final address, and link to it from a page of the site."
    },
    "fr": {
     "title": "llms.txt renvoie vers des pages inutilisables pour les robots",
     "why": "Les adresses de llms.txt sont les pages que vous demandez aux assistants de lire. Certaines sont en noindex, bloquées par robots.txt, redirigées, en erreur, ou aucune page ne les lie : la carte contredit le site.",
     "fix": "Retirez ces adresses de llms.txt, ou corrigez la page : supprimez le noindex ou la règle robots, liez l'adresse finale, et liez-la depuis une page du site."
    },
    "nl": {
     "title": "llms.txt wijst naar pagina's die crawlers niet kunnen gebruiken",
     "why": "De adressen in llms.txt zijn de pagina's die je assistenten laat lezen. Sommige zijn noindex, geblokkeerd door robots.txt, verwijzen door, geven een fout, of er linkt geen pagina naar: de kaart spreekt de site tegen.",
     "fix": "Haal die adressen uit llms.txt, of repareer de pagina: verwijder de noindex of de robots-regel, link naar het eindadres en link ernaar vanaf een pagina van de site."
    },
    "de": {
     "title": "llms.txt verweist auf Seiten, die Crawler nicht nutzen können",
     "why": "Die Adressen in llms.txt sind die Seiten, die Sie Assistenten zum Lesen empfehlen. Einige sind noindex, durch robots.txt gesperrt, leiten weiter, liefern einen Fehler oder keine Seite verlinkt sie: Die Karte widerspricht der Website.",
     "fix": "Entfernen Sie diese Adressen aus llms.txt oder korrigieren Sie die Seite: noindex oder robots-Regel entfernen, auf die Zieladresse verlinken und von einer Seite der Website aus verlinken."
    },
    "es": {
     "title": "llms.txt apunta a páginas que los rastreadores no pueden usar",
     "why": "Las direcciones de llms.txt son las páginas que pides a los asistentes que lean. Algunas son noindex, están bloqueadas por robots.txt, redirigen, dan un error, o ninguna página enlaza a ellas: el mapa contradice al sitio.",
     "fix": "Quita esas direcciones de llms.txt, o corrige la página: elimina el noindex o la regla de robots, enlaza a la dirección final y enlaza a ella desde una página del sitio."
    }
   }
  },
  {
   "check": "author_anonymous",
   "section": "structure",
   "severity": "notice",
   "added_version": 8,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Article has no named author",
     "why": "The article markup names no author, or names the organization or an \"editorial team\". Assistants and search engines weigh who wrote a page, most of all on health, money, legal and exam advice, and an unsigned page has no person to trust or cite.",
     "fix": "Name the person who wrote or reviewed it: add a byline and an author of type Person (name, and a profile or sameAs link) to the Article JSON-LD."
    },
    "fr": {
     "title": "L'article n'a pas d'auteur nommé",
     "why": "Le balisage de l'article ne nomme aucun auteur, ou nomme l'organisation ou une « équipe éditoriale ». Les assistants et les moteurs pèsent qui a écrit une page, surtout pour les conseils santé, argent, droit et examens, et une page non signée n'a personne à qui faire confiance ou à citer.",
     "fix": "Nommez la personne qui l'a rédigé ou relu : ajoutez une signature et un auteur de type Person (nom, et un profil ou un lien sameAs) au JSON-LD de l'Article."
    },
    "nl": {
     "title": "Artikel heeft geen genoemde auteur",
     "why": "De artikelmarkup noemt geen auteur, of noemt de organisatie of een \"redactie\". Assistenten en zoekmachines wegen wie een pagina schreef, vooral bij gezondheids-, geld-, juridisch en examenadvies, en een ongetekende pagina heeft geen persoon om te vertrouwen of te citeren.",
     "fix": "Noem de persoon die het schreef of nakeek: voeg een byline en een auteur van het type Person (naam, en een profiel- of sameAs-link) toe aan de Article-JSON-LD."
    },
    "de": {
     "title": "Artikel ohne genannten Autor",
     "why": "Das Artikel-Markup nennt keinen Autor oder nennt die Organisation oder ein „Redaktionsteam“. Assistenten und Suchmaschinen gewichten, wer eine Seite geschrieben hat, besonders bei Gesundheits-, Geld-, Rechts- und Prüfungsratgebern, und eine ungezeichnete Seite hat keine Person, der man vertrauen oder die man zitieren kann.",
     "fix": "Nennen Sie die Person, die den Text geschrieben oder geprüft hat: Fügen Sie dem Article-JSON-LD eine Autorenzeile und einen Autor vom Typ Person (Name sowie ein Profil- oder sameAs-Link) hinzu."
    },
    "es": {
     "title": "El artículo no tiene autor nombrado",
     "why": "El marcado del artículo no nombra a ningún autor, o nombra a la organización o a un «equipo editorial». Los asistentes y los buscadores valoran quién escribió una página, sobre todo en consejos de salud, dinero, derecho y exámenes, y una página sin firma no tiene a nadie de quien fiarse ni a quien citar.",
     "fix": "Nombra a la persona que lo escribió o revisó: añade una firma y un autor de tipo Person (nombre y un perfil o enlace sameAs) al JSON-LD del Article."
    }
   }
  },
  {
   "check": "entity_sameas_missing",
   "section": "structure",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Organization lists no profile outside your own site",
     "why": "sameAs is how engines and assistants tie your site to the same business elsewhere (LinkedIn, Wikipedia or Wikidata, Crunchbase, social profiles). With none, or only your own pages, nothing outside confirms who you are, and a namesake can be mistaken for you.",
     "fix": "Add the real profiles your business already has to sameAs in the home page's Organization JSON-LD, and keep them current. Do not list profiles you do not control."
    },
    "fr": {
     "title": "L'organisation ne liste aucun profil hors de votre site",
     "why": "sameAs relie votre site à la même entreprise ailleurs (LinkedIn, Wikipédia ou Wikidata, Crunchbase, réseaux sociaux). Sans cela, ou avec seulement vos propres pages, rien d'extérieur ne confirme qui vous êtes, et un homonyme peut être pris pour vous.",
     "fix": "Ajoutez à sameAs, dans le JSON-LD Organization de la page d'accueil, les vrais profils que votre entreprise possède déjà, et tenez-les à jour. Ne listez pas de profils que vous ne contrôlez pas."
    },
    "nl": {
     "title": "Organisatie noemt geen profiel buiten uw eigen site",
     "why": "sameAs koppelt uw site aan hetzelfde bedrijf elders (LinkedIn, Wikipedia of Wikidata, Crunchbase, socialemediaprofielen). Zonder, of met alleen uw eigen pagina's, bevestigt niets van buiten wie u bent, en een naamgenoot kan voor u worden aangezien.",
     "fix": "Voeg de echte profielen die uw bedrijf al heeft toe aan sameAs in de Organization-JSON-LD van de homepage, en houd ze actueel. Noem geen profielen die u niet beheert."
    },
    "de": {
     "title": "Die Organisation nennt kein Profil außerhalb Ihrer Website",
     "why": "sameAs verbindet Ihre Website mit demselben Unternehmen anderswo (LinkedIn, Wikipedia oder Wikidata, Crunchbase, Social-Media-Profile). Ohne oder mit nur Ihren eigenen Seiten bestätigt nichts von außen, wer Sie sind, und ein Namensvetter kann mit Ihnen verwechselt werden.",
     "fix": "Tragen Sie die echten Profile, die Ihr Unternehmen schon hat, in sameAs im Organization-JSON-LD der Startseite ein und halten Sie sie aktuell. Nennen Sie keine Profile, die Sie nicht kontrollieren."
    },
    "es": {
     "title": "La organización no lista ningún perfil fuera de tu sitio",
     "why": "sameAs vincula tu sitio con la misma empresa en otros lugares (LinkedIn, Wikipedia o Wikidata, Crunchbase, redes sociales). Sin él, o solo con tus propias páginas, nada externo confirma quién eres, y un homónimo puede confundirse contigo.",
     "fix": "Añade a sameAs, en el JSON-LD Organization de la página de inicio, los perfiles reales que tu empresa ya tiene, y mantenlos al día. No listes perfiles que no controlas."
    }
   }
  },
  {
   "check": "js_changes_page",
   "section": "render",
   "severity": "warning",
   "added_version": 9,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Scripts change or remove what the page says",
     "why": "A crawler reads the HTML the server sends. In a browser, scripts then rewrite the address, change the title, or remove the article and its links. Search engines that render the page index something different from what AI crawlers (which do not run scripts) read, and a page whose address becomes a /#/ route has no address of its own.",
     "fix": "Make the server send the final page: the real address, title, H1, text and links in the HTML. Use scripts to add behaviour, not to replace the page, and do not rewrite the address or title."
    },
    "fr": {
     "title": "Des scripts modifient ou suppriment ce que dit la page",
     "why": "Un robot lit le HTML envoyé par le serveur. Dans un navigateur, des scripts réécrivent ensuite l'adresse, changent le titre, ou suppriment l'article et ses liens. Les moteurs qui exécutent la page indexent autre chose que ce que lisent les robots d'IA (qui n'exécutent pas les scripts), et une page dont l'adresse devient une route /#/ n'a pas d'adresse propre.",
     "fix": "Faites envoyer la page finale par le serveur : la vraie adresse, le titre, le H1, le texte et les liens dans le HTML. Utilisez les scripts pour ajouter du comportement, pas pour remplacer la page, et ne réécrivez ni l'adresse ni le titre."
    },
    "nl": {
     "title": "Scripts wijzigen of verwijderen wat de pagina zegt",
     "why": "Een crawler leest de HTML die de server stuurt. In een browser herschrijven scripts daarna het adres, wijzigen de titel, of verwijderen het artikel en zijn links. Zoekmachines die de pagina renderen indexeren iets anders dan wat AI-crawlers (die geen scripts uitvoeren) lezen, en een pagina waarvan het adres een /#/-route wordt heeft geen eigen adres.",
     "fix": "Laat de server de definitieve pagina sturen: het echte adres, de titel, H1, tekst en links in de HTML. Gebruik scripts om gedrag toe te voegen, niet om de pagina te vervangen, en herschrijf het adres of de titel niet."
    },
    "de": {
     "title": "Skripte ändern oder entfernen, was die Seite sagt",
     "why": "Ein Crawler liest das HTML, das der Server sendet. Im Browser schreiben Skripte dann die Adresse um, ändern den Titel oder entfernen den Artikel und seine Links. Suchmaschinen, die die Seite rendern, indexieren etwas anderes als das, was KI-Crawler (die keine Skripte ausführen) lesen, und eine Seite, deren Adresse zu einer /#/-Route wird, hat keine eigene Adresse.",
     "fix": "Lassen Sie den Server die fertige Seite senden: die echte Adresse, Titel, H1, Text und Links im HTML. Nutzen Sie Skripte für Verhalten, nicht um die Seite zu ersetzen, und schreiben Sie weder Adresse noch Titel um."
    },
    "es": {
     "title": "Los scripts cambian o quitan lo que dice la página",
     "why": "Un rastreador lee el HTML que envía el servidor. En un navegador, los scripts reescriben después la dirección, cambian el título o quitan el artículo y sus enlaces. Los buscadores que renderizan la página indexan algo distinto de lo que leen los rastreadores de IA (que no ejecutan scripts), y una página cuya dirección pasa a ser una ruta /#/ no tiene dirección propia.",
     "fix": "Haz que el servidor envíe la página final: la dirección real, el título, el H1, el texto y los enlaces en el HTML. Usa los scripts para añadir comportamiento, no para sustituir la página, y no reescribas la dirección ni el título."
    }
   }
  },
  {
   "check": "js_only_prices",
   "section": "render",
   "severity": "warning",
   "added_version": 9,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Prices appear only after scripts run",
     "why": "The page shows prices in a browser, but the HTML a crawler gets contains none. AI crawlers do not run scripts, so assistants cannot quote what it costs and may guess or name a rival.",
     "fix": "Put the prices in the server-sent HTML (and Offer markup), and let scripts only update them."
    },
    "fr": {
     "title": "Les prix n'apparaissent qu'après l'exécution des scripts",
     "why": "La page affiche des prix dans un navigateur, mais le HTML reçu par un robot n'en contient aucun. Les robots d'IA n'exécutent pas les scripts : les assistants ne peuvent pas citer ce que ça coûte et peuvent deviner ou citer un concurrent.",
     "fix": "Mettez les prix dans le HTML envoyé par le serveur (et dans le balisage Offer), et laissez les scripts seulement les mettre à jour."
    },
    "nl": {
     "title": "Prijzen verschijnen pas nadat scripts draaien",
     "why": "De pagina toont prijzen in een browser, maar de HTML die een crawler krijgt bevat er geen. AI-crawlers voeren geen scripts uit, dus assistenten kunnen niet citeren wat het kost en gaan gissen of noemen een concurrent.",
     "fix": "Zet de prijzen in de door de server gestuurde HTML (en Offer-markup) en laat scripts ze alleen bijwerken."
    },
    "de": {
     "title": "Preise erscheinen erst, nachdem Skripte laufen",
     "why": "Die Seite zeigt im Browser Preise, aber das HTML, das ein Crawler erhält, enthält keine. KI-Crawler führen keine Skripte aus, Assistenten können also nicht zitieren, was es kostet, und raten oder nennen einen Mitbewerber.",
     "fix": "Legen Sie die Preise in das vom Server gesendete HTML (und das Offer-Markup) und lassen Sie Skripte sie nur aktualisieren."
    },
    "es": {
     "title": "Los precios solo aparecen cuando se ejecutan los scripts",
     "why": "La página muestra precios en un navegador, pero el HTML que recibe un rastreador no contiene ninguno. Los rastreadores de IA no ejecutan scripts, así que los asistentes no pueden citar cuánto cuesta y pueden adivinar o nombrar a un rival.",
     "fix": "Pon los precios en el HTML que envía el servidor (y en el marcado Offer) y deja que los scripts solo los actualicen."
    }
   }
  },
  {
   "check": "link_wrong_language",
   "section": "technical",
   "severity": "warning",
   "added_version": 9,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Links send readers to a page in another language",
     "why": "Pages in one language link to a page that is only in another (an English page linking the Spanish price page). Visitors land on text they cannot read, and the link tells engines that page is the one for this language.",
     "fix": "Link to this language's own version of the page; if there is none, publish it, or link to the language switcher instead."
    },
    "fr": {
     "title": "Des liens envoient les lecteurs vers une page dans une autre langue",
     "why": "Des pages d'une langue renvoient vers une page qui n'existe que dans une autre (une page anglaise qui lie la page de prix espagnole). Les visiteurs arrivent sur un texte qu'ils ne lisent pas, et le lien dit aux moteurs que cette page est celle de cette langue.",
     "fix": "Liez vers la version de la page dans cette langue ; s'il n'y en a pas, publiez-la, ou liez vers le sélecteur de langue."
    },
    "nl": {
     "title": "Links sturen lezers naar een pagina in een andere taal",
     "why": "Pagina's in de ene taal linken naar een pagina die alleen in een andere taal bestaat (een Engelse pagina die naar de Spaanse prijspagina linkt). Bezoekers belanden op tekst die ze niet kunnen lezen, en de link zegt zoekmachines dat die pagina die voor deze taal is.",
     "fix": "Link naar de eigen versie van de pagina in deze taal; bestaat die niet, publiceer hem dan, of link naar de taalkeuze."
    },
    "de": {
     "title": "Links führen Leser auf eine Seite in einer anderen Sprache",
     "why": "Seiten in einer Sprache verlinken auf eine Seite, die es nur in einer anderen gibt (eine englische Seite verlinkt die spanische Preisseite). Besucher landen auf Text, den sie nicht lesen können, und der Link sagt Suchmaschinen, dass diese Seite die für diese Sprache ist.",
     "fix": "Verlinken Sie auf die Version der Seite in dieser Sprache; gibt es keine, veröffentlichen Sie sie oder verlinken Sie auf die Sprachauswahl."
    },
    "es": {
     "title": "Enlaces que llevan a los lectores a una página en otro idioma",
     "why": "Páginas en un idioma enlazan a una página que solo existe en otro (una página en inglés que enlaza la página de precios en español). Los visitantes llegan a un texto que no leen, y el enlace dice a los buscadores que esa página es la de este idioma.",
     "fix": "Enlaza a la versión de la página en este idioma; si no existe, publícala, o enlaza al selector de idioma."
    }
   }
  },
  {
   "check": "hreflang_x_default_missing",
   "section": "technical",
   "severity": "notice",
   "added_version": 9,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "hreflang has no x-default",
     "why": "A page that lists language versions but no x-default leaves engines without a fallback for visitors whose language you do not serve, so they may be sent to the wrong version.",
     "fix": "Add hreflang=\"x-default\" to the version that should serve everyone else, usually the language chooser or the main language."
    },
    "fr": {
     "title": "hreflang n'a pas de x-default",
     "why": "Une page qui liste des versions linguistiques sans x-default laisse les moteurs sans solution de repli pour les visiteurs dont vous ne servez pas la langue : ils risquent d'être envoyés vers la mauvaise version.",
     "fix": "Ajoutez hreflang=\"x-default\" à la version qui doit servir tous les autres, en général le sélecteur de langue ou la langue principale."
    },
    "nl": {
     "title": "hreflang heeft geen x-default",
     "why": "Een pagina die taalversies noemt maar geen x-default laat zoekmachines zonder terugvaloptie voor bezoekers wier taal u niet bedient, zodat ze naar de verkeerde versie kunnen worden gestuurd.",
     "fix": "Voeg hreflang=\"x-default\" toe aan de versie die alle anderen moet bedienen, meestal de taalkeuze of de hoofdtaal."
    },
    "de": {
     "title": "hreflang hat kein x-default",
     "why": "Eine Seite, die Sprachversionen nennt, aber kein x-default, lässt Suchmaschinen ohne Ausweichziel für Besucher, deren Sprache Sie nicht bedienen, sodass sie auf die falsche Version geleitet werden können.",
     "fix": "Fügen Sie hreflang=\"x-default\" bei der Version ein, die alle anderen bedienen soll, meist die Sprachauswahl oder die Hauptsprache."
    },
    "es": {
     "title": "hreflang no tiene x-default",
     "why": "Una página que lista versiones de idioma pero no x-default deja a los buscadores sin alternativa para los visitantes cuyo idioma no sirves, así que pueden enviarlos a la versión equivocada.",
     "fix": "Añade hreflang=\"x-default\" a la versión que debe servir a todos los demás, normalmente el selector de idioma o el idioma principal."
    }
   }
  },
  {
   "check": "public_not_cacheable",
   "section": "technical",
   "severity": "notice",
   "added_version": 9,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Public page cannot be cached",
     "why": "The page is open to everyone but is sent with Cache-Control private or no-store (or sets a cookie), so a CDN cannot serve it from cache. Every visit, and every crawler request, hits your server, and cold pages answer slowly.",
     "fix": "Send Cache-Control: public with a max-age (and s-maxage for a CDN) on pages that are the same for everyone, and keep cookies off them."
    },
    "fr": {
     "title": "Une page publique ne peut pas être mise en cache",
     "why": "La page est ouverte à tous mais envoyée avec Cache-Control private ou no-store (ou pose un cookie) : un CDN ne peut pas la servir depuis son cache. Chaque visite, et chaque requête de robot, atteint votre serveur, et les pages à froid répondent lentement.",
     "fix": "Envoyez Cache-Control: public avec un max-age (et s-maxage pour un CDN) sur les pages identiques pour tous, et sans cookie."
    },
    "nl": {
     "title": "Openbare pagina kan niet worden gecachet",
     "why": "De pagina is voor iedereen open maar wordt verstuurd met Cache-Control private of no-store (of zet een cookie), zodat een CDN haar niet uit de cache kan leveren. Elk bezoek en elk crawlerverzoek raakt uw server, en koude pagina's antwoorden traag.",
     "fix": "Stuur Cache-Control: public met een max-age (en s-maxage voor een CDN) op pagina's die voor iedereen gelijk zijn, en houd er cookies van af."
    },
    "de": {
     "title": "Öffentliche Seite kann nicht gecacht werden",
     "why": "Die Seite ist für alle offen, wird aber mit Cache-Control private oder no-store gesendet (oder setzt ein Cookie), sodass ein CDN sie nicht aus dem Cache ausliefern kann. Jeder Besuch und jede Crawler-Anfrage trifft Ihren Server, und kalte Seiten antworten langsam.",
     "fix": "Senden Sie Cache-Control: public mit einem max-age (und s-maxage für ein CDN) bei Seiten, die für alle gleich sind, und lassen Sie Cookies weg."
    },
    "es": {
     "title": "Una página pública no se puede cachear",
     "why": "La página está abierta a todos pero se envía con Cache-Control private o no-store (o pone una cookie), así que un CDN no puede servirla desde la caché. Cada visita y cada petición de un rastreador llega a tu servidor, y las páginas en frío responden despacio.",
     "fix": "Envía Cache-Control: public con un max-age (y s-maxage para un CDN) en las páginas iguales para todos, y sin cookies."
    }
   }
  },
  {
   "check": "lang_mismatch",
   "section": "structure",
   "severity": "notice",
   "added_version": 9,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Declared language differs from the text",
     "why": "The page says it is in one language (html lang) but most of its text is in another, so engines and assistants may file it under the wrong language and show it to the wrong readers.",
     "fix": "Translate the page or correct html lang and the hreflang entry to the language the text is really in."
    },
    "fr": {
     "title": "La langue déclarée diffère du texte",
     "why": "La page se dit dans une langue (html lang) mais la plupart de son texte est dans une autre : moteurs et assistants peuvent la classer dans la mauvaise langue et la montrer aux mauvais lecteurs.",
     "fix": "Traduisez la page, ou corrigez html lang et l'entrée hreflang pour la langue réelle du texte."
    },
    "nl": {
     "title": "Opgegeven taal wijkt af van de tekst",
     "why": "De pagina zegt in één taal te zijn (html lang) maar het grootste deel van de tekst is in een andere, zodat zoekmachines en assistenten haar onder de verkeerde taal kunnen indelen en aan de verkeerde lezers tonen.",
     "fix": "Vertaal de pagina of corrigeer html lang en de hreflang-vermelding naar de taal waarin de tekst echt is."
    },
    "de": {
     "title": "Angegebene Sprache weicht vom Text ab",
     "why": "Die Seite gibt eine Sprache an (html lang), aber der Großteil des Textes ist in einer anderen, sodass Suchmaschinen und Assistenten sie in die falsche Sprache einordnen und den falschen Lesern zeigen können.",
     "fix": "Übersetzen Sie die Seite oder korrigieren Sie html lang und den hreflang-Eintrag auf die Sprache, in der der Text wirklich ist."
    },
    "es": {
     "title": "El idioma declarado difiere del texto",
     "why": "La página dice estar en un idioma (html lang) pero la mayor parte de su texto está en otro, así que buscadores y asistentes pueden clasificarla en el idioma equivocado y mostrarla a los lectores equivocados.",
     "fix": "Traduce la página o corrige html lang y la entrada hreflang al idioma en que realmente está el texto."
    }
   }
  },
  {
   "check": "url_variants_404",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Address variants of real pages return 404",
     "why": "A real page answers 200, but the same address with or without the trailing slash, or in another letter case, answers 404. Links written that way, and crawlers that normalise addresses, hit an error page.",
     "fix": "Redirect each variant to the canonical address with a 301, or serve the same page on both."
    },
    "fr": {
     "title": "Des variantes d'adresse de vraies pages renvoient 404",
     "why": "Une vraie page répond 200, mais la même adresse avec ou sans barre oblique finale, ou dans une autre casse, répond 404. Les liens écrits ainsi, et les robots qui normalisent les adresses, tombent sur une page d'erreur.",
     "fix": "Redirigez chaque variante vers l'adresse canonique par une 301, ou servez la même page sur les deux."
    },
    "nl": {
     "title": "Adresvarianten van echte pagina's geven 404",
     "why": "Een echte pagina geeft 200, maar hetzelfde adres met of zonder slash aan het eind, of in een andere hoofdletterstand, geeft 404. Links die zo zijn geschreven, en crawlers die adressen normaliseren, komen op een foutpagina.",
     "fix": "Leid elke variant met een 301 door naar het canonieke adres, of lever dezelfde pagina op beide."
    },
    "de": {
     "title": "Adressvarianten echter Seiten liefern 404",
     "why": "Eine echte Seite antwortet mit 200, aber dieselbe Adresse mit oder ohne abschließenden Schrägstrich oder in anderer Groß- und Kleinschreibung antwortet mit 404. So geschriebene Links und Crawler, die Adressen normalisieren, landen auf einer Fehlerseite.",
     "fix": "Leiten Sie jede Variante per 301 auf die kanonische Adresse um oder liefern Sie dieselbe Seite unter beiden aus."
    },
    "es": {
     "title": "Variantes de dirección de páginas reales devuelven 404",
     "why": "Una página real responde 200, pero la misma dirección con o sin barra final, o con otra capitalización, responde 404. Los enlaces escritos así, y los rastreadores que normalizan direcciones, llegan a una página de error.",
     "fix": "Redirige cada variante a la dirección canónica con una 301, o sirve la misma página en ambas."
    }
   }
  },
  {
   "check": "locale_adaptive_home",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "The home address changes language with the visitor's browser",
     "why": "The same address answers in different languages depending on Accept-Language and does not redirect. Crawlers send no language, so they see one version, and engines index a language that may not be the one a person was meant to get.",
     "fix": "Serve each language at its own address (/fr/, /es/) and, at most, redirect from / to it once; give / one language."
    },
    "fr": {
     "title": "L'adresse d'accueil change de langue selon le navigateur du visiteur",
     "why": "La même adresse répond dans des langues différentes selon Accept-Language, sans redirection. Les robots n'envoient aucune langue : ils voient une version, et les moteurs indexent une langue qui n'est peut-être pas celle qu'une personne devait recevoir.",
     "fix": "Servez chaque langue à sa propre adresse (/fr/, /es/) et, au plus, redirigez une fois de / vers elle ; donnez à / une seule langue."
    },
    "nl": {
     "title": "Het hoofdadres wisselt van taal met de browser van de bezoeker",
     "why": "Hetzelfde adres antwoordt in verschillende talen afhankelijk van Accept-Language, zonder door te verwijzen. Crawlers sturen geen taal, zien dus één versie, en zoekmachines indexeren een taal die misschien niet de bedoelde is.",
     "fix": "Lever elke taal op een eigen adres (/fr/, /es/) en verwijs hooguit eenmaal door van / ernaartoe; geef / één taal."
    },
    "de": {
     "title": "Die Startadresse wechselt die Sprache mit dem Browser des Besuchers",
     "why": "Dieselbe Adresse antwortet je nach Accept-Language in verschiedenen Sprachen und leitet nicht um. Crawler senden keine Sprache, sehen also eine Version, und Suchmaschinen indexieren eine Sprache, die vielleicht nicht die gemeinte ist.",
     "fix": "Liefern Sie jede Sprache unter einer eigenen Adresse (/fr/, /es/) und leiten Sie höchstens einmal von / dorthin um; geben Sie / eine Sprache."
    },
    "es": {
     "title": "La dirección de inicio cambia de idioma según el navegador del visitante",
     "why": "La misma dirección responde en idiomas distintos según Accept-Language y no redirige. Los rastreadores no envían idioma, así que ven una versión, y los buscadores indexan un idioma que quizá no sea el que debía recibir una persona.",
     "fix": "Sirve cada idioma en su propia dirección (/fr/, /es/) y, como mucho, redirige una vez de / a ella; da a / un solo idioma."
    }
   }
  },
  {
   "check": "lead_buried",
   "section": "render",
   "severity": "notice",
   "added_version": 10,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "The page opens with source and date lines",
     "why": "The first lines a reader, a search snippet and an assistant see are sources, dates or a byline, and the first sentence that says anything comes after them. Assistants lift the opening of a page as its answer, so they quote the housekeeping.",
     "fix": "Open with the answer in one or two sentences, then put sources, dates and the reviewer below it or in a footnote."
    },
    "fr": {
     "title": "La page s'ouvre sur des lignes de sources et de dates",
     "why": "Les premières lignes que voient un lecteur, un extrait de recherche et un assistant sont des sources, des dates ou une signature, et la première phrase qui dit quelque chose vient après. Les assistants reprennent l'ouverture d'une page comme sa réponse : ils citent l'intendance.",
     "fix": "Ouvrez par la réponse en une ou deux phrases, puis placez sources, dates et relecteur en dessous ou en note."
    },
    "nl": {
     "title": "De pagina opent met bron- en datumregels",
     "why": "De eerste regels die een lezer, een zoekfragment en een assistent zien zijn bronnen, data of een auteursregel, en de eerste zin die iets zegt komt erna. Assistenten nemen de opening van een pagina als haar antwoord over, dus ze citeren de randzaken.",
     "fix": "Open met het antwoord in een of twee zinnen en zet bronnen, data en de nakijker eronder of in een voetnoot."
    },
    "de": {
     "title": "Die Seite beginnt mit Quellen- und Datumszeilen",
     "why": "Die ersten Zeilen, die ein Leser, ein Suchauszug und ein Assistent sehen, sind Quellen, Daten oder eine Autorenzeile, und der erste Satz, der etwas sagt, kommt danach. Assistenten übernehmen den Anfang einer Seite als ihre Antwort und zitieren so das Beiwerk.",
     "fix": "Beginnen Sie mit der Antwort in ein oder zwei Sätzen und setzen Sie Quellen, Daten und Prüfer darunter oder in eine Fußnote."
    },
    "es": {
     "title": "La página empieza con líneas de fuentes y fechas",
     "why": "Las primeras líneas que ven un lector, un fragmento de búsqueda y un asistente son fuentes, fechas o una firma, y la primera frase que dice algo viene después. Los asistentes toman el comienzo de una página como su respuesta, así que citan lo accesorio.",
     "fix": "Empieza con la respuesta en una o dos frases y pon fuentes, fechas y revisor debajo o en una nota."
    }
   }
  },
  {
   "check": "internal_redirect_link",
   "section": "technical",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Internal links point to redirects",
     "why": "Each redirect costs crawlers a request and slows visitors.",
     "fix": "Update the links to point straight at the final URL."
    },
    "fr": {
     "title": "Des liens internes pointent vers des redirections",
     "why": "Chaque redirection coûte une requête aux robots et ralentit les visiteurs.",
     "fix": "Mettez les liens à jour pour qu'ils pointent directement vers l'URL finale."
    },
    "nl": {
     "title": "Interne links verwijzen naar redirects",
     "why": "Elke redirect kost crawlers een verzoek en vertraagt bezoekers.",
     "fix": "Pas de links aan zodat ze rechtstreeks naar de eind-URL verwijzen."
    },
    "de": {
     "title": "Interne Links zeigen auf Weiterleitungen",
     "why": "Jede Weiterleitung kostet Crawler eine Anfrage und verlangsamt Besucher.",
     "fix": "Aktualisieren Sie die Links, sodass sie direkt auf die finale URL zeigen."
    },
    "es": {
     "title": "Enlaces internos que apuntan a redirecciones",
     "why": "Cada redirección cuesta una petición a los crawlers y ralentiza a los visitantes.",
     "fix": "Actualiza los enlaces para que apunten directamente a la URL final."
    }
   }
  },
  {
   "check": "content_duplicate",
   "section": "render",
   "severity": "warning",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Duplicate or near-duplicate content",
     "why": "Pages with the same main text compete with each other; search engines and assistants pick one and ignore the rest.",
     "fix": "Merge the pages, make each one distinct, or point duplicates to the main page with a canonical."
    },
    "fr": {
     "title": "Contenu dupliqué ou quasi dupliqué",
     "why": "Les pages ayant le même texte principal se concurrencent ; les moteurs de recherche et les assistants en choisissent une et ignorent les autres.",
     "fix": "Fusionnez les pages, différenciez-les, ou faites pointer les doublons vers la page principale avec une canonical."
    },
    "nl": {
     "title": "Dubbele of bijna dubbele content",
     "why": "Pagina's met dezelfde hoofdtekst concurreren met elkaar; zoekmachines en assistenten kiezen er één en negeren de rest.",
     "fix": "Voeg de pagina's samen, maak ze elk uniek, of verwijs duplicaten met een canonical naar de hoofdpagina."
    },
    "de": {
     "title": "Doppelter oder nahezu doppelter Inhalt",
     "why": "Seiten mit demselben Haupttext konkurrieren miteinander. Suchmaschinen und Assistenten wählen eine aus und ignorieren den Rest.",
     "fix": "Führen Sie die Seiten zusammen, machen Sie jede eigenständig oder verweisen Sie Duplikate per Canonical auf die Hauptseite."
    },
    "es": {
     "title": "Contenido duplicado o casi duplicado",
     "why": "Las páginas con el mismo texto principal compiten entre sí; los buscadores y los asistentes eligen una e ignoran el resto.",
     "fix": "Fusiona las páginas, diferencia cada una o apunta los duplicados a la página principal con un canonical."
    }
   }
  },
  {
   "check": "deep_page",
   "section": "technical",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Page is more than 3 clicks from the home page",
     "why": "Pages deep in the click path are crawled less often and look less important.",
     "fix": "Link to the page from a hub, category or the navigation so it is at most 3 clicks from home."
    },
    "fr": {
     "title": "La page est à plus de 3 clics de la page d'accueil",
     "why": "Les pages profondes dans l'arborescence sont explorées moins souvent et paraissent moins importantes.",
     "fix": "Ajoutez un lien vers la page depuis un hub, une catégorie ou la navigation, pour qu'elle soit à 3 clics maximum de l'accueil."
    },
    "nl": {
     "title": "Pagina staat meer dan 3 klikken van de homepage",
     "why": "Pagina's diep in het klikpad worden minder vaak gecrawld en lijken minder belangrijk.",
     "fix": "Link naar de pagina vanaf een hub, categorie of het menu, zodat hij hooguit 3 klikken van de homepage staat."
    },
    "de": {
     "title": "Seite ist mehr als 3 Klicks von der Startseite entfernt",
     "why": "Seiten tief im Klickpfad werden seltener gecrawlt und wirken weniger wichtig.",
     "fix": "Verlinken Sie die Seite von einer Übersichtsseite, Kategorie oder der Navigation, sodass sie höchstens 3 Klicks von der Startseite entfernt ist."
    },
    "es": {
     "title": "La página está a más de 3 clics de la página de inicio",
     "why": "Las páginas enterradas en la ruta de clics se rastrean con menos frecuencia y parecen menos importantes.",
     "fix": "Enlaza la página desde un hub, una categoría o el menú de navegación para que esté como máximo a 3 clics del inicio."
    }
   }
  },
  {
   "check": "dead_end",
   "section": "technical",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Page has no internal links (dead end)",
     "why": "A page with no links to the rest of the site stops crawlers and visitors.",
     "fix": "Add links to related pages, the category and the home page."
    },
    "fr": {
     "title": "La page n'a aucun lien interne (impasse)",
     "why": "Une page sans lien vers le reste du site arrête les robots et les visiteurs.",
     "fix": "Ajoutez des liens vers des pages liées, la catégorie et la page d'accueil."
    },
    "nl": {
     "title": "Pagina heeft geen interne links (doodlopend)",
     "why": "Een pagina zonder links naar de rest van de site houdt crawlers en bezoekers tegen.",
     "fix": "Voeg links toe naar gerelateerde pagina's, de categorie en de homepage."
    },
    "de": {
     "title": "Seite hat keine internen Links (Sackgasse)",
     "why": "Eine Seite ohne Links zum Rest der Website hält Crawler und Besucher auf.",
     "fix": "Fügen Sie Links zu verwandten Seiten, zur Kategorie und zur Startseite hinzu."
    },
    "es": {
     "title": "La página no tiene enlaces internos (callejón sin salida)",
     "why": "Una página sin enlaces al resto del sitio detiene a los crawlers y a los visitantes.",
     "fix": "Añade enlaces a páginas relacionadas, a la categoría y a la página de inicio."
    }
   }
  },
  {
   "check": "not_in_sitemap",
   "section": "technical",
   "severity": "notice",
   "added_version": 3,
   "added": "2026-10-19",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Indexable page missing from the sitemap",
     "why": "The sitemap is how you tell crawlers which pages matter; this one is left out.",
     "fix": "Add the page to sitemap.xml (most CMSs do this when the page is published and indexable)."
    },
    "fr": {
     "title": "Page indexable absente du sitemap",
     "why": "Le sitemap indique aux robots quelles pages comptent ; celle-ci en est exclue.",
     "fix": "Ajoutez la page à sitemap.xml (la plupart des CMS le font à la publication d'une page indexable)."
    },
    "nl": {
     "title": "Indexeerbare pagina ontbreekt in de sitemap",
     "why": "Met de sitemap geef je crawlers aan welke pagina's ertoe doen; deze is weggelaten.",
     "fix": "Voeg de pagina toe aan sitemap.xml (de meeste CMS'en doen dit zodra de pagina is gepubliceerd en indexeerbaar is)."
    },
    "de": {
     "title": "Indexierbare Seite fehlt in der Sitemap",
     "why": "Mit der Sitemap sagen Sie Crawlern, welche Seiten wichtig sind. Diese fehlt dort.",
     "fix": "Fügen Sie die Seite zur sitemap.xml hinzu (die meisten CMS tun das, sobald die Seite veröffentlicht und indexierbar ist)."
    },
    "es": {
     "title": "Página indexable que falta en el sitemap",
     "why": "El sitemap es como indicas a los crawlers qué páginas importan; esta se ha dejado fuera.",
     "fix": "Añade la página a sitemap.xml (la mayoría de los CMS lo hacen al publicar una página indexable)."
    }
   }
  },
  {
   "check": "noindex_in_sitemap",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Sitemap lists a page that is not indexable",
     "why": "The sitemap asks crawlers to index a page that says noindex or canonicalises elsewhere: a mixed signal.",
     "fix": "Remove noindex and canonicalised pages from the sitemap."
    },
    "fr": {
     "title": "Le sitemap liste une page non indexable",
     "why": "Le sitemap demande aux robots d'indexer une page en noindex ou dont la canonical pointe ailleurs : un signal contradictoire.",
     "fix": "Retirez du sitemap les pages en noindex et celles dont la canonical pointe ailleurs."
    },
    "nl": {
     "title": "Sitemap bevat een pagina die niet indexeerbaar is",
     "why": "De sitemap vraagt crawlers een pagina te indexeren die noindex zegt of via canonical naar elders verwijst: een tegenstrijdig signaal.",
     "fix": "Verwijder noindex-pagina's en pagina's met een canonical naar elders uit de sitemap."
    },
    "de": {
     "title": "Sitemap enthält eine nicht indexierbare Seite",
     "why": "Die Sitemap bittet Crawler, eine Seite zu indexieren, die noindex trägt oder per Canonical woanders hinzeigt: ein widersprüchliches Signal.",
     "fix": "Entfernen Sie noindex-Seiten und Seiten mit abweichendem Canonical aus der Sitemap."
    },
    "es": {
     "title": "El sitemap incluye una página no indexable",
     "why": "El sitemap pide a los crawlers que indexen una página que dice noindex o que tiene un canonical a otra URL: una señal contradictoria.",
     "fix": "Elimina del sitemap las páginas con noindex y las que tienen canonical a otra URL."
    }
   }
  },
  {
   "check": "http_not_redirected",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "HTTP version does not redirect to HTTPS",
     "why": "http:// still serves the site instead of redirecting, so two copies of every page exist and visitors can land on the insecure one.",
     "fix": "Redirect every http:// URL to its https:// version with a 301."
    },
    "fr": {
     "title": "La version HTTP ne redirige pas vers HTTPS",
     "why": "http:// sert encore le site au lieu de rediriger : deux copies de chaque page existent et les visiteurs peuvent arriver sur la version non sécurisée.",
     "fix": "Redirigez chaque URL http:// vers sa version https:// avec une 301."
    },
    "nl": {
     "title": "HTTP-versie stuurt niet door naar HTTPS",
     "why": "http:// toont de site nog steeds in plaats van door te sturen, dus van elke pagina bestaan twee kopieën en bezoekers kunnen op de onveilige belanden.",
     "fix": "Stuur elke http://-URL met een 301 door naar de https://-versie."
    },
    "de": {
     "title": "HTTP-Version leitet nicht auf HTTPS weiter",
     "why": "http:// liefert die Website weiterhin aus, statt weiterzuleiten. So existieren zwei Kopien jeder Seite, und Besucher können auf der unsicheren landen.",
     "fix": "Leiten Sie jede http://-URL per 301 auf ihre https://-Version weiter."
    },
    "es": {
     "title": "La versión HTTP no redirige a HTTPS",
     "why": "http:// sigue sirviendo el sitio en lugar de redirigir, así que existen dos copias de cada página y los visitantes pueden acabar en la insegura.",
     "fix": "Redirige cada URL http:// a su versión https:// con un 301."
    }
   }
  },
  {
   "check": "www_inconsistent",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "www and non-www both serve the site",
     "why": "example.com and www.example.com both answer 200 without redirecting to one, which splits links and creates duplicates.",
     "fix": "Pick one host and 301-redirect the other to it."
    },
    "fr": {
     "title": "www et non-www servent tous deux le site",
     "why": "example.com et www.example.com répondent tous deux 200 sans rediriger vers l'un des deux, ce qui disperse les liens et crée des doublons.",
     "fix": "Choisissez un seul hôte et redirigez l'autre vers lui avec une 301."
    },
    "nl": {
     "title": "www en non-www tonen allebei de site",
     "why": "example.com en www.example.com geven allebei 200 zonder naar één te redirecten, wat links versnippert en duplicaten veroorzaakt.",
     "fix": "Kies één host en stuur de andere met een 301 door naar die host."
    },
    "de": {
     "title": "www und non-www liefern beide die Website aus",
     "why": "example.com und www.example.com antworten beide mit 200, ohne auf eine Variante weiterzuleiten. Das verteilt Links und erzeugt Duplikate.",
     "fix": "Wählen Sie einen Host und leiten Sie den anderen per 301 darauf weiter."
    },
    "es": {
     "title": "El sitio se sirve tanto con www como sin www",
     "why": "example.com y www.example.com responden 200 sin redirigir a una sola, lo que divide los enlaces y crea duplicados.",
     "fix": "Elige un host y redirige el otro a él con un 301."
    }
   }
  },
  {
   "check": "hsts_missing",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No HSTS header",
     "why": "Strict-Transport-Security makes browsers always use HTTPS, which prevents downgrade attacks.",
     "fix": "Send Strict-Transport-Security: max-age=31536000; includeSubDomains on HTTPS responses."
    },
    "fr": {
     "title": "Pas d'en-tête HSTS",
     "why": "Strict-Transport-Security impose aux navigateurs de toujours utiliser HTTPS, ce qui empêche les attaques par rétrogradation.",
     "fix": "Envoyez Strict-Transport-Security: max-age=31536000; includeSubDomains sur les réponses HTTPS."
    },
    "nl": {
     "title": "Geen HSTS-header",
     "why": "Strict-Transport-Security zorgt dat browsers altijd HTTPS gebruiken, wat downgrade-aanvallen voorkomt.",
     "fix": "Stuur Strict-Transport-Security: max-age=31536000; includeSubDomains mee bij HTTPS-antwoorden."
    },
    "de": {
     "title": "Kein HSTS-Header",
     "why": "Strict-Transport-Security sorgt dafür, dass Browser immer HTTPS nutzen, und verhindert Downgrade-Angriffe.",
     "fix": "Senden Sie Strict-Transport-Security: max-age=31536000; includeSubDomains bei HTTPS-Antworten."
    },
    "es": {
     "title": "Sin cabecera HSTS",
     "why": "Strict-Transport-Security hace que los navegadores usen siempre HTTPS, lo que evita los ataques de degradación.",
     "fix": "Envía Strict-Transport-Security: max-age=31536000; includeSubDomains en las respuestas HTTPS."
    }
   }
  },
  {
   "check": "security_headers_missing",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": null,
   "headers": [
    "Strict-Transport-Security: max-age=31536000; includeSubDomains",
    "Content-Security-Policy: frame-ancestors 'self'",
    "X-Content-Type-Options: nosniff",
    "X-Frame-Options: SAMEORIGIN",
    "Referrer-Policy: strict-origin-when-cross-origin",
    "Permissions-Policy: camera=(), microphone=(), geolocation=()"
   ],
   "text": {
    "en": {
     "title": "Security headers missing",
     "why": "Content-Security-Policy, X-Content-Type-Options, X-Frame-Options and Referrer-Policy protect visitors from injected scripts, clickjacking and leaking URLs.",
     "fix": "Add the headers in the fix box to your server or CDN configuration."
    },
    "fr": {
     "title": "En-têtes de sécurité manquants",
     "why": "Content-Security-Policy, X-Content-Type-Options, X-Frame-Options et Referrer-Policy protègent les visiteurs contre les scripts injectés, le clickjacking et la fuite d'URL.",
     "fix": "Ajoutez les en-têtes de l'encadré de correction à la configuration de votre serveur ou CDN."
    },
    "nl": {
     "title": "Beveiligingsheaders ontbreken",
     "why": "Content-Security-Policy, X-Content-Type-Options, X-Frame-Options en Referrer-Policy beschermen bezoekers tegen geïnjecteerde scripts, clickjacking en lekkende URL's.",
     "fix": "Voeg de headers uit het fixvak toe aan de configuratie van je server of CDN."
    },
    "de": {
     "title": "Security-Header fehlen",
     "why": "Content-Security-Policy, X-Content-Type-Options, X-Frame-Options und Referrer-Policy schützen Besucher vor eingeschleusten Skripten, Clickjacking und dem Preisgeben von URLs.",
     "fix": "Fügen Sie die Header aus dem Fix-Feld Ihrer Server- oder CDN-Konfiguration hinzu."
    },
    "es": {
     "title": "Faltan cabeceras de seguridad",
     "why": "Content-Security-Policy, X-Content-Type-Options, X-Frame-Options y Referrer-Policy protegen a los visitantes de scripts inyectados, clickjacking y filtraciones de URL.",
     "fix": "Añade las cabeceras del cuadro de solución a la configuración de tu servidor o CDN."
    }
   }
  },
  {
   "check": "server_version_disclosed",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Server version is public",
     "why": "The Server or X-Powered-By header names the software and its exact version, which tells an attacker which known flaws to try. It does not affect search or AI answers.",
     "fix": "Hide the version: nginx `server_tokens off;`, Apache `ServerTokens Prod`, PHP `expose_php = Off`."
    },
    "fr": {
     "title": "La version du serveur est publique",
     "why": "L'en-tête Server ou X-Powered-By donne le logiciel et sa version exacte, ce qui indique à un attaquant quelles failles connues essayer. Cela n'affecte ni le référencement ni les réponses des IA.",
     "fix": "Masquez la version : nginx `server_tokens off;`, Apache `ServerTokens Prod`, PHP `expose_php = Off`."
    },
    "nl": {
     "title": "De serverversie is openbaar",
     "why": "De header Server of X-Powered-By noemt de software en de exacte versie, waardoor een aanvaller weet welke bekende lekken hij kan proberen. Het heeft geen invloed op zoekresultaten of AI-antwoorden.",
     "fix": "Verberg de versie: nginx `server_tokens off;`, Apache `ServerTokens Prod`, PHP `expose_php = Off`."
    },
    "de": {
     "title": "Die Serverversion ist öffentlich",
     "why": "Der Header Server oder X-Powered-By nennt die Software und ihre genaue Version; so weiß ein Angreifer, welche bekannten Lücken er versuchen kann. Auf Suchergebnisse und KI-Antworten hat das keinen Einfluss.",
     "fix": "Blenden Sie die Version aus: nginx `server_tokens off;`, Apache `ServerTokens Prod`, PHP `expose_php = Off`."
    },
    "es": {
     "title": "La versión del servidor es pública",
     "why": "La cabecera Server o X-Powered-By indica el software y su versión exacta, lo que dice a un atacante qué fallos conocidos probar. No afecta a las búsquedas ni a las respuestas de IA.",
     "fix": "Oculta la versión: nginx `server_tokens off;`, Apache `ServerTokens Prod`, PHP `expose_php = Off`."
    }
   }
  },
  {
   "check": "csp_unsafe_inline",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Content-Security-Policy allows inline scripts",
     "why": "script-src contains 'unsafe-inline' with no nonce or hash, so a script injected into a page runs as if it were yours and the policy gives little protection. It does not affect search or AI answers.",
     "fix": "Replace 'unsafe-inline' in script-src with per-response nonces or script hashes (a strict CSP). On frameworks that inline their bootstrap scripts this takes real work."
    },
    "fr": {
     "title": "La Content-Security-Policy autorise les scripts en ligne",
     "why": "script-src contient 'unsafe-inline' sans nonce ni empreinte : un script injecté dans une page s'exécute comme le vôtre, et la politique protège peu. Cela n'affecte ni le référencement ni les réponses des IA.",
     "fix": "Remplacez 'unsafe-inline' dans script-src par des nonces par réponse ou des empreintes de scripts (une CSP stricte). Sur les frameworks qui insèrent leurs scripts d'amorçage en ligne, cela demande un vrai travail."
    },
    "nl": {
     "title": "De Content-Security-Policy staat inline scripts toe",
     "why": "script-src bevat 'unsafe-inline' zonder nonce of hash, dus een script dat in een pagina wordt ingespoten draait alsof het van jou is en het beleid beschermt weinig. Het heeft geen invloed op zoekresultaten of AI-antwoorden.",
     "fix": "Vervang 'unsafe-inline' in script-src door nonces per antwoord of hashes van scripts (een strikte CSP). Bij frameworks die hun opstartscripts inline zetten is dat echt werk."
    },
    "de": {
     "title": "Die Content-Security-Policy erlaubt Inline-Skripte",
     "why": "script-src enthält 'unsafe-inline' ohne Nonce oder Hash. Ein in eine Seite eingeschleustes Skript läuft dann wie Ihr eigenes, und die Richtlinie schützt kaum. Auf Suchergebnisse und KI-Antworten hat das keinen Einfluss.",
     "fix": "Ersetzen Sie 'unsafe-inline' in script-src durch Nonces pro Antwort oder Hashes der Skripte (eine strikte CSP). Bei Frameworks, die ihre Startskripte inline einbetten, ist das echte Arbeit."
    },
    "es": {
     "title": "La Content-Security-Policy permite scripts en línea",
     "why": "script-src contiene 'unsafe-inline' sin nonce ni hash, así que un script inyectado en una página se ejecuta como si fuera tuyo y la política protege poco. No afecta a las búsquedas ni a las respuestas de IA.",
     "fix": "Sustituye 'unsafe-inline' en script-src por nonces por respuesta o hashes de scripts (una CSP estricta). En frameworks que insertan sus scripts de arranque en línea, esto es trabajo real."
    }
   }
  },
  {
   "check": "broken_external_link",
   "section": "technical",
   "severity": "notice",
   "added_version": 11,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Link to a page that no longer exists",
     "why": "A link that sends readers, and crawlers that follow it, to a page that is gone (HTTP 404 or 410) or to a domain that no longer exists. We asked twice, 30 seconds apart, and got the same answer.",
     "fix": "Replace the link with a working address or remove it."
    },
    "fr": {
     "title": "Lien vers une page qui n'existe plus",
     "why": "Un lien qui envoie les lecteurs, et les robots qui le suivent, vers une page disparue (HTTP 404 ou 410) ou vers un domaine qui n'existe plus. Nous avons demandé deux fois, à 30 secondes d'intervalle, et obtenu la même réponse.",
     "fix": "Remplacez le lien par une adresse qui fonctionne ou supprimez-le."
    },
    "nl": {
     "title": "Link naar een pagina die niet meer bestaat",
     "why": "Een link die lezers, en crawlers die hem volgen, naar een verdwenen pagina (HTTP 404 of 410) of naar een domein stuurt dat niet meer bestaat. We vroegen twee keer, met 30 seconden ertussen, en kregen hetzelfde antwoord.",
     "fix": "Vervang de link door een adres dat werkt of verwijder hem."
    },
    "de": {
     "title": "Link auf eine Seite, die nicht mehr existiert",
     "why": "Ein Link, der Leser und Crawler, die ihm folgen, auf eine verschwundene Seite (HTTP 404 oder 410) oder auf eine Domain schickt, die nicht mehr existiert. Wir haben zweimal im Abstand von 30 Sekunden gefragt und dieselbe Antwort erhalten.",
     "fix": "Ersetzen Sie den Link durch eine funktionierende Adresse oder entfernen Sie ihn."
    },
    "es": {
     "title": "Enlace a una página que ya no existe",
     "why": "Un enlace que lleva a los lectores, y a los rastreadores que lo siguen, a una página desaparecida (HTTP 404 o 410) o a un dominio que ya no existe. Preguntamos dos veces, con 30 segundos de diferencia, y obtuvimos la misma respuesta.",
     "fix": "Sustituye el enlace por una dirección que funcione o quítalo."
    }
   }
  },
  {
   "check": "sitemap_lastmod_drift",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Sitemap dates are older than the pages' own",
     "why": "On some pages the date the page gives for its last change is more than two weeks newer than the <lastmod> in your sitemap. Crawlers use lastmod to decide what to fetch again, so they may keep an old copy. The HTML cannot say which of the two dates is stale.",
     "fix": "Drive the sitemap <lastmod> and the page's own modified date from the same last-content-change timestamp."
    },
    "fr": {
     "title": "Les dates du sitemap sont plus anciennes que celles des pages",
     "why": "Sur certaines pages, la date de dernière modification donnée par la page a plus de deux semaines d'avance sur le <lastmod> de votre sitemap. Les robots s'appuient sur lastmod pour décider quoi retélécharger : ils peuvent garder une ancienne copie. Le HTML ne dit pas laquelle des deux dates est périmée.",
     "fix": "Alimentez le <lastmod> du sitemap et la date de modification de la page avec le même horodatage de dernière modification du contenu."
    },
    "nl": {
     "title": "De sitemapdatums zijn ouder dan die van de pagina's zelf",
     "why": "Bij sommige pagina's ligt de datum van de laatste wijziging die de pagina zelf geeft ruim twee weken voor op de <lastmod> in je sitemap. Crawlers gebruiken lastmod om te bepalen wat ze opnieuw ophalen, dus ze kunnen een oude kopie houden. De HTML kan niet zeggen welke van de twee datums verouderd is.",
     "fix": "Laat de <lastmod> van de sitemap en de wijzigingsdatum van de pagina uit dezelfde tijdstempel van de laatste inhoudswijziging komen."
    },
    "de": {
     "title": "Die Sitemap-Daten sind älter als die der Seiten selbst",
     "why": "Bei einigen Seiten liegt das Datum der letzten Änderung, das die Seite selbst angibt, mehr als zwei Wochen vor dem <lastmod> Ihrer Sitemap. Crawler nutzen lastmod, um zu entscheiden, was sie neu abrufen; sie behalten womöglich eine alte Kopie. Das HTML sagt nicht, welches der beiden Daten veraltet ist.",
     "fix": "Speisen Sie das <lastmod> der Sitemap und das Änderungsdatum der Seite aus demselben Zeitstempel der letzten Inhaltsänderung."
    },
    "es": {
     "title": "Las fechas del sitemap son más antiguas que las de las propias páginas",
     "why": "En algunas páginas, la fecha de última modificación que da la propia página va más de dos semanas por delante del <lastmod> de tu sitemap. Los rastreadores usan lastmod para decidir qué volver a descargar, así que pueden quedarse con una copia antigua. El HTML no dice cuál de las dos fechas está desactualizada.",
     "fix": "Alimenta el <lastmod> del sitemap y la fecha de modificación de la página con la misma marca de tiempo del último cambio de contenido."
    }
   }
  },
  {
   "check": "favicon_missing",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": true,
   "code_scope": "site",
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No favicon",
     "why": "Browsers show a favicon in the tab and in bookmarks, and Google can show it next to your result. We found no icon link on the home page and no icon at /favicon.ico.",
     "fix": "Add <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\"> and a 48x48 /favicon.ico to the home page head."
    },
    "fr": {
     "title": "Pas de favicon",
     "why": "Les navigateurs affichent un favicon dans l'onglet et dans les favoris, et Google peut l'afficher à côté de votre résultat. Nous n'avons trouvé aucun lien d'icône sur la page d'accueil ni d'icône à /favicon.ico.",
     "fix": "Ajoutez <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\"> et un /favicon.ico de 48x48 dans le head de la page d'accueil."
    },
    "nl": {
     "title": "Geen favicon",
     "why": "Browsers tonen een favicon in het tabblad en bij bladwijzers, en Google kan hem naast je resultaat tonen. We vonden geen icoonlink op de startpagina en geen icoon op /favicon.ico.",
     "fix": "Voeg <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\"> en een /favicon.ico van 48x48 toe aan de head van de startpagina."
    },
    "de": {
     "title": "Kein Favicon",
     "why": "Browser zeigen ein Favicon im Tab und bei Lesezeichen, und Google kann es neben Ihrem Ergebnis anzeigen. Wir fanden weder einen Icon-Link auf der Startseite noch ein Icon unter /favicon.ico.",
     "fix": "Ergänzen Sie <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\"> und eine /favicon.ico mit 48x48 im Head der Startseite."
    },
    "es": {
     "title": "Sin favicon",
     "why": "Los navegadores muestran un favicon en la pestaña y en los marcadores, y Google puede mostrarlo junto a tu resultado. No encontramos ningún enlace de icono en la página de inicio ni un icono en /favicon.ico.",
     "fix": "Añade <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\"> y un /favicon.ico de 48x48 al head de la página de inicio."
    }
   }
  },
  {
   "check": "outbound_dead",
   "section": "technical",
   "severity": "warning",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Links to pages that no longer exist",
     "why": "Pages link out to addresses that answer 404 or 410, or do not resolve at all. Readers and assistants following the source find nothing, and a page of dead sources reads as unmaintained.",
     "fix": "Remove each dead link or point it at the page that replaced it."
    },
    "fr": {
     "title": "Des liens vers des pages qui n'existent plus",
     "why": "Des pages renvoient vers des adresses qui répondent 404 ou 410, ou ne se résolvent pas. Lecteurs et assistants qui suivent la source ne trouvent rien, et une page de sources mortes paraît à l'abandon.",
     "fix": "Retirez chaque lien mort ou faites-le pointer vers la page qui l'a remplacé."
    },
    "nl": {
     "title": "Links naar pagina's die niet meer bestaan",
     "why": "Pagina's linken naar adressen die 404 of 410 geven, of helemaal niet bestaan. Lezers en assistenten die de bron volgen vinden niets, en een pagina met dode bronnen oogt onbeheerd.",
     "fix": "Verwijder elke dode link of laat hem wijzen naar de pagina die hem verving."
    },
    "de": {
     "title": "Links auf Seiten, die es nicht mehr gibt",
     "why": "Seiten verlinken auf Adressen, die mit 404 oder 410 antworten oder gar nicht auflösen. Leser und Assistenten, die der Quelle folgen, finden nichts, und eine Seite mit toten Quellen wirkt ungepflegt.",
     "fix": "Entfernen Sie jeden toten Link oder lassen Sie ihn auf die Seite zeigen, die ihn ersetzt hat."
    },
    "es": {
     "title": "Enlaces a páginas que ya no existen",
     "why": "Las páginas enlazan a direcciones que responden 404 o 410, o que no se resuelven. Los lectores y asistentes que siguen la fuente no encuentran nada, y una página con fuentes muertas parece abandonada.",
     "fix": "Quita cada enlace muerto o haz que apunte a la página que lo sustituyó."
    }
   }
  },
  {
   "check": "outbound_moved",
   "section": "technical",
   "severity": "notice",
   "added_version": 9,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Links to addresses that have moved",
     "why": "Pages link out to addresses that now redirect permanently to another address, so every visitor pays an extra hop and the source you cite is no longer where you say it is.",
     "fix": "Update each link to the address it redirects to."
    },
    "fr": {
     "title": "Des liens vers des adresses qui ont changé",
     "why": "Des pages renvoient vers des adresses qui redirigent désormais définitivement ailleurs : chaque visiteur paie un saut de plus, et la source citée n'est plus là où vous le dites.",
     "fix": "Mettez chaque lien à jour avec l'adresse vers laquelle il redirige."
    },
    "nl": {
     "title": "Links naar adressen die zijn verhuisd",
     "why": "Pagina's linken naar adressen die nu permanent naar een ander adres doorverwijzen, zodat elke bezoeker een extra stap betaalt en de bron die u noemt niet meer is waar u zegt.",
     "fix": "Werk elke link bij naar het adres waarnaar hij doorverwijst."
    },
    "de": {
     "title": "Links auf Adressen, die umgezogen sind",
     "why": "Seiten verlinken auf Adressen, die jetzt dauerhaft auf eine andere Adresse umleiten, sodass jeder Besucher einen Umweg zahlt und die zitierte Quelle nicht mehr dort ist, wo Sie sagen.",
     "fix": "Aktualisieren Sie jeden Link auf die Adresse, auf die er umleitet."
    },
    "es": {
     "title": "Enlaces a direcciones que se han movido",
     "why": "Las páginas enlazan a direcciones que ahora redirigen de forma permanente a otra, así que cada visitante paga un salto extra y la fuente que citas ya no está donde dices.",
     "fix": "Actualiza cada enlace a la dirección a la que redirige."
    }
   }
  },
  {
   "check": "no_main_landmark",
   "section": "structure",
   "severity": "notice",
   "added_version": 11,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "No single <main> landmark",
     "why": "Screen readers and content extractors look for one visible <main> element to find the page's own content, apart from the menu and footer.",
     "fix": "Wrap the page's own content (not the header, nav or footer) in one <main> element."
    },
    "fr": {
     "title": "Pas de repère <main> unique",
     "why": "Les lecteurs d'écran et les outils d'extraction cherchent un seul élément <main> visible pour trouver le contenu propre à la page, hors menu et pied de page.",
     "fix": "Entourez le contenu propre à la page (pas l'en-tête, la navigation ni le pied de page) d'un seul élément <main>."
    },
    "nl": {
     "title": "Geen enkele <main>-landmark",
     "why": "Schermlezers en tools die inhoud uitlezen zoeken één zichtbaar <main>-element om de eigen inhoud van de pagina te vinden, los van menu en voettekst.",
     "fix": "Zet de eigen inhoud van de pagina (niet de header, nav of footer) in één <main>-element."
    },
    "de": {
     "title": "Kein einzelnes <main>-Landmark",
     "why": "Screenreader und Werkzeuge zum Auslesen von Inhalten suchen ein einziges sichtbares <main>-Element, um den eigenen Inhalt der Seite von Menü und Fußzeile zu trennen.",
     "fix": "Setzen Sie den eigenen Inhalt der Seite (nicht Header, Navigation oder Footer) in ein einziges <main>-Element."
    },
    "es": {
     "title": "Sin un único punto de referencia <main>",
     "why": "Los lectores de pantalla y las herramientas que extraen contenido buscan un solo elemento <main> visible para encontrar el contenido propio de la página, aparte del menú y el pie.",
     "fix": "Envuelve el contenido propio de la página (no la cabecera, la navegación ni el pie) en un único elemento <main>."
    }
   }
  },
  {
   "check": "faq_not_visible",
   "section": "structure",
   "severity": "warning",
   "added_version": 12,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "FAQ markup lists questions the page does not show",
     "why": "The page's FAQPage markup names questions that are not in the text a visitor reads. Google's rules say marked-up content must be visible on the page, and markup for text that is not there can be ignored or held against the site.",
     "fix": "Show each marked-up question and its answer on the page, or remove that question from the markup."
    },
    "fr": {
     "title": "Le balisage FAQ liste des questions que la page n'affiche pas",
     "why": "Le balisage FAQPage de la page nomme des questions qui ne figurent pas dans le texte lu par un visiteur. Les règles de Google exigent que le contenu balisé soit visible sur la page ; un balisage pour un texte absent peut être ignoré ou retenu contre le site.",
     "fix": "Affichez chaque question balisée et sa réponse sur la page, ou retirez cette question du balisage."
    },
    "nl": {
     "title": "FAQ-markup noemt vragen die de pagina niet toont",
     "why": "De FAQPage-markup van de pagina noemt vragen die niet in de tekst staan die een bezoeker leest. Volgens de regels van Google moet gemarkeerde inhoud zichtbaar zijn op de pagina; markup voor tekst die er niet is kan worden genegeerd of de site worden aangerekend.",
     "fix": "Toon elke gemarkeerde vraag met het antwoord op de pagina, of haal die vraag uit de markup."
    },
    "de": {
     "title": "FAQ-Markup nennt Fragen, die die Seite nicht zeigt",
     "why": "Das FAQPage-Markup der Seite nennt Fragen, die nicht im Text stehen, den ein Besucher liest. Nach Googles Regeln muss ausgezeichneter Inhalt auf der Seite sichtbar sein; Markup für nicht vorhandenen Text kann ignoriert oder der Website angelastet werden.",
     "fix": "Zeigen Sie jede ausgezeichnete Frage samt Antwort auf der Seite oder entfernen Sie diese Frage aus dem Markup."
    },
    "es": {
     "title": "El marcado FAQ lista preguntas que la página no muestra",
     "why": "El marcado FAQPage de la página nombra preguntas que no están en el texto que lee un visitante. Las reglas de Google exigen que el contenido marcado sea visible en la página, y el marcado de un texto que no está puede ignorarse o jugar en contra del sitio.",
     "fix": "Muestra cada pregunta marcada y su respuesta en la página, o quita esa pregunta del marcado."
    }
   }
  },
  {
   "check": "faq_schema_widespread",
   "section": "structure",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "FAQ markup on most pages",
     "why": "More than half of the site's pages carry FAQPage markup. Google no longer shows FAQ rich results for most sites, so the same block everywhere adds weight and wins nothing, and a template that adds it to pages without real questions marks up text that is not an FAQ.",
     "fix": "Keep FAQPage markup on pages whose visible text is a list of questions with answers, and take it out of the template everywhere else."
    },
    "fr": {
     "title": "Balisage FAQ sur la plupart des pages",
     "why": "Plus de la moitié des pages du site portent un balisage FAQPage. Google n'affiche plus de résultat enrichi FAQ pour la plupart des sites : le même bloc partout alourdit les pages sans rien gagner, et un modèle qui l'ajoute à des pages sans vraies questions balise un texte qui n'est pas une FAQ.",
     "fix": "Gardez le balisage FAQPage sur les pages dont le texte visible est une liste de questions avec réponses, et retirez-le du modèle partout ailleurs."
    },
    "nl": {
     "title": "FAQ-markup op de meeste pagina's",
     "why": "Meer dan de helft van de pagina's van de site heeft FAQPage-markup. Google toont voor de meeste sites geen FAQ-rich results meer: hetzelfde blok overal maakt pagina's zwaarder en levert niets op, en een sjabloon dat het toevoegt aan pagina's zonder echte vragen markeert tekst die geen FAQ is.",
     "fix": "Houd FAQPage-markup op pagina's waarvan de zichtbare tekst een lijst vragen met antwoorden is, en haal het overal elders uit het sjabloon."
    },
    "de": {
     "title": "FAQ-Markup auf den meisten Seiten",
     "why": "Mehr als die Hälfte der Seiten der Website trägt FAQPage-Markup. Google zeigt für die meisten Websites keine FAQ-Rich-Results mehr: derselbe Block überall macht die Seiten schwerer und bringt nichts, und eine Vorlage, die ihn Seiten ohne echte Fragen hinzufügt, zeichnet Text aus, der keine FAQ ist.",
     "fix": "Behalten Sie FAQPage-Markup auf Seiten, deren sichtbarer Text eine Liste von Fragen mit Antworten ist, und entfernen Sie es überall sonst aus der Vorlage."
    },
    "es": {
     "title": "Marcado FAQ en la mayoría de las páginas",
     "why": "Más de la mitad de las páginas del sitio llevan marcado FAQPage. Google ya no muestra resultados enriquecidos de FAQ para la mayoría de los sitios: el mismo bloque en todas partes añade peso y no gana nada, y una plantilla que lo añade a páginas sin preguntas reales marca un texto que no es una FAQ.",
     "fix": "Mantén el marcado FAQPage en las páginas cuyo texto visible es una lista de preguntas con respuestas, y quítalo de la plantilla en todas las demás."
    }
   }
  },
  {
   "check": "no_validators",
   "section": "technical",
   "severity": "notice",
   "added_version": null,
   "added": null,
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Pages cannot be revalidated",
     "why": "None of the sampled pages sends an ETag or Last-Modified header, so a crawler cannot ask whether a page changed and get a short 304 answer. Google's crawling guide recommends it: without it every revisit downloads the whole page and fewer pages get recrawled.",
     "fix": "Send ETag or Last-Modified on HTML pages and answer a matching If-None-Match or If-Modified-Since with 304 Not Modified. Most web servers and CDNs do this when it is switched on."
    },
    "fr": {
     "title": "Les pages ne peuvent pas être revalidées",
     "why": "Aucune des pages échantillonnées n'envoie d'en-tête ETag ni Last-Modified : un robot ne peut pas demander si la page a changé et recevoir une courte réponse 304. Le guide d'exploration de Google le recommande : sans cela, chaque nouvelle visite télécharge la page entière et moins de pages sont réexplorées.",
     "fix": "Envoyez ETag ou Last-Modified sur les pages HTML et répondez 304 Not Modified à un If-None-Match ou If-Modified-Since correspondant. La plupart des serveurs web et des CDN le font une fois l'option activée."
    },
    "nl": {
     "title": "Pagina's kunnen niet opnieuw worden gevalideerd",
     "why": "Geen van de gecontroleerde pagina's stuurt een ETag- of Last-Modified-header, dus een crawler kan niet vragen of de pagina veranderd is en een korte 304-reactie krijgen. De crawlgids van Google raadt het aan: zonder dit downloadt elk nieuw bezoek de hele pagina en worden minder pagina's opnieuw gecrawld.",
     "fix": "Stuur ETag of Last-Modified mee op HTML-pagina's en antwoord op een passende If-None-Match of If-Modified-Since met 304 Not Modified. De meeste webservers en CDN's doen dit zodra het is ingeschakeld."
    },
    "de": {
     "title": "Seiten lassen sich nicht erneut validieren",
     "why": "Keine der geprüften Seiten sendet einen ETag- oder Last-Modified-Header, daher kann ein Crawler nicht fragen, ob sich die Seite geändert hat, und eine kurze 304-Antwort erhalten. Googles Crawling-Leitfaden empfiehlt das: Ohne es lädt jeder erneute Besuch die ganze Seite herunter und weniger Seiten werden erneut gecrawlt.",
     "fix": "Senden Sie ETag oder Last-Modified auf HTML-Seiten und antworten Sie auf ein passendes If-None-Match oder If-Modified-Since mit 304 Not Modified. Die meisten Webserver und CDNs tun das, wenn man es einschaltet."
    },
    "es": {
     "title": "Las páginas no se pueden revalidar",
     "why": "Ninguna de las páginas muestreadas envía la cabecera ETag ni Last-Modified, así que un rastreador no puede preguntar si la página cambió y recibir una respuesta 304 corta. La guía de rastreo de Google lo recomienda: sin ello, cada nueva visita descarga la página entera y se vuelven a rastrear menos páginas.",
     "fix": "Envía ETag o Last-Modified en las páginas HTML y responde 304 Not Modified a un If-None-Match o If-Modified-Since que coincida. La mayoría de los servidores web y CDN lo hacen al activarlo."
    }
   }
  },
  {
   "check": "form_control_unnamed",
   "section": "structure",
   "severity": "warning",
   "added_version": 11,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Form field without a name",
     "why": "A field with no label, aria-label or title is announced as just an edit box by a screen reader and cannot be picked by voice control (WCAG 1.3.1 and 4.1.2, Level A).",
     "fix": "Give the field a visible <label for=\"id\"> or an aria-label. A file input that a button opens should instead get aria-hidden=\"true\" and tabindex=\"-1\"."
    },
    "fr": {
     "title": "Champ de formulaire sans nom",
     "why": "Un champ sans étiquette, sans aria-label ni title est annoncé comme une simple zone de saisie par un lecteur d'écran et ne peut pas être choisi à la voix (WCAG 1.3.1 et 4.1.2, niveau A).",
     "fix": "Donnez au champ un <label for=\"id\"> visible ou un aria-label. Un champ fichier qu'un bouton ouvre doit plutôt recevoir aria-hidden=\"true\" et tabindex=\"-1\"."
    },
    "nl": {
     "title": "Formulierveld zonder naam",
     "why": "Een veld zonder label, aria-label of title wordt door een schermlezer alleen als invoerveld aangekondigd en is niet te kiezen met spraakbesturing (WCAG 1.3.1 en 4.1.2, niveau A).",
     "fix": "Geef het veld een zichtbaar <label for=\"id\"> of een aria-label. Een bestandsveld dat een knop opent krijgt beter aria-hidden=\"true\" en tabindex=\"-1\"."
    },
    "de": {
     "title": "Formularfeld ohne Namen",
     "why": "Ein Feld ohne Label, aria-label oder title meldet ein Screenreader nur als Eingabefeld, und die Sprachsteuerung kann es nicht anwählen (WCAG 1.3.1 und 4.1.2, Stufe A).",
     "fix": "Geben Sie dem Feld ein sichtbares <label for=\"id\"> oder ein aria-label. Ein Dateifeld, das eine Schaltfläche öffnet, erhält stattdessen aria-hidden=\"true\" und tabindex=\"-1\"."
    },
    "es": {
     "title": "Campo de formulario sin nombre",
     "why": "Un campo sin etiqueta, aria-label ni title lo anuncia un lector de pantalla solo como un cuadro de texto y no se puede elegir por voz (WCAG 1.3.1 y 4.1.2, nivel A).",
     "fix": "Dale al campo un <label for=\"id\"> visible o un aria-label. Un campo de archivo que abre un botón debe recibir en su lugar aria-hidden=\"true\" y tabindex=\"-1\"."
    }
   }
  },
  {
   "check": "schema_article_props",
   "section": "structure",
   "severity": "notice",
   "added_version": 11,
   "added": "2026-10-24",
   "basis": "measured",
   "measured": true,
   "writes_code": false,
   "code_scope": null,
   "token": null,
   "headers": null,
   "text": {
    "en": {
     "title": "Article schema without author or date",
     "why": "Google lists author and datePublished as recommended Article properties. With them an assistant can say who wrote the page and when.",
     "fix": "Add author (a Person or Organization with a name) and datePublished (ISO 8601, for example 2026-10-24) to the Article JSON-LD."
    },
    "fr": {
     "title": "Schéma Article sans auteur ni date",
     "why": "Google indique author et datePublished comme propriétés recommandées de l'Article. Avec elles, un assistant peut dire qui a écrit la page et quand.",
     "fix": "Ajoutez author (une Person ou une Organization avec un nom) et datePublished (ISO 8601, par exemple 2026-10-24) au JSON-LD Article."
    },
    "nl": {
     "title": "Article-schema zonder auteur of datum",
     "why": "Google noemt author en datePublished aanbevolen eigenschappen van Article. Daarmee kan een assistent zeggen wie de pagina schreef en wanneer.",
     "fix": "Voeg author (een Person of Organization met een naam) en datePublished (ISO 8601, bijvoorbeeld 2026-10-24) toe aan de Article-JSON-LD."
    },
    "de": {
     "title": "Article-Schema ohne Autor oder Datum",
     "why": "Google nennt author und datePublished als empfohlene Eigenschaften von Article. Damit kann ein Assistent sagen, wer die Seite geschrieben hat und wann.",
     "fix": "Ergänzen Sie author (eine Person oder Organization mit Namen) und datePublished (ISO 8601, zum Beispiel 2026-10-24) im Article-JSON-LD."
    },
    "es": {
     "title": "Esquema Article sin autor ni fecha",
     "why": "Google indica author y datePublished como propiedades recomendadas de Article. Con ellas, un asistente puede decir quién escribió la página y cuándo.",
     "fix": "Añade author (una Person u Organization con nombre) y datePublished (ISO 8601, por ejemplo 2026-10-24) al JSON-LD de Article."
    }
   }
  }
 ]
}