Acerca de este problema HTML
La especificación HTML restringe dónde pueden aparecer los elementos <link> basándose en su propósito. Los enlaces que cargan recursos necesarios para el renderizado (como hojas de estilo y recursos precargados) o que contienen microdatos (itemprop) están permitidos en <body> porque tienen una relación directa con el contenido que los rodea. Otros tipos de elementos <link>—URLs canónicas, iconos, versiones alternativas—son metadatos a nivel de documento y pertenecen exclusivamente en <head>.
Esto es importante por varias razones. Los navegadores pueden ignorar o manejar de manera inconsistente los elementos <link> colocados en ubicaciones inesperadas, causando problemas como señales canónicas perdidas para motores de búsqueda o referencias rotas de favicon. El cumplimiento de estándares también asegura que tu HTML sea compatible hacia adelante y se comporte de manera predecible en todos los navegadores.
Causas comunes
Colocación directa en <body>
La causa más directa es colocar un <link> de metadatos directamente dentro de <body>, frecuentemente debido a un CMS, sistema de plantillas o plugin que lo inyecta en la ubicación incorrecta.
Creación implícita de <body> por el parser
Una causa más sutil ocurre cuando un elemento que solo es válido en <body> aparece dentro de <head>. Cuando el parser HTML encuentra tal elemento (como <img>, <div> o <p>), cierra implícitamente el <head> y abre el <body>. Cualquier elemento <link> que siga es entonces tratado como descendiente de <body>, incluso aunque parezcan estar dentro de <head> en tu código fuente.
Por ejemplo, una etiqueta <img> en el <head> hace que el parser cambie al contexto de body, por lo que el subsiguiente <link rel="canonical"> se interpreta como estando dentro de <body> y dispara este error.
Cómo solucionarlo
-
Mueve elementos
<link>no permitidos a<head>: Si un<link>conrel="canonical",rel="icon",rel="alternate"o valores similares está en<body>, muévelo a<head>. -
Verifica elementos solo de body en
<head>: Busca elementos como<img>,<div>,<p>,<script>(sinsrc) o contenido de texto que puedan haberse colocado accidentalmente en<head>. Estos hacen que el parser cierre implícitamente<head>, convirtiendo todo lo que sigue en parte de<body>. -
Usa valores
relpermitidos si la colocación en body es intencional: Si genuinamente necesitas un<link>en<body>, asegúrate de que use uno de los valoresrelpermitidos (stylesheet,preload,prefetch,preconnect,dns-prefetch,modulepreload,pingback,prerender) o tenga un atributoitemprop.
Ejemplos
❌ <link rel="canonical"> colocado en <body>
<body>
<link rel="canonical" href="https://example.com/page">
<h1>Welcome</h1>
</body>
✅ Muévelo a <head>
<head>
<title>My Page</title>
<link rel="canonical" href="https://example.com/page">
</head>
<body>
<h1>Welcome</h1>
</body>
❌ Una <img> en <head> fuerza contexto implícito de body
Aunque el <link> parezca estar en <head>, la <img> hace que el parser cambie al contexto de body:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test</title>
<img src="photo.jpg" alt="A smiling cat">
<link rel="canonical" href="https://example.com/">
</head>
<body>
<p>Some content</p>
</body>
</html>
✅ Mueve la <img> a <body> donde pertenece
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test</title>
<link rel="canonical" href="https://example.com/">
</head>
<body>
<img src="photo.jpg" alt="A smiling cat">
<p>Some content</p>
</body>
</html>
✅ Elementos <link> permitidos dentro de <body>
Estos son válidos porque usan valores rel permitidos:
<body>
<article>
<link rel="stylesheet" href="article-theme.css">
<h2>Article Title</h2>
<p>Content here.</p>
</article>
<link rel="prefetch" href="/next-page.html">
<link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin>
</body>
✅ Usando itemprop para microdatos
Un <link> con un atributo itemprop también es válido dentro de <body>:
<body>
<div itemscope itemtype="https://schema.org/Product">
<span itemprop="name">Widget</span>
<link itemprop="availability" href="https://schema.org/InStock">
</div>
</body>
Encuentra problemas como este automáticamente
Rocket Validator escanea miles de páginas en segundos, detectando problemas de HTML en todo tu sitio web.
Más información: