Localization for a whole stack

A string is one key. Not ten.

Translating one product into ten languages is one product, translated. SyncLocale bills per unique key, with unlimited languages and unlimited seats — so adding a language costs nothing, which is the point of adding one.

Strings in your product
2,000
Languages you ship
10
Billed elsewhere, by word
20,000
Billed here, by key
2,000

No card. 500 keys on the trial.

One extractor for every language you actually use.

Frontend, backend and mobile drift apart because each has its own catalogue and its own tool. SyncLocale reads all of them into one set of keys, so an error message written in Go and shown in React is one string with one translation.

A key built from a variable is deliberately invisible — there is no literal to extract, and inventing one would be a key you pay for and never use.

Read the CLI documentation
  • React, Vue, Next.js

    t('auth.login')
  • Go services

    i18n.Translate("user_not_found")
  • Python services

    _("checkout.failed")
  • iOS

    "welcome.title" = "Welcome, %@";
  • Android

    <string name="greeting">Hello %1$s</string>

Machine translation that is checked, and never shipped by accident.

Context goes with the string

The key name, your developer note and the neighbouring strings on the same screen all reach the model. That is what separates a translation from a dictionary lookup.

Tokens are validated, not trusted

A translation that loses {count} or invents {surname} is rejected before it is stored. ICU plurals may be restructured for the target language; the variable may not go missing.

Nothing unreviewed ships silently

Machine output is marked as such and stays out of published dictionaries until somebody chooses to include it. Your users never see a guess you did not approve.

Flat pricing, counted in keys.

Pro

A product and the services behind it.

$49/ month

10,000 keys

Start with Pro

Scale

A platform, or an agency running many.

$149/ month

50,000 keys

Start with Scale