Universally Documentation

Step-by-step guides, multilingual SEO tips, and best practices to help you translate and scale your WordPress website.

JavaScript serving mode

In JavaScript mode, one script tag in your site's <head> does the whole job: it renders the language switcher, picks a language for each visitor, and swaps your page text for its translation in the browser. Your URLs never change, so example.com/about is the same address in every language and there is no DNS to set up. The trade-off is that search engines see only your source language.

JavaScript mode is the only mode for Webflow, Framer, Squarespace, Duda, Tilda, Weebly, and Lovable, and one of two choices for Any Website projects.

What gets translated

Universally extracts strings from your page with the same parsers it uses for server-side translation:

  • Text in the page.
  • The <title> and meta content.
  • The placeholder, aria-label, alt, title, and value attributes.

Stored translations, word counting, and glossary rules work the same as in every other mode. The script also sets <html lang> and dir for the chosen language.

What does not

  • Search engines see no translations. Translations exist only in the browser, and crawlers get your source HTML. No hreflang links are added.
  • Only public pages are translated. Universally fetches each page itself, without the visitor's session, so a page behind a login or a password shows its source text.
  • Text that JavaScript adds after the page loads is not translated when it is not in the HTML your server sends. The script re-applies translations to new content for a few seconds after load and on single-page-app navigations, but only for strings it already has.
  • JSON-LD is not translated.
  • Query strings are ignored. ?a=1 and ?a=2 share one set of translations.
  • About 2,000 strings per page is the ceiling. Strings beyond that stay in the source language.
  • Only CSS selector rules apply. On Translation Rules, Exclude CSS Selectors works. Exclude Pages and Exclude Link Localization have no effect in JavaScript mode, and neither does Include CSS Selectors. See Include and exclude CSS selectors.
  • The switcher has no design settings. It sits in the bottom-right corner with flags and language names (top-right on Framer and Lovable).

When the project's prepaid words are used up, new strings stay in the source language and strings already translated keep showing. See Usage limits.

How it works

  1. The script loads. The file s.js is served with a 15 minute cache. While the project is inactive or has no live target language it serves nothing, which is why your site does not change until you add a language.
  2. A language is chosen. A first-time visitor is matched to their browser language automatically. The choice is stored in a cookie named universally_lang for 30 days. Picking a language in the switcher sets the cookie and reloads the page. The Redirect by browser language switch on General Settings has no effect in this mode: the automatic match happens regardless.
  3. The browser sends the page URL. Only the URL and the language go to Universally, never the page content.
  4. Universally fetches the page itself. It requests the URL from your published site anonymously, with no visitor cookies and no login, extracts the strings, translates them, and returns them.
  5. The browser swaps each string in place. Nothing reloads and the address stays the same.

Translations for a page are cached for 24 hours on Universally's side and kept in the visitor's browser storage, so a repeat view has no flicker. Edits on the Translations screen show once that 24 hour cache expires, or straight away after you click Clear translator cache on General Settings, which clears both. See Edit translations manually.

To see how much of a page was translated, add ?uni_debug=1 to its URL and open the browser console.

When to choose subdomains instead

If you want each language on its own address, an Any Website project can move to language subdomains from its Setup page. Moving back is not available yet. See Language subdomains.

Was this helpful?