Character encoding missing or not UTF-8
What Is This Issue
This issue checks whether your web pages have a properly configured <meta charset="UTF-8"> declaration in the HTML head section.
The charset declaration tells the browser how to interpret the byte stream of the HTML document. A passing implementation includes:
- A
<meta charset="UTF-8">tag (or the legacy<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">form) - The tag must be the first element inside the
<head>section - The tag must appear within the first 1024 bytes of the HTML response
- The charset value should be
UTF-8(the universal standard)
Example of correct implementation:
<head>
<meta charset="UTF-8" />
<title>Page Title</title>
...
</head>Without this declaration, browsers may fall back to legacy encoding detection, causing accented characters, CJK characters, and special symbols to render as garbled text (mojibake).
Why Is This Important
Proper character encoding is fundamental to web page rendering and SEO:
- User experience: Incorrect encoding causes text to display as unreadable gibberish, making content inaccessible to users.
- Crawlability: Search engine crawlers need to correctly parse page content. Garbled text may prevent proper indexing.
- Indexability: Pages with encoding issues may be flagged as low-quality or problematic, affecting indexation.
- International SEO: UTF-8 supports all international characters, which is essential for multilingual websites.
- AI Search / AEO: AI-powered search systems need to correctly parse content to provide accurate answers.
Resolving this issue improves your SEO health score by ensuring search engines and browsers can correctly interpret your content, which is a foundational requirement for all other SEO optimizations.
How XeoPix Detects This
XeoPix performs the following checks to detect this issue:
-
HTML response analysis: The crawler fetches the raw HTML response and examines the first 1024 bytes of the document.
-
Charset declaration search: It looks for:
<meta charset="...">(HTML5 form)<meta http-equiv="Content-Type" content="text/html; charset=...">(HTML4 form)
-
Position validation: The crawler checks:
- Whether a charset declaration exists
- Whether it appears within the first 1024 bytes of the response
- Whether it’s the first element inside the
<head>section
-
Value validation: If a declaration is found, XeoPix:
- Extracts the charset value (e.g., “UTF-8”, “utf-8”, “iso-8859-1”)
- Normalizes it to lowercase
- Checks if it matches “utf-8”
-
Conflict detection: The crawler also checks for conflicts between:
- The meta tag charset value
- The
charsetparameter in the HTTPContent-Typeresponse header
-
Pass/Fail determination:
- Passes: If a UTF-8 charset declaration exists, appears within the first 1024 bytes, and is the first element in
<head> - Fails: If the declaration is missing, not UTF-8, appears too late in the document, or is not the first head element
- Passes: If a UTF-8 charset declaration exists, appears within the first 1024 bytes, and is the first element in
How To Fix
Follow these steps to implement the charset declaration correctly:
-
Add the meta charset tag to your HTML head: Place the following line as the very first element inside the
<head>section:<meta charset="UTF-8" /> -
Ensure correct positioning: The charset declaration must be:
- The first element inside
<head>(before<title>, other<meta>tags, etc.) - Within the first 1024 bytes of the HTML response
- The first element inside
-
Use UTF-8 encoding: Ensure your HTML file is actually saved with UTF-8 encoding (not ISO-8859-1, Windows-1252, etc.)
-
Remove duplicate declarations: If multiple charset declarations exist, remove all but one.
-
Verify implementation:
- Use View Page Source to confirm the tag appears correctly
- Check that it appears before any other head elements
- Use browser developer tools to ensure characters render correctly
Note: If you must support legacy systems, the HTML4 form is also acceptable: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">, but the HTML5 form is preferred.
What We Store
Storage Level
Page Level — This issue is evaluated for each individual URL.
Database Table / Prisma Model
PageHtmlHeadAudit
Stored Fields
| Field | Type | Description |
|---|---|---|
| charsetValue | String? | The charset value extracted from the meta tag |
Detection Dependencies
- The following data sources are required to evaluate this issue:
- HTML Document — The crawler parses the HTML head section to find the charset declaration
- Meta Tag Extraction — The
<meta charset>or<meta http-equiv="Content-Type">tag is extracted
Examples
Example 1: Correct Implementation
Scenario: A properly configured page with UTF-8 charset declaration.
Correct State (Passes):
<head>
<meta charset="UTF-8" />
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>Example 2: Incorrect Placement
Scenario: Charset declaration appears after the title tag.
Problematic State (Fails):
<head>
<title>Pagé Title</title>
<meta charset="UTF-8" />
</head>Why it fails: The <title> tag is rendered before the charset declaration, which may cause the title to display with wrong encoding (mojibake).
Corrected State (Passes):
<head>
<meta charset="UTF-8" />
<title>Pagé Title</title>
</head>Example 3: Missing Charset Declaration
Scenario: Page has no charset declaration.
Problematic State (Fails):
<head>
<title>Page Title</title>
<meta name="description" content="Page description" />
</head>Corrected State (Passes):
<head>
<meta charset="UTF-8" />
<title>Page Title</title>
<meta name="description" content="Page description" />
</head>Example 4: HTTP Header Conflict
Scenario: HTTP header specifies different charset than meta tag.
Problematic State (Fails):
- HTTP Response Header:
Content-Type: text/html; charset=iso-8859-1 - HTML Meta Tag:
<meta charset="UTF-8">
Why it fails: The HTTP Content-Type header takes precedence over the in-document <meta charset> tag. The browser will use ISO-8859-1, causing potential encoding issues.
Corrected State (Passes):
- HTTP Response Header:
Content-Type: text/html; charset=utf-8 - HTML Meta Tag:
<meta charset="UTF-8">
Unit Test
Test File
__tests__/seo-audit-checks/htmlHeadTags/issue-103-meta-charset-utf.test.js
Purpose
Validates the detection of missing or incorrect <meta charset> declarations in the HTML <head>. Ensures that pages are flagged when the charset is missing, not UTF-8, or defined via an alternative mechanism with a non-UTF-8 value.
Tested Function
runHtmlHeadTags() from toggleGroups/htmlHeadTags.js
Issue Information
- Issue Number: 103
- Issue Code:
META_CHARSET_UTF - Toggle Group:
htmlHeadTags
Test Scenarios
Positive Test Cases
- Page has
<meta charset="UTF-8">— no issue reported - Page has
<meta charset="utf-8">(lowercase) — no issue reported - Page has
<meta http-equiv="content-type" content="text/html; charset=UTF-8">— no issue reported - Malformed HTML that still contains a valid UTF-8 charset declaration — no issue reported, no crash
- Charset value with extra whitespace (
" UTF-8 ") — no issue reported
Negative Test Cases
- Page has no
<meta charset>tag at all — issue reported with message"Charset metadata is missing" - Page has
<meta charset="ISO-8859-1">— issue reported withcharsetValue: "ISO-8859-1" - Page has
<meta charset="ASCII">— issue reported withcharsetValue: "ASCII" - Page has
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">— issue reported withcharsetValue: "ISO-8859-1"
Boundary Cases
None present.
Edge Cases
- Empty HTML (
<html></html>): issue reported (charset metadata is missing) - Malformed HTML: function handles without crashing; correctly detects charset when present
- Whitespace handling: charset value with surrounding whitespace is treated as valid
- http-equiv alternative: the
content-typehttp-equiv form is checked for charset value
Expected Outcome
Pass
The issue should be reported when:
- The
<meta charset>tag is completely absent - The charset is present but not set to
UTF-8/utf-8 - The http-equiv content-type form is used but with a non-UTF-8 charset
Fail
The issue should not be reported when:
<meta charset="UTF-8">(any case) is present<meta http-equiv="content-type" content="text/html; charset=UTF-8">is present- The charset value contains extra whitespace but resolves to UTF-8
Validation
- Correct detection of missing charset metadata
- Correct detection of non-UTF-8 charset values (ISO-8859-1, ASCII)
- Correct detection via the http-equiv alternative form
- Whitespace-tolerant charset value parsing
- Graceful handling of malformed HTML
- Cache mechanism prevents duplicate issue entries on repeated calls
Related Production Files
toggleGroups/htmlHeadTags.jsissueCodes.js
Coverage Summary
- Positive cases: 4 (UTF-8, lowercase utf-8, http-equiv UTF-8, whitespace)
- Negative cases: 4 (missing, ISO-8859-1, ASCII, http-equiv ISO-8859-1)
- Edge cases: 3 (empty HTML, malformed HTML, whitespace handling)
- Cache validation: 1
References
- Character encoding — MDN
- Character Model for the World Wide Web — W3C
- HTML suggestions — Google Search Central