BazingaJsTranslationBundle
BazingaJsTranslationBundle copied to clipboard
Translator returns translation keys instead of translations
Followed documentation and yet have a problem. Translator returns translation keys instead of translations. Full explanation of the issue at hand on StackOwerflow. What am i missing?
the issue is that you have 2 translators in your JS:
- the global
Translator
variable defined by your loading ofbundles/bazingajstranslation/js/translator.min.js
, which is configured with the appropriate translations (loaded fromurl('bazinga_jstranslation_js')
) - the instance bundled inside your webpack build when importing
bazinga-translator
, which is used by your code, but does not have any loaded translations.
Thank you for your comment @stof.
the issue is that you have 2 translators in your JS:
Now i see the problem. So i should use only one translator.
I think that the one i am importing is the way to go. What should be the config in that case?
Am i correct at thinking that includes in base.html.twig <script src="{{ asset('bundles/bazingajstranslation/js/translator.min.js') }}"></script>
and <script src="{{ url('bazinga_jstranslation_js') }}"></script>
are not needed anymore? Because translator
is imported in test.js
...
But now i have following error in the console:
ReferenceError: Translator is not defined[Learn More]
bazinga-translator
external "Translator":1
__webpack_require__
bootstrap 2b9bb242f4ffe6caa822:19
./assets/js/test.js
test.js:1
__webpack_require__
bootstrap 2b9bb242f4ffe6caa822:19
<anonymous>
bootstrap 2b9bb242f4ffe6caa822:62
<anonymous>
http://127.0.0.1:8000/build/test.js:1:11
Aside
It works if there is<script src="{{ asset('bundles/bazingajstranslation/js/translator.min.js') }}"></script>
in base.html.twig. and <script src="{{ url('bazinga_jstranslation_js', { 'domain': 'TRANSLATION_DOMAIN_NAME', 'locales': 'en,fr,de' }) }}"></script>
in test.html.twig. But i guess in this case it is working with wrong translator, is it not?
Please show an example configuration that works with Webpack.Encore
.
Thank you for your help.
Command yarn encore dev
does not return an error. But i get an error in browsers console. I have read available BazingaJsTranslation
bundle documentation and issues on github
thoroughly, but did not find working solution. Any help with this issue would be greatly appreciated.
@Rikijs <script src="{{ url('bazinga_jstranslation_js', { 'domain': 'TRANSLATION_DOMAIN_NAME', 'locales': 'en,fr,de' }) }}"></script>
does not define a translator. It loads the translations in the translator available in Translator
.
So your suggestion would work well (assuming that you don't use the translator in JS code running on other pages where translations would not be loaded in it of course)
there is no easy way to load the translations into Translator, if you are using it fom webpack, and do not want to have script tags.
you could the what @timwhite sugested here https://github.com/willdurand/BazingaJsTranslationBundle/issues/252#issuecomment-569460207
i have the same problem .. if someone has any sugesions on how to load translations after "import Translator from 'bazinga-translator';" please let us know
this worked for me:
first i used the dump command to dump the translations as json and then i added this in my app.js:
import translator from 'bazinga-translator';
import('../../public/js/bazinga_jstranslation_js/translations/messages/' + document.documentElement.lang).then( function (translations) { translator.fromJSON(translations); } );
import Translator from 'bazinga-translator';
(async () => {
const res = await fetch('/translations/messages.json');
const json = await res.json();
Translator.fromJSON(json);
})();
this works via ajax.
Inspired by @bm-stschneider, we can actually bundle this fairly easily in a component (I didn't need the translation on each page).
// ./components/_translator_webpack.js
/* This async loading is required to make the translator work through webpack */
import Translator from 'bazinga-translator';
(async () => {
const res = await fetch('/translations/messages.json?locales=en,fr');
const json = await res.json();
Translator.fromJSON(json);
})();
export default { Translator }
The important bit in that code are the locales I wish to expose via the async call (in my use case, I was fine exposing all the languages and all the keys).
Then your other script (if needed)
import Translator from './_translator_webpack';
Translator.Translator.trans('translation.key')
Still stuck into the same problem, using the NPM package and loading the translations. Documentation lacks a lot and version 4 doesn't work, it complains about the INTL dependency not found!
Anyways, both @Schyzophrenic and @st-schneider solutions doesn't play well because loading in asynchronously, that is the Translation
will (most probably) used before the loading complets.
@gremo if you want to bundle the translator and translations in your webpack build, the simpliest way is probably to use the dumping command to dump the translations to JSON and import them in your webpack build.
An alternative would be to change the solution from @Schyzophrenic to use a top-level await in the module for the loading of translation, making the module itself async, instead of asynchronously loading translations in a sync module (which indeed causes issues). But this requires using webpack 5 with an experimental feature turned on for now: https://webpack.js.org/configuration/experiments/
I made it work like the following In the twig file, put in your scripts the needed call as described in doc
<html lang="{{ app.request.locale|split('_')[0] }}">
<head>
...
<script src="{{ asset('bundles/bazingajstranslation/js/translator.min.js') }}"></script>
<script src="{{ url('bazinga_jstranslation_js', { 'domain': 'DOMAIN_NAME', 'locales': 'MY_LOCALE' }) }}"></script>
</head>
<body>
<div id="app"></div>
{{ encore_entry_script_tags('app') }}
</body>
</html>
create a small translator.[js|ts]
file
//translator.[js|ts]
module.exports = global.Translator
and in your js files, you can then call it like that
//app.[js|ts]
const Translator = require('./translator');
Translator.trans('id-to-translate')