Client-Side vs Server-Side Translation for SEO
Client-side translation swaps text in the browser after the page loads, usually on a single URL, while server-side or pre-rendered translation delivers complete translated HTML on its own URL. Google can render JavaScript and index what it produces, but separate, server-delivered URLs per language are the more reliable foundation for search, with client-side translation best kept as an optional layer on top.
How does client-side translation work?
In a client-side setup, the server sends one HTML document, typically in the source language. A script then fetches translations (from a dictionary, an API or a vendor service) and replaces text nodes in the DOM. The language often depends on a cookie, local storage, the browser's language or a button the visitor presses.
Typical traits:
- One URL serves every language.
- The original-language HTML is what a plain HTTP fetch returns.
- Translated text exists only after JavaScript runs and the right language is selected.
- If the script or the translation service fails, visitors see the source language.
How does server-side or pre-rendered translation work?
With server-side rendering (SSR), the server builds the translated HTML per request, usually on a language-specific URL such as /fr/produits/. With pre-rendering (static generation), the translated HTML files are built ahead of time and served from storage or a CDN. In both cases the first response already contains the translated headings, body text, links, title and meta description, and <html lang> can be set correctly.
| Aspect | Client-side swap | Server-rendered or pre-rendered |
|---|---|---|
| URL per language | Often one shared URL | One URL per language |
| Text in initial HTML | Source language only | Translated |
| Needs JavaScript to see translation | Yes | No |
| Depends on cookie or stored choice | Often | No |
| Title and meta tags translated | Only if script rewrites them | Yes, in the response |
| Failure mode | Falls back to source language | Depends on your hosting and build |
| Works for crawlers without rendering | No | Yes |
What does Googlebot render and index?
Google's JavaScript SEO documentation describes three phases: crawling, rendering and indexing. Googlebot fetches the URL (after checking robots.txt), parses the HTML for links, and queues the page for rendering. A headless Chromium then executes the JavaScript and Google indexes the rendered HTML. Google says a page may stay in the render queue for seconds or longer, and that pages with a non-200 status might skip rendering.
Key consequences for translation:
- Script-inserted text can be indexed. If your script translates on load without user interaction and the content is present when rendering finishes, Google can see it.
- One URL holds one rendered state. Googlebot does not click your language switcher or keep cookies between visits, so it generally indexes whichever default your script produces. We say "generally" because Google does not document every rendering detail; verify with the URL Inspection tool in Search Console.
- Other crawlers differ. Google notes that not all bots can run JavaScript and recommends server-side rendering or pre-rendering because it helps both users and crawlers.
- Links must be real links. Google discovers links in
<a>elements with anhref. Language switchers built from buttons or click handlers without hrefs hide your other language versions. - Do not use fragments. Google's guidance says not to use URL fragments to load different page content. For single-page apps it recommends the History API with real URLs.
Why do separate URLs matter?
Google's guidance on multilingual sites recommends a separate URL for each language version rather than using cookies or browser settings to change the language of a page, and annotating versions with hreflang. It also notes that Googlebot usually crawls from the USA and does not send an Accept-Language header, so dynamic language changes may prevent Google from finding all variations.
With separate URLs each page can have its own title, description, canonical tag and sitemap entry:
<link rel="alternate" hreflang="en" href="https://example.com/en/pricing/" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/tarifs/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/pricing/" />
See the hreflang guide for details. Without separate URLs there is nothing to put in those tags.
What are the risks of client-side-only translation?
- Only one language is indexable. Other languages have no address to rank, link to or share.
- Delayed or incomplete indexing. Rendering is queued; heavy scripts or slow translation requests can mean content is missing when rendering completes.
- Mixed-language snapshots. If some text translates and some does not, the indexed page can be a mix.
- Metadata mismatch. Title and description in the raw HTML remain in the source language unless your script changes them, and snippets may show the wrong language.
- Dependency on a third party. If a translation API is slow or down, the page reverts to the source language. Our article on a translation vendor outage covers what to plan for.
- Performance cost. Extra scripts and a flash of untranslated text affect users. Measure it rather than assuming.
When is client-side translation acceptable?
Client-side translation is reasonable when search visibility in other languages is not the goal or is handled elsewhere:
- Logged-in apps and dashboards that search engines do not index anyway.
- Pages with
noindexsuch as account settings. - A convenience layer over real translated URLs, for example translating user-generated comments in place.
- Prototyping before you commit to a server-side workflow.
If you do use it on indexable pages, make sure the translated state is delivered without user interaction on a dedicated URL, links are real anchors, and you inspect the rendered HTML in Search Console.
How can you get server-side benefits with a resilient design?
A common approach is to keep translations as static bundles, pre-render or cache the translated HTML at build or publish time, and serve it from a CDN so a vendor outage does not blank your pages. This is the design direction we are taking with ResilientLang, which is not released; see static translation bundles and CDN failover for the technique in general terms.
Key takeaways
- Google renders JavaScript and indexes the result, but rendering is queued and Googlebot does not use your language switcher or cookies.
- Use one crawlable URL per language, with hreflang, and deliver translated HTML in the initial response where you can.
- Switchers need real
<a href>links; avoid fragments and cookie-only language selection. - Client-side translation is fine for non-indexed or convenience use, not as the only route to ranking in other languages.
- Test with the URL Inspection tool and compare raw and rendered HTML.
Sources
- JavaScript SEO basics – crawl, render and index phases, render queue, links, SSR and pre-rendering, fragments
- Managing multi-regional and multilingual sites – separate URLs per language, cookies, Googlebot location and Accept-Language
- Tell Google about localized versions of your page – hreflang methods and requirements
- Locale-adaptive pages – how Googlebot crawls and why separate locale URLs are recommended
Frequently asked questions
Can Google index content translated by JavaScript?
Google renders JavaScript with a headless Chromium and indexes the rendered HTML, so script-inserted text can be indexed. But rendering is queued and not guaranteed to be immediate, and a translation that only runs after a user clicks or depends on a cookie may never be seen. Server-rendered translated URLs are more dependable.
Is client-side translation bad for SEO?
Not inherently, but it is risky as the only mechanism for ranking in other languages. If every language shares one URL and the language changes in the browser, search engines have no separate page to index. It is fine as a convenience layer on top of real translated URLs.
What is the difference between server-side rendering and pre-rendering?
Server-side rendering builds the translated HTML on each request. Pre-rendering builds it ahead of time, for example at deploy time, and serves static files. Both deliver complete translated HTML on a distinct URL, which crawlers and users receive without waiting for scripts to run.
Should language be switched with a cookie or a URL?
Use a URL. Google recommends a separate URL per language version rather than changing content by cookie or browser settings, because crawlers do not keep cookies and cannot reliably find versions that exist only behind them.