Problem Solved

HTML · meta charset

Home › Courses › HTML › Problems › meta charset
📄 Concept · 2 min read

The meta charset attribute.
First tag. Every page.

<meta charset="UTF-8"> tells the browser how to decode the file's bytes into characters. It must be the very first tag in <head>, before any content. Without it, accented characters, non-Latin scripts, and emoji can render as garbage — the classic é instead of é, or instead of 中文. This page covers why, and how to fix it.

Short answer: Add <meta charset="UTF-8"> as the very first tag inside <head>. Save the HTML file as UTF-8 in your editor. Set the server's Content-Type header to text/html; charset=UTF-8. All three must agree — file encoding, meta tag, HTTP header. UTF-8 handles every language and emoji. Anything else is a legacy encoding with limited character support.

✅ Before and after

The same page, with and without the tag.

no-charset.html
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Café</title>
</head>
<body>
<h1>Café</h1>
<p>Ça va? 日本語 😀</p>
</body>
</html>
❌ Browser guesses the encoding.
❌ On some systems: "Café" instead of "Café".
❌ On others: "" instead of "日本語".
❌ Emoji may show as "?" or boxes.
❌ The bug depends on the OS and server,
so it looks random — but it's not.
with-charset.html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Café</title>
</head>
<body>
<h1>Café</h1>
<p>Ça va? 日本語 😀</p>
</body>
</html>
✅ "Café" renders correctly.
✅ "日本語" renders correctly.
✅ "😀" renders correctly.
✅ Every character in every language works.
✅ Same result on every OS and server.

✅ The three places encoding must agree

File, meta tag, HTTP header. All three.

File encoding

Save the HTML file as UTF-8 in your editor. VS Code shows it in the status bar. Sublime, Notepad++, all editors support it.

Meta tag

<meta charset="UTF-8"> as the first tag in <head>. Tells the browser which encoding to use.

HTTP header

Content-Type: text/html; charset=UTF-8 from the server. Takes priority over the meta tag when they disagree.

All three must agree

If the header says ISO-8859-1 and the file is UTF-8, the browser decodes wrong — garbled text.

⚠️ Common mistakes

The charset mistakes that cost real time.

1. Missing meta charset

Browser guesses; some characters break. Fix: add the tag as the first item in <head>.

2. Meta charset not the first tag

If it's after content, the browser has already started decoding wrong. Fix: it must be first.

3. Using an old encoding value

charset="ISO-8859-1" or charset="windows-1252". Fix: UTF-8.

4. File saved as one encoding, declared as another

Bytes are wrong; declaration doesn't help. Fix: re-save the file as UTF-8.

5. Server sends a different encoding than the meta tag

Header wins — page breaks. Fix: set server Content-Type to UTF-8 too.

6. Copy-pasting from Word or Google Docs

Smart quotes and special chars may not be UTF-8. Fix: paste as plain text, verify.

7. Ignoring the issue on multilingual sites

English-only pages may "work" — until you add a name with an accent. Fix: always UTF-8.

8. Using meta charset in the body

The browser has already started parsing. Fix: only in <head>, first tag.

❓ Frequently asked

What does meta charset do?

The meta charset attribute tells the browser which character encoding the HTML file uses. charset='UTF-8' means the file is encoded in UTF-8, which supports every character in every language — including emoji. Without it, the browser guesses. If the guess is wrong, accented characters, non-Latin scripts, and emoji display as garbled symbols. UTF-8 is the modern standard; the W3C recommends it for every page.

Why must charset be the first meta tag?

The browser reads the HTML file as bytes, not text. It needs to know the encoding before it can convert those bytes to characters. If the charset tag appears after the first 1024 bytes of the document, the browser has already started parsing with the wrong encoding — the tag itself may be misread. The spec requires charset to be declared in the first 1024 bytes of the document. Put it as the very first meta tag in head, right after the opening head tag.

What happens if I forget meta charset?

The browser falls back to a default encoding — usually the system locale on desktop, or Windows-1252, or whatever the HTTP Content-Type header says. On most modern systems this is UTF-8, so simple pages work. But on older systems or misconfigured servers, characters like é, ü, 中文, 日本語, or 😀 render as garbage. It is one of the most common causes of 'my page has weird characters' bug reports.

Is meta charset the same as Content-Type?

Related but different. Content-Type is an HTTP header sent by the server: Content-Type: text/html; charset=UTF-8. meta charset is a tag inside the HTML document. The browser uses the HTTP header first if present, and falls back to the meta tag if not. If the header says ISO-8859-1 and the meta tag says UTF-8, the header wins — and the page breaks. Best practice: set both to UTF-8.

What is the difference between UTF-8 and UTF-16?

Both encode every Unicode character, but differently. UTF-8 uses 1 byte per ASCII character and 2-4 bytes per non-ASCII. UTF-16 uses 2 bytes per ASCII character and 2-4 bytes per non-ASCII. For HTML files with mostly ASCII content, UTF-8 is smaller — often 30-50% smaller. UTF-8 is also the internet standard, used by 98% of websites. Use UTF-8.

How do I fix garbled characters in HTML?

Three steps. (1) Verify the file is saved as UTF-8 in your editor. Re-save as UTF-8 if not. (2) Add meta charset='UTF-8' as the first tag in head. (3) Check the server's Content-Type header — if it says anything other than UTF-8, fix the server config. If characters still break, the file was saved as one encoding and declared as another — you may need to re-open the file with the original encoding and re-save as UTF-8.

🔗 Related

← All HTML problems
Problem solved · HTML