JavaScript-enabled Translation

Translations directly imported in JavaScript

Write & manage your translations like you always do. Then use them just as easily in JS.

composer require symfony/ux-translator

What Translator gives you

  • The same catalogues

    Translations you already wrote, now in JavaScript.

  • Dumped at build time

    Generated files, no runtime lookup.

  • Only what you use

    Tree-shakeable domains keep the bundle small.

  • Typed parameters

    TypeScript types generated from your catalogues.

  • Intl ready

    Pluralisation and locale switching included.

Symfony Translations in JavaScript

Add Translator to your app.

Use Symfony's translations in JavaScript

hello: 'Hello!'
say_hello: 'Hello {name}!'

# Select
invitation_title: >-
  {organizer_gender, select,
      female   {{organizer_name} has invited you to her party!}
      male     {{organizer_name} has invited you to his party!}
      multiple {{organizer_name} have invited you to their party!}
      other    {{organizer_name} has invited you to their party!}
  }

# Pluralization
num_of_apples: >-
  {apples, plural,
      =0    {There are no apples}
      =1    {There is one apple...}
      other {There are # apples!}
  }

# Ordinal
finish_place: >-
  You finished {place, selectordinal,
      one   {#st}
      two   {#nd}
      few   {#rd}
      other {#th}
  }!

# Date and Time
published_at: 'Published at {publication_date, date} - {publication_date, time, short}'

# Numbers
progress: '{progress, number, percent} of the work is done'
value_of_object: 'This artifact is worth {price, number, ::currency/EUR}'
hello: 'Bonjour !'
say_hello: 'Bonjour {name} !'

# Select
invitation_title: >-
  {organizer_gender, select,
      female   {{organizer_name} t'a invité à sa fête !}
      male     {{organizer_name} t'a invité à sa fête !}
      multiple {{organizer_name} t'a invité à sa fête !}
      other    {{organizer_name} t'a invité à sa fête !}
  }

# Pluralization
num_of_apples: >-
  {apples, plural,
      =0    {Il n'y a pas de pommes}
      =1    {Il y a une pomme...}
      other {Il y a # pommes !}
  }

# Ordinal
finish_place: >-
  Tu as terminé {place, selectordinal,
      one   {#er}
      other {#e}
  } !

# Date and Time
published_at: 'Publié le {publication_date, date} - {publication_date, time, short}'

# Numbers
progress: '{progress, number, percent} du travail est fait'
value_of_object: "Cet artéfact vaut {price, number, ::currency/EUR}"
Symfony logo

UX Translator

import { trans } from '../translator';

trans('hello')
🇬🇧
🇫🇷
import { trans } from '../translator';

trans('say_hello', {
     name: 'Fabien',
}})
🇬🇧
🇫🇷
import { trans } from '../translator';

trans('invitation_title', {
     organizer_gender: 'Fabien',
     organizer_name: 'Clara',
}})
🇬🇧
🇫🇷
import { trans } from '../translator';

trans('num_of_apples', {
     apples: 2,
}})
🇬🇧
🇫🇷
import { trans } from '../translator';

trans('finish_place', {
     place: 2,
}})
🇬🇧
🇫🇷
import { trans } from '../translator';

trans('published_at', {
     publication_date: new Date('2023-04-27 08:12'),
}})
🇬🇧
🇫🇷
import { trans } from '../translator';

trans('progress', {
     progress: 42,
}})
🇬🇧
🇫🇷
import { trans } from '../translator';

trans('value_of_object', {
     price: 30,
}})
🇬🇧
🇫🇷

Dumped at build time

How the catalogues get there.

Nothing is fetched at runtime. A cache warmer writes your catalogues to disk, and your JavaScript imports them like any other module.

Written to disk

Every domain and every locale you configured ends up in one generated module, types included.

var/translations/
├── index.js
└── index.d.ts

The same trans()

Placeholders, pluralisation and locale fallbacks behave the way they do in Twig.

import { trans } from '@symfony/ux-translator';
import { HELLO } from '../translations/messages';

trans(HELLO, { name: 'Hugo' });

Only what you import

Message ids are named exports, so a bundler drops the domains your code never touches.

import { TASK_CREATED } from '../translations';

// the validators domain is never
// imported, so it never ships

Install Translator.

$ composer require symfony/ux-translator

More from Symfony UX.

Translator is one package among many. They share the same Stimulus foundation and install the same way.

Image for the Chart.js UX package

Chart.js

Easy charts with Chart.js

Image for the React UX package

React

Quickly render <React /> components & pass them props.

Image for the Vue.js UX package

Vue.js

Quickly render <Vue /> components & pass them props.

Browse every package

Keep Translator at hand.

Documentation, the people behind it, and where to ask when something does not behave.