While using WordPress, I kept wondering how a multilingual website should work. WordPress itself has solid multilingual UI support, but building a coherent multilingual publication on top of it is difficult. Grav later showed me an elegant file-based approach. When I began writing my own site software, I wanted a solution that was both practical and understandable. This article records the design choices behind it.
Writing Multilingual Content
Language carries culture. Choosing a language also means choosing the audience and context in which an idea can travel. English can reach a broad readership for some technical or internationally relevant topics; Chinese may be the more natural language for others. The point is not to translate everything, but to publish a genuinely useful native version where it has an audience.
Today, limited English is no longer a barrier to communicating with the English-speaking world. Earlier, writers could compare several translation tools and proofread the result; now they can also use AI. Writing in English and then reviewing it manually remains an excellent way to learn1. For example, pigleo explains in “Anyone can write an English blog” that unauthorised English translations of his work prompted him to use software-assisted English writing.
Given that the Chinese Internet is fragmenting2, leading to cultural isolation3, multilingual writing can support exchange across those boundaries. More simply: English can reach a wider audience when the topic genuinely has one.
Multi-language website implementation
You can run a separate site for each language, but that is not always the best fit. WordPress.org uses language-specific sub-sites for help and support because forum posts usually exist in just one language. A personal publication is different: a single article can have carefully maintained versions in more than one language, and readers should be able to discover their relationship.
Some authors offer on-page machine translation, and readers can use tools such as Immersion Translate. That is not native content: readers cannot judge its quality in advance and may have to translate it again through an API, while search engines cannot treat it as a separately maintained page. It is better to create multilingual content by hand. Even if a draft is entirely AI-translated, spending time to proofread it is worthwhile.
For me, a multilingual website provides native versions of both content and UI, with a consistent browsing experience and comparable editorial quality. It is still one publication, even if it uses subdomains or different domains. The WordPress multisite model is therefore outside this article’s scope.
I once used qtranslate-x for WordPress. It stored multilingual text by adding delimiters to database fields, a compromise for a system that did not naturally model localized content; migration and maintenance could be painful. Grav, by contrast, is file-based: if the Chinese article is item.zh.md, adding item.en.md beside it creates the English counterpart. That is intuitive and portable. Grav still has limitations, including a single set of site-wide settings such as the site nameNote1, so I adopted a similar file-based model with finer-grained planning.
Planning for content
Would an English edition help readers understand an article praising mainland China’s app-filing system? Would a long critique of Trump need a Traditional Chinese edition? Would a film review built around Japanese anime references make sense in German? These are editorial questions, not mechanical translation tasks.
Choosing a multilingual site does not mean that every article requires the same set of translations. Decide language by language and article by article. Different editions can add explanations, examples, or calls to action for readers with different levels of background knowledge, and can include marketing tailored to their language and culture.
URL Design
How should URLs work when one site contains several content languages? Should they use a query parameter such as ?lang=zh-CN, a cookie, or an explicit path such as /en/post-slug/?
When an article is difficult to read, a few familiar characters can make someone look for a version in their language—often unsuccessfully. When a native edition exists, the site should make it discoverable. Accept-Language is useful for selecting an initial UI language or a sensible fallback, but an explicit content URL should remain stable and shareable. A clear language switcher is essential; finding one should not be a challenge on a Russian- or German-language site.
So, my site implements:
- Keep the UI language separate from the content language.
- Let the default URL choose a reasonable initial language or fallback.
- Let a language in the URL select an explicit content version.
Language affects more than article text. A Simplified Chinese UI may need ICP, public-security, and publishing licence information; European-language UI may need privacy and cookie controls. Those controls should offer genuine choices, not misleading actions.
An English-speaking visitor to /website-multilingual-design-details/ does not need to be forcibly redirected to /en/website-multilingual-design-details/. They can remain on the default URL, with English UI and English content when that edition exists.
When you visit the path of the specified language version, the content switches to the corresponding version, and the UI language still depends on the visitor’s browser settings.
Other details
Once the URL scheme is clear, the remaining details follow. For example, an en-US preference can fall back to supported en content. A zh-CN reader might be offered zh-HK only as an explicitly labelled fallback, because script and regional conventions differ. Grav also allows an article to opt out of a language by creating that language’s content and marking it for removal.
Content language hints
If a reader arrives from Google or social media at an English URL but prefers another language, the page can show the current content language and any available alternatives. The reader should be able to switch voluntarily. Listing every native edition at the end of the article also helps readers compare and, occasionally, help spot translation mistakes.
UI language switching
At the end of the page, readers can choose any supported UI language. When a corresponding article edition exists, it can switch too. This means that even a default-English Tor Browser can show a Russian Отправить button.
Media Resources
For images containing text, you can either reference different files from item.en.md and item.zh.md, or create image.en.png and image.zh.png and reference . The latter needs content negotiation based on the Accept-Language header; make sure caches vary correctly by that header, or use explicit asset URLs when predictable sharing and caching matter more.
RSS
While some people still miss Google Reader, I also implemented automatic language selection for RSS. In practice, many reader bots neither send a useful language header nor follow language links in Atom feeds. Explicit feeds such as /en/feed/ are therefore available for readers who want English content only.
SEO
One cost of not using a publishing platform is owning the SEO details. Google recommends explicitly connecting equivalent localized pages with reciprocal hreflang annotations, including a self-reference on every version; x-default is appropriate for a catch-all page when it really serves unmatched users4. A translation is not duplicate content merely because it describes the same topic—the important part is that the main content is genuinely localized. A file-based article system also makes it straightforward to write distinct titles, summaries, and metadata for each language.
Do not rely on hreflang alone. Each language page needs a stable, crawlable URL, a clear language label, useful internal links, and a canonical URL that reflects the page itself. Keep any sitemap alternates consistent with the HTML annotations and verify the rendered output after deployment.
You may also choose to let Baidu focus on Chinese content in robots.txt:
User-Agent: Baiduspider
Disallow: /en/
Anchor links
I even considered anchor links. A Markdown heading plugin may assign the Chinese heading id 锚点链接; an English edition will use a different id. If people regularly share cross-language anchors, custom stable IDs such as {#anchor-link} in every edition can solve it. For a small blog, that may be unnecessary complexity.
Comment system languages
This may be over-engineering, but comments do become tricky. I record both the content language and the UI language used when a comment is made; this supports language-grouped comments and notification emails in the appropriate language.
Conclusion
After continuous improvement, the design is working. A reader once pointed out that my RSS language content was mixed up—thank you. The site now even receives spam comments in English and Russian. Internationale, indeed.
Notes
-
In Grav, it is possible to create a hidden content page for storing multi-language versions of site configurations, but this approach requires the use of a custom theme that supports this feature. ↩
References
-
Dallas Lu. …原始文章是你自己写的,这个理解程度是他人作品所不能比的。整个过程既有输出的强化练习,又有高效地学习吸收…. 𝕏. 2024-05-01. ↩
-
何加盐. 中文互联网正在加速崩塌. cnBeta. 2024-05-23. MP. ↩
-
darmau. We are witnessing the insularization of Chinese civilization. darmau.co. 2024-08-13. ↩
-
Google Search Central. Tell Google about localized versions of your page. Accessed 2026-09-04. ↩
Webmention
Comment Form
非常感谢分享。我的 wordpress 站点用的是 Polylang,就感觉还是比较笨重。第一次听说 Grav ,看了一下它对多语言的原生支持很给力。不过2024年了在 CMS 领域另立一个山头,总觉得比较害怕后续无人维护生态崩溃……
主题很好看 但感觉这个字体看起来不太舒服
我也有些同感。不知是字重大了,还是间距小了,或者字体的风格需要换一换。看上去有点花,满眼都是字