Language Switcher with hreflang
The best language switcher is a list of plain links. No script that guesses the visitor's language, no automatic redirect — just links that people and search engines can follow, connected with hreflang. Plus what changes when one of your languages is Chinese.
- JavaScript
- 0 KB
- Built with
<details>,hreflang,lang- Browsers
- All current browsers (Chrome, Edge, Firefox, Safari)
- Updated
Give every language its own URL and link them with normal <a> links — written in their own language, marked with lang and hreflang. Connect the versions with <link rel="alternate" hreflang="…"> in the <head>. Don't redirect visitors automatically by IP address or browser language: search engine crawlers get redirected too, and may never see your other versions.
Live demo
The real language switch between Jademond's English and Chinese websites. Click it, or Tab to it and press Enter. Each language is shown in its own script — someone who reads only Chinese finds “简体中文”, not “Chinese”.
How the language switcher works
- Plain links, nothing else
Each language is an
<a href>to its own URL. Crawlers follow it, visitors can open it in a new tab, and it works when scripts fail. A<select>that changes the page with JavaScript does none of that. - A native dropdown
<details>and<summary>open and close the list with mouse, touch and keyboard. With only two or three languages, you can skip the dropdown and show the links side by side. - Languages in their own words
“简体中文”, “Deutsch”, “日本語” — not “Chinese”, “German”, “Japanese”. A visitor who can't read the current page must still recognise their language.
langon each linklang="zh-CN"tells screen readers to pronounce “简体中文” as Chinese, and lets browsers pick the right font.hreflangon each linkIt says which language the target page is in. Search engines take the binding signal from the
<link>tags in the<head>(below); on the link itself it is a helpful hint.- No flags
Flags stand for countries, not languages. Chinese is the language of mainland China, Taiwan, Hong Kong and Singapore — which flag would you pick? Text labels avoid the question.
Copy the HTML and CSS
Exactly the code running in the demo. Replace the two links with the URLs of the current page in each language — not your home pages — so visitors land on the same content in their language.
<nav class="ui-lang" aria-label="Language">
<details class="ui-lang__menu">
<summary>
<span class="ui-lang__icon" aria-hidden="true">文A</span>
<span lang="en">English</span>
</summary>
<ul>
<li><a href="https://www.jademond.com/" hreflang="en" lang="en" aria-current="true">English</a></li>
<li><a href="https://www.jademond.cn/" hreflang="zh-CN" lang="zh-CN">简体中文</a></li>
</ul>
</details>
</nav>/* Language switcher — no JavaScript.
Plain links to each language version, in a native <details>
dropdown. Each language is written in its own language,
and marked with lang and hreflang. */
.ui-lang {
--ui-bg: #ffffff;
--ui-text: #1b1f3b;
--ui-accent: #4f46e5;
--ui-hover: #eef0ff;
position: relative;
display: inline-block;
font: 500 0.9375rem/1.4 system-ui, -apple-system, "Segoe UI", sans-serif;
color: var(--ui-text);
}
.ui-lang summary {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.55rem 0.9rem;
border-radius: 8px;
background: var(--ui-bg);
cursor: pointer;
list-style: none;
}
.ui-lang summary::-webkit-details-marker {
display: none;
}
.ui-lang summary::after {
content: "";
width: 0.4rem;
height: 0.4rem;
margin: -0.2rem 0 0 0.15rem;
border-right: 2px solid currentColor;
border-bottom: 2px solid currentColor;
transform: rotate(45deg);
}
.ui-lang summary:focus-visible,
.ui-lang a:focus-visible {
outline: 2px solid var(--ui-accent);
outline-offset: 2px;
}
.ui-lang__icon {
font-size: 0.8rem;
font-weight: 700;
color: var(--ui-accent);
}
/* The list of languages */
.ui-lang ul {
position: absolute;
top: calc(100% + 0.4rem);
left: 0;
z-index: 10;
min-width: 12rem;
margin: 0;
padding: 0.35rem 0;
list-style: none;
border-radius: 10px;
background: var(--ui-bg);
box-shadow: 0 12px 32px rgb(15 18 40 / 0.2);
}
.ui-lang a {
display: block;
padding: 0.6rem 1rem;
color: var(--ui-text);
text-decoration: none;
}
.ui-lang a:hover {
background: var(--ui-hover);
}
.ui-lang a[aria-current] {
color: var(--ui-accent);
font-weight: 700;
}The hreflang tags for your <head>
These connect the language versions for search engines. Every version lists all versions, including itself. x-default names the page for everyone else. (Example URLs — this page has no translations, so it doesn't use these tags itself.)
<!-- In the <head> of EVERY language version of the page — the same set each time -->
<link rel="alternate" hreflang="en" href="https://www.example.com/products/">
<link rel="alternate" hreflang="zh-CN" href="https://www.example.cn/chanpin/">
<link rel="alternate" hreflang="zh-TW" href="https://www.example.com/zh-tw/products/">
<link rel="alternate" hreflang="x-default" href="https://www.example.com/products/">
<!-- And the language of each page on its <html> element -->
<html lang="zh-CN">Language versions and SEO — Google and Baidu
Don't redirect automatically. Sending visitors to a language version based on their IP address or browser language feels helpful, but crawlers are visitors too. Google's crawler mostly comes from the US and doesn't send a language preference; a site that redirects it to English may keep its other versions out of Google's index. If you want to help visitors, show a small note — “This page is also available in 简体中文” — rendered on the server, and let them choose.
One language per URL. A page that mixes two languages, or switches language with a script while the URL stays the same, gives search engines nothing clear to index. That is also why we rewrote this lab in English only — the earlier versions mixed English and Chinese on one page.
hreflang is a Google and Bing signal. Baidu doesn't document support for hreflang. For Baidu, the Chinese version has to stand on its own: Simplified Chinese content written for mainland readers, <html lang="zh-CN">, fast hosting for China — in our experience ideally a separate site, often on a .cn domain. The plain links between the versions still help crawlers find it.
Simplified and Traditional are different versions. Mainland China and Singapore read Simplified Chinese, Taiwan and Hong Kong read Traditional — with different vocabulary, not just different characters. Treat them as separate versions with their own hreflang: zh-CN, zh-TW, zh-HK.
Accessibility and browser support
| Situation | Without JS | Details |
|---|---|---|
| Keyboard | Works | Enter or Space opens the list, Tab moves through the languages. |
| Screen readers | Works | A “Language” navigation; each language name is pronounced correctly thanks to lang. |
| Crawlers | Works | Normal links in the HTML, followed by every search engine. |
| Close on click outside | Needs JS | A <details> stays open until it is clicked again. Use a popover instead if that matters — see the modal page. |
| Remember the choice | Server | The URL already remembers it: each language lives on its own address. |
Questions about language switchers and hreflang
Should I redirect visitors to their language automatically?
No. Crawlers may be redirected too and miss your other versions. Show a suggestion instead and let visitors choose.
What hreflang code should I use for Chinese?
zh-CN for Simplified Chinese aimed at mainland China, zh-TW for Traditional Chinese in Taiwan, zh-HK for Hong Kong. Use plain zh only if one version serves all Chinese readers.
Does Baidu use hreflang?
Baidu doesn't document support for it. Make the Chinese version strong on its own — content, lang="zh-CN", hosting — and link to it with plain links.
Should I use flags in a language switcher?
Better not. Flags stand for countries, many languages are spoken in several countries, and some flags are politically sensitive. Write each language's name in that language.
Where should the language switcher go?
In the header, usually top right, where visitors look for it — and again in the footer. It should look the same on every page.
This FAQ is built without JavaScript — see the accordion pattern.
Planning a Chinese version — or Korean and Japanese too?
We set up Chinese websites that rank on Baidu, with the right structure between language versions. For Korea and Japan we work with trusted partners in each market.
CSS-First UI Patterns are written and maintained by Jademond Digital, a Chinese digital marketing agency founded in Guangzhou in 2012. We build and audit websites for Baidu, Google and AI search — which is why we care what works without JavaScript. About us →