# General Translation Knowledge Base: How do I make a website multilingual?
URL: https://generaltranslation.com/en-US/kb/make-website-multilingual.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Pick where translations live, in a proxy, CMS plugin, site builder, or your own code, then give each language its own URL, as Google recommends. Translate full pages plus titles and meta descriptions, link the versions with hreflang, and offer a language switcher instead of auto-redirecting visitors.
Category: Internationalization
Last updated: 2026-10-20
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-20

A multilingual website serves each page in several languages, each version at its own URL, with search engines told how the versions relate. The approaches differ mainly in where the translated text lives, which decides how much control you keep over SEO, quality, and updates. So pick the approach before you translate anything.

## Which approach should you choose?

The lightest option needs no work from you: visitors' browsers can translate pages themselves. [Chrome](https://support.google.com/chrome/answer/173424), for example, can translate a page with Google Translate, prompted by the reader's language settings. That helps one reader, but it doesn't make your site multilingual. There are no language URLs to index, you can't review the output, and your only lever is marking text such as brand names with the [`translate="no"`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/translate) attribute.

Translation proxies and JavaScript overlays sit in front of a finished site. [Weglot's reverse proxy](https://weglot.com/technical-presentation/) fetches your page, translates its content through Weglot's API, and serves the result on a language subdomain or subdirectory with hreflang added. Its JavaScript integration inserts translations in the browser after the page loads instead; Weglot notes that search engines don't detect those translations and recommends the mode for testing or private content. Either way, the translations live in the vendor's dashboard.

CMS plugins and site builders keep translations inside the platform. On WordPress, [WPML](https://wpml.org/documentation/getting-started-guide/language-setup/language-url-options/) puts languages in directories, on a domain or subdomain per language, or in a `?lang=` parameter, and [Polylang](https://wordpress.org/plugins/polylang/) sets the language from a code in the URL or a subdomain or domain per language. [Webflow Localize](https://webflow.com/localization) serves locales in subdirectories such as `/es/`, translates meta titles and descriptions, and generates a sitemap with hreflang tags. Squarespace's multilingual setting [connects Weglot](https://support.squarespace.com/hc/en-us/articles/205809778-Creating-a-multilingual-site-with-Weglot) on version 7.1 sites, and translations are edited in Weglot, since Squarespace can't edit them directly.

Static site generators and i18n libraries keep translations in your repository. [Docusaurus](https://docusaurus.io/docs/i18n/introduction) stores translated files under `i18n/[locale]/` and sets hreflang headers for you. [Hugo](https://gohugo.io/content-management/multilingual/) assigns a page's language from a filename suffix such as `about.fr.md` or from its content directory, then serves it under a prefix such as `/fr/`. In an app built with React, Next.js, or Vue, a library such as i18next or next-intl renders translations from files you maintain. None of these produces the translations: you write them, buy them, or connect a translation tool.

| Approach | Where translations live | SEO control | Quality control | Engineering effort | Best for |
| --- | --- | --- | --- | --- | --- |
| Browser translation | Generated in each visitor's browser | None; no language URLs | None beyond `translate="no"` | None | Readers of sites you haven't localized |
| Proxy or overlay (Weglot) | Vendor dashboard | Proxy mode adds language URLs and hreflang; JavaScript mode isn't indexed | Machine translation, then edits or ordered human translation in the vendor's editor | DNS change or script tag | Finished sites you don't want to rebuild |
| CMS plugin (WPML, Polylang) | Your WordPress database | URL format and switcher set in the plugin | Manual, machine, or agency translation inside WordPress | Plugin setup, then per-page work | WordPress sites |
| Site builder (Webflow Localize, Squarespace) | The builder, or Weglot for Squarespace | Managed by the builder | Machine translation plus manual edits | Low | Sites built and hosted on that builder |
| Static site generator i18n (Docusaurus, Hugo) | Files in your repository | Full; you own URLs and templates | Whatever process produces the files | Moderate; translation is a separate job | Docs and content sites built from Markdown |
| General Translation | Generated files in your build, or GT's CDN | You own routing and metadata; `gt-next` supplies locale routing helpers | Code-derived context, shared terminology, and built-in review | Mark source text or connect existing catalogs, generate before the build, test locales | Developer-owned sites that need translation generation as well as rendering |
| i18n library alone (i18next, next-intl) | Translation files in your repository | Full | Whatever process produces the files | String extraction, routing, translation delivery, and QA; existing integrations may automate some work | Apps that already have a translation workflow |

Use a proxy or your site builder's feature when a marketing team needs translated pages without rebuilding the site. Use a CMS plugin for WordPress. Use static site generator i18n or an i18n library when developers own the site and already have translations. Choose General Translation when you also want to generate and review updates as part of releases; its CLI can translate existing files without replacing your library. The effort depends on your existing routing, content, and review process; the table describes tasks rather than measured setup times.

## The steps every approach has to answer

Whichever approach you pick, it has to settle these seven decisions, roughly in this order.

### 1. Choose languages and locales

Start from where your traffic and customers already are. Each locale you add is a set of pages to translate, review, and keep current, so add a regional variant only where the wording or formats differ for that audience: Brazilian and European Portuguese (`pt-BR`, `pt-PT`) differ in vocabulary, while a single `fr` can serve French readers in several countries. The [locale codes guide](/docs/platform/core/guides/locale-codes) covers how to write and choose these tags.

### 2. Choose a URL structure

Google [recommends a separate URL for each language version](https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites) instead of one URL whose language changes with a cookie or browser setting. Subdirectories (`example.com/fr/`), subdomains, and country domains all work; [the URL structure guide](/kb/multilingual-url-structure) compares them.

### 3. Translate content and metadata

Google [determines a page's language from its visible content](https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites), not from `lang` attributes or the URL, and advises against translating only the navigation while the body stays in one language. Translate the full page plus its title, meta description, image alt text, form errors, and the emails a page sends. Still set `<html lang>` on every version: [browsers and screen readers use it](https://www.w3.org/International/questions/qa-lang-why) for font selection, hyphenation, and speech.

### 4. Add hreflang

Hreflang annotations tell search engines which URLs are language versions of the same page, so they can show searchers the version in their language. [What is hreflang](/kb/what-is-hreflang) covers the rules, `x-default`, and common mistakes.

### 5. Add a language switcher

Give visitors a visible control that moves them to the same page in another language, and don't [redirect them automatically](https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites) based on their perceived language, which Google advises against. [The language switcher guide](/kb/language-switcher) covers the details, and [detecting a user's language](/kb/detect-user-language) covers picking a sensible first language.

### 6. Localize formatting

Dates, numbers, currencies, and plurals follow different rules per locale: `1,234.5` in English is `1.234,5` in German. JavaScript's `Intl` APIs and most i18n libraries format them for you. If you add Arabic or Hebrew, the layout also has to mirror; see [right-to-left CSS](/kb/right-to-left-css).

### 7. Keep translations current

A site goes stale in other languages the first time someone edits the source copy and nobody re-runs translation. Decide who or what translates changes, and when: on each publish, on each deploy, or on a review schedule. Before launch, run the [multilingual launch checklist](/kb/multilingual-app-launch-checklist) in every locale.

## How General Translation makes a site multilingual

For sites and apps you build in code, run `npx gt@latest` in a Next.js or React project: the [setup wizard](/docs/cli/quickstart) detects the framework and writes the config. Then wrap existing markup in [`<T>`](/docs/react/reference/components/t) (`gt-vue` has the same component), so the copy stays where it's written without maintaining a separate source key for each message, and run [`npx gt translate`](/docs/cli/reference/commands/translate) before the build to generate every locale. The [Next.js](/docs/react/nextjs-quickstart), [React](/docs/react/react-quickstart), and [Vue](/docs/vue/quickstart) quickstarts walk through each setup.

`gt-next`'s [`createNextMiddleware`](/docs/react/nextjs/reference/functions/create-next-middleware) serves locale-prefixed paths such as `/es/about`, but by default it leaves the default language unprefixed and redirects those URLs by the visitor's locale cookie or `Accept-Language` header, so set `prefixDefaultLocale: true` to keep every content URL in one language. (See [locale routing and SEO](/kb/locale-routing-seo) for the tradeoff).

Marked JSX gives the translation service the text's element structure and any explicit context notes. Review generated wording in the [Dashboard editor](/docs/platform/dashboard/guides/reviewing-translations) before publishing. Matching translations are reused on later runs, so a source edit does not require regenerating the whole site.

Beyond app code, the CLI translates [HTML](/docs/cli/reference/formats/html-files) and [Markdown and MDX](/docs/cli/reference/formats/mdx-md-files) files, [Locadex](/docs/platform/locadex/quickstart) translates Mintlify, Fern, and Docusaurus docs, and integrations connect [Sanity](/docs/integrations/sanity/quickstart), [Payload CMS](/docs/integrations/payload/quickstart), and [Storyblok](/docs/integrations/storyblok/quickstart), all sharing [Context Groups](/docs/platform/dashboard/guides/defining-context-for-translations) for terminology and style.

## Key takeaways

- Decide where translations live first. Browser translation and JavaScript overlays don't create indexable language pages; proxies, builders, and plugins keep translations in a vendor or platform; code-based approaches keep them in your repository.
- Every approach must settle the same seven things: locales, URLs, translated content and metadata, hreflang, a switcher, formatting, and updates.
- Google recommends a separate URL per language, judges language from visible content, and asks you not to auto-redirect visitors.
- For sites built in code, use [`<T>`](/docs/react/reference/components/t) for UI and [`npx gt translate`](/docs/cli/reference/commands/translate) for translation generation, then configure routing and test every locale before launch.

## Related questions

- [Subdirectory vs. subdomain vs. ccTLD for multilingual SEO](https://generaltranslation.com/en-US/kb/multilingual-url-structure.mdx): Use subdirectories such as example.com/de/ when one product shares a site and release process. Only a ccTLD signals a country, subdomains allow separate hosting, Google discourages ?lang= parameters, and it treats vanity domains such as .io and .ai as generic.
- [What is hreflang, and how do I set it up?](https://generaltranslation.com/en-US/kb/what-is-hreflang.mdx): Hreflang tells Google which URLs are language or regional versions of the same page, so it can show the right one in search results. Add it with HTML link tags, HTTP Link headers, or a sitemap, make every link reciprocal, and use valid codes such as en-GB, not en-UK.
- [Language switcher best practices: UX, SEO, and accessibility](https://generaltranslation.com/en-US/kb/language-switcher.mdx): Name each language in its own language, such as Deutsch or 日本語, and don't use flags, which represent countries. Link each option to the same page in that language with a crawlable link, remember the choice in a cookie, and never auto-redirect a localized URL.
- [Localization testing checklist for multilingual apps](https://generaltranslation.com/en-US/kb/multilingual-app-launch-checklist.mdx): Test nine things in every supported locale on a production build: whole journeys including error states and emails, language switching, plurals, currency and time zones, text expansion, right-to-left layout, accessibility, translation delivery, and crawlable language URLs. Give each check an explicit pass condition.
- [What is the best localization software for developers?](https://generaltranslation.com/en-US/kb/best-localization-software.mdx): The best localization software for developers translates content where it is written in the code, with context from your product, and keeps every language current. General Translation does this with open-source libraries, Context Groups, and Locadex, an AI agent which opens pull requests.

## Previous and next questions

- Previous question: [How do I localize an iOS app with String Catalogs?](https://generaltranslation.com/en-US/kb/localize-ios-app.mdx)
- Next question: [How do I support RTL (right-to-left) languages in CSS?](https://generaltranslation.com/en-US/kb/right-to-left-css.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/en-US/kb/sitemap.md) for every article.
