Symfony中如何在嵌入的JavaScript文件中实现国际化?
Great question! When you're already comfortable with Twig's {% trans %} tags and need to bring that same i18n functionality to your Webpack Encore-bundled JavaScript, there are a few tried-and-true approaches—some even mirror how FOSJsRoutingBundle bridges PHP and JS routing. Let's break them down:
1. Use the Official @symfony/translation JS Library
This is the most modern, Symfony-native approach, perfect if you prefer working with ES modules in your JS code.
Steps to Implement:
- Install the JS dependency:
npm install @symfony/translation - Export your Symfony translations to JSON:
Use Symfony'stranslation:extractcommand to generate JSON files from your existing translation files (XLIFF, YAML, etc.). For example, to extract translations for English and French into yourassets/translationsdirectory:bin/console translation:extract en --format=json --output-dir=assets/translations bin/console translation:extract fr --format=json --output-dir=assets/translations - Initialize the translator in your JS:
Import the library, load your JSON translation files, and start translating just like in Twig:import { Translator } from '@symfony/translation'; import enTranslations from '../translations/messages.en.json'; import frTranslations from '../translations/messages.fr.json'; const translator = new Translator('en'); // Set default locale translator.addResource('json', enTranslations, 'en'); translator.addResource('json', frTranslations, 'fr'); // Use it like Twig's trans filter console.log(translator.trans('hello.world')); console.log(translator.trans('greeting', {'%name%': 'Alice'}, 'messages'));
2. Inject Translations via Twig into a Global Variable
If you only need a handful of translations in JS, this quick-and-dirty method works perfectly (no extra bundles or dependencies required). It mirrors how FOSJsRoutingBundle injects routing data into the global scope.
Implementation:
In your base Twig template, inject translations directly into a window.translations object:
<script> window.translations = { 'hello': '{{ 'hello.world'|trans }}', 'greeting': '{{ 'greeting'|trans({'%name%': 'John'}) }}', // Add more translations as needed }; </script>
Then in your bundled JS, access them directly:
console.log(window.translations.hello); console.log(window.translations.greeting);
Note: This is best for small sets of translations—avoid it if you have dozens/hundreds of strings to keep your template clean.
3. Use willdurand/js-translation-bundle (FOSJsRoutingBundle-style)
This bundle is the classic counterpart to FOSJsRoutingBundle for translations. It generates a JS file containing all your Symfony translations, which you can load in your app and use with a familiar trans() API.
Steps to Implement:
- Install the bundle:
composer require willdurand/js-translation-bundle - Configure the bundle:
Create/modifyconfig/packages/js_translation.yamlto specify which translation domains and locales to export:js_translation: locales: ['en', 'fr'] domains: ['messages', 'validators'] - Generate the JS translation file:
Run this command to generate a JS file that includes your translations:bin/console translation:dump public/js/translations --format=json - Load the file in Webpack Encore:
Either import it directly in your entry JS file:
Or add it as a separate entry inimport '../../public/js/translations/en.js';webpack.config.js:Encore // ... .addEntry('translations', './public/js/translations/en.js') - Use the translator in JS:
The bundle exposes a globalTranslatorobject, so you can use it like this:console.log(Translator.trans('hello.world')); console.log(Translator.trans('greeting', {'%name%': 'Bob'}, 'messages'));
Which Should You Choose?
- Small apps/limited translations: Go with the global Twig injection method—it's simple and requires no extra setup.
- Modern ES module-based apps: Use the official
@symfony/translationJS library for a clean, native integration. - Large apps with lots of shared translations: Use
willdurand/js-translation-bundle—it's battle-tested and syncs perfectly with Symfony's translation system, just like FOSJsRoutingBundle does for routing.
内容的提问来源于stack exchange,提问作者DerpyNerd

