About This HTML Issue
In a valid HTML document, all content must reside within the <html> element, and specifically within either <head> or <body>. The HTML parser expects a well-defined structure: <!DOCTYPE html>, then <html>, containing <head> and <body>. When a <script> tag appears outside this hierarchy — for example, after the closing </html> tag — the validator reports it as a “stray start tag” because it has no valid parent in the document tree.
This is a common issue that arises in a few ways. Sometimes developers accidentally place a script after </body> or </html>, thinking it will still execute. Other times, template systems or CMS platforms inject scripts at the end of the output without ensuring they’re inside <body>. While browsers are forgiving and will typically still execute the script, relying on this error-recovery behavior leads to non-standard markup and unpredictable DOM placement.
Why this matters
-
Standards compliance: The HTML specification requires all elements to be properly nested within the document structure. A
<script>outside<html>violates this requirement. -
Predictable DOM: When a browser encounters a stray
<script>, it must use error recovery to determine where to place it in the DOM. Different browsers may handle this differently, leading to inconsistencies. - Maintainability: Invalid markup can cause confusing debugging scenarios, especially when JavaScript relies on DOM structure or ordering.
How to fix it
Move the <script> element inside either <head> or <body>:
-
Place it in
<head>if the script needs to load before the page content renders (configuration, analytics setup, etc.). Consider using thedeferorasyncattribute for external scripts to avoid blocking rendering. -
Place it at the end of
<body>(just before</body>) if the script interacts with DOM elements, which is a common and recommended pattern.
Examples
Incorrect: script after closing </html> tag
This triggers the “Stray start tag script” error because the <script> is outside the document structure entirely.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
<script>
console.log("This is stray!");
</script>
Incorrect: script between </head> and <body>
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<script>
console.log("Misplaced script");
</script>
<body>
<p>Hello world</p>
</body>
</html>
Correct: script in the <head>
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<script>
console.log("Hello from the head");
</script>
</head>
<body>
<p>Hello world</p>
</body>
</html>
Correct: script at the end of <body>
This is the most common and recommended placement for scripts that interact with the page.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
<script>
console.log("Hello from the body");
</script>
</body>
</html>
Correct: external script with defer in <head>
Using defer lets you place the script in <head> while ensuring it executes after the DOM is fully parsed, giving you the best of both worlds.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<script src="app.js" defer></script>
</head>
<body>
<p>Hello world</p>
</body>
</html>
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.
Learn more: