Universally Documentation

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

Translation updates in Astro

A new string is translated in the background after the first page that uses it, and a dashboard edit reaches your running server by a signed push or by a check every 60 seconds per language. A static site picks up both only when you rebuild.

New strings

  1. A page calls t() with text that has no translation. The visitor gets the source text.
  2. After the response, the integration reports the missed strings to Universally in chunks of 500. On runtimes that offer waitUntil, the report finishes after the response is sent.
  3. Universally returns the translations it already has and translates the rest in the background.
  4. The new translations reach your server on a later report (a missed string is reported again on the next render) or when that language reloads.

In practice a new string is translated a second or two after its first render. Reports are not sent during builds.

Dashboard edits

Machine translations do not change a language's cache epoch. Dashboard edits do, and two mechanisms carry them to your server.

Push. Universally sends a signed POST to https://{your project domain}/_universally/revalidate when you:

  • edit a string, verify or unverify it, or delete it
  • restore a revision or retranslate
  • verify or delete in bulk
  • delete a source string
  • clear the cache

The integration answers the request before Astro routing, so you add no page or route. The push times out after 3 seconds and failures are only logged, so for instant edits the endpoint has to be reachable from the internet. Pushes are sent in SDK mode only.

Polling. After a localized response, the integration checks whether a language's cache epoch changed, at most once per revalidateSeconds (60 by default) per language. The check asks for a single row. On a change it reloads that language and logs universally: reloaded N translations for X at cache epoch E. Setting revalidateSeconds to 0 turns polling off, and the server then keeps its translations until a push arrives or it restarts. See Astro integration options.

Edits you make on the Translations screen travel this way. See Edit translations manually.

When translations load

Event What loads
Dev server start Every language's catalog
Build start Every language's catalog
First localized request on a server that ran neither (for example the built Node server) Every language's catalog. That request waits for it.
Push or changed cache epoch The languages that changed

If a language fails to load, the log shows universally: could not preload .... That language is not retried or polled until the process restarts, so fix the cause and restart.

Languages

The list of languages is read once, when your Astro config runs. Adding a language or switching its Live switch on sends no push, so restart the dev server or rebuild before the new prefix works.

Static sites

A static build has no server code after the build: no polling and no push endpoint. Dashboard edits appear only after you rebuild and redeploy. The build itself sends everything it missed in one blocking call, then prints N new strings translated. Rebuild to include them., so a second build puts those strings into the HTML.

Several server instances

Each instance holds its own catalog in memory. A push reaches whichever instance answers it, and the others catch up by polling. Keep revalidateSeconds at a delay you are happy to wait.

When the word limit is reached

Once the project's prepaid words are used, Universally returns only strings it already holds. The integration logs universally: word limit reached, {variant} keeps serving source text once per language. Translated strings keep being served. After you add words, missing strings are reported again on their next render. See Usage limits.

Was this helpful?