<p>During the initial development of Trilium Notes, internationalisation was not considered as it was meant to be an English-only product.</p><p>As the application and the user base grows, it makes sense to be able to reach out as many people as possible by providing translations in their native language.</p><p>The library used is <ahref="https://www.i18next.com/">i18next</a>.</p><h2>What has been implemented so far</h2><ulclass="todo-list"><li><labelclass="todo-list__label"><inputtype="checkbox"checked="checked"disabled="disabled"><spanclass="todo-list__label__description">Client component-level translations: <ahref="https://github.com/TriliumNext/Notes/pull/248/files">#248</a></span></label></li><li><labelclass="todo-list__label"><inputtype="checkbox"disabled="disabled"><spanclass="todo-list__label__description">Client template-level translations</span></label></li><li><labelclass="todo-list__label"><inputtype="checkbox"disabled="disabled"><spanclass="todo-list__label__description">Server-side translations</span></label></li><li><labelclass="todo-list__label"><inputtype="checkbox"disabled="disabled"><spanclass="todo-list__label__description">Electron translations</span></label></li><li><labelclass="todo-list__label"><inputtype="checkbox"disabled="disabled"><spanclass="todo-list__label__description">Allowing the user to switch the language via options</span></label></li><li><labelclass="todo-list__label"><inputtype="checkbox"disabled="disabled"><spanclass="todo-list__label__description">Integrate with a translation service</span></label></li></ul><h2>Where are the translations?</h2><p>The translations are formatted as JSON files and they are located in <code>src/public/translations</code>. For every supported locale, there is a subdirectory in which there is a <code>translation.json</code> file (e.g. <code>src/public/translations/en/translation.json</code>).</p><h3>Message keys</h3><p>One important aspect is the fact that we are using a key-based approach. This means that each message is identified by an ID rather than a natural-language message (such as the default approach in gettext).</p><p>The key-based approach allows a hierarchical structure. For example, a key of <code>about.title</code> would be added in <code>translation.json</code> as follows:</p><pre><codeclass="language-application-json">{
} </code></pre><p>Follow the <aclass="reference-link type-text"href="Z9N9OKBXXLFW.html">Guidelines</a> when creating a new message.</p><h3>Adding a new locale</h3><p>To add a new locale, go to <code>src/public/translations</code> with your favorite text editor and copy the <code>en</code> directory.</p><p>Rename the copy to the ISO code (e.g. <code>fr</code>, <code>ro</code>) of the language being translated.</p><p>Translations with a country-language combination, using their corresponding ISO code (e.g. <code>fr_FR</code>, <code>fr_BE</code>), has not been tested yet.</p><h3>Changing the language</h3><p>Since the internationalisation process is in its early stages, there is no user-facing way to switch the language.</p><p>To change the language manually, edit <code>src/public/app/services/i18n.js</code> and look for the line containing <code>lng: "en"</code>. Replace <code>en</code> with the desired language code (from the ones available in <code>src/public/translations</code>).</p><h2>Client-side translations</h2><h3>Component-level translations</h3><p>Most of the client translations are present in the various widgets and layouts.</p><p>Translation support has to be added manually for every file.</p><p>The first step is to add the translation import with a relative import. For example, if we are in the <code>src/public/app/widgets/dialogs</code> directory, the import would look as follows:</p><pre><codeclass="language-application-javascript-env-frontend">import { t } from "../../services/i18n.js";</code></pre><p>Afterwards, simply replace the hard-coded message with:</p><pre><codeclass="language-application-javascript-env-frontend">${t("msgid")}</code></pre><p>where <code>msgid</code> is the key of the message being translated.</p><h3>Variables</h3><p>In the translation, enclose the variables with <code>{{</code> and <code>}}</code>:</p><pre><codeclass="language-text-plain">{
"key": "{{what}} is {{how}}"
}</code></pre><p>Then pass the arguments when reading the translation:</p><pre><codeclass="language-text-plain">t('key', { what: 'i18next', how: 'great' })</code></pre><h3>Template-level translations</h3><p>Templates are <code>.ejs</code> files present in <code>src/views</code>, these are used to prepare the root layout for desktop, mobile applications as well as setup (onboarding) and the shared notes view.</p><p>Due to using a different approach, it is not possible yet to translate those files.</p><h2>Server-side translations</h2><p>Currently the server-side messages are not translatable. They will be added as a separate step.</p>