# A “link” element must not appear as a descendant of a “body” element unless the “link” element has an “itemprop” attribute or has a “rel” attribute whose value contains “dns-prefetch”, “modulepreload”, “pingback”, “preconnect”, “prefetch”, “preload”, “prerender”, or “stylesheet”.

> Canonical HTML version: https://rocketvalidator.com/html-validation/a-link-element-must-not-appear-as-a-descendant-of-a-body-element-unless-the-link-element-has-an-itemprop-attribute-or-has-a-rel-attribute-whose-value-contains-dns-prefetch-modulepreload-pingback-preconnect-prefetch-preload-prerender-or-style
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The HTML specification restricts where `<link>` elements can appear based on their purpose. Links that load resources needed for rendering (like stylesheets and preloaded assets) or carry microdata (`itemprop`) are allowed in `<body>` because they have a direct relationship to the content around them. Other types of `<link>` elements—canonical URLs, icons, alternate versions—are document-level metadata and belong exclusively in `<head>`.

This matters for several reasons. Browsers may ignore or inconsistently handle `<link>` elements placed in unexpected locations, leading to issues like missing canonical signals for search engines or broken favicon references. Standards compliance also ensures your HTML is forward-compatible and behaves predictably across all browsers.

## Common causes

### Direct placement in `<body>`

The most straightforward cause is placing a metadata `<link>` directly inside `<body>`, often due to a CMS, template system, or plugin injecting it in the wrong location.

### Implicit `<body>` creation by the parser

A subtler cause occurs when an element that's only valid in `<body>` appears inside `<head>`. When the HTML parser encounters such an element (like `<img>`, `<div>`, or `<p>`), it implicitly closes the `<head>` and opens the `<body>`. Any `<link>` elements that follow are then treated as descendants of `<body>`, even though they appear to be inside `<head>` in your source code.

For example, an `<img>` tag in the `<head>` causes the parser to switch to body context, so the subsequent `<link rel="canonical">` is interpreted as being inside `<body>` and triggers this error.

## How to fix it

1. **Move disallowed `<link>` elements to `<head>`**: If a `<link>` with `rel="canonical"`, `rel="icon"`, `rel="alternate"`, or similar values is in `<body>`, move it into `<head>`.

2. **Check for body-only elements in `<head>`**: Look for elements like `<img>`, `<div>`, `<p>`, `<script>` (without `src`), or text content that may have been accidentally placed in `<head>`. These cause the parser to implicitly close `<head>`, making everything after them part of `<body>`.

3. **Use allowed `rel` values if a body placement is intentional**: If you genuinely need a `<link>` in `<body>`, ensure it uses one of the permitted `rel` values (`stylesheet`, `preload`, `prefetch`, `preconnect`, `dns-prefetch`, `modulepreload`, `pingback`, `prerender`) or has an `itemprop` attribute.

## Examples

### ❌ `<link rel="canonical">` placed in `<body>`

```html
<body>
  <link rel="canonical" href="https://example.com/page">
  <h1>Welcome</h1>
</body>
```

### ✅ Move it to `<head>`

```html
<head>
  <title>My Page</title>
  <link rel="canonical" href="https://example.com/page">
</head>
<body>
  <h1>Welcome</h1>
</body>
```

### ❌ An `<img>` in `<head>` forces implicit body context

Even though the `<link>` appears to be in `<head>`, the `<img>` causes the parser to switch to body context:

```html
<!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>
```

### ✅ Move the `<img>` to `<body>` where it belongs

```html
<!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>
```

### ✅ Allowed `<link>` elements inside `<body>`

These are valid because they use permitted `rel` values:

```html
<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>
```

### ✅ Using `itemprop` for microdata

A `<link>` with an `itemprop` attribute is also valid inside `<body>`:

```html
<body>
  <div itemscope itemtype="https://schema.org/Product">
    <span itemprop="name">Widget</span>
    <link itemprop="availability" href="https://schema.org/InStock">
  </div>
</body>
```
