<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Localang</title>
    <description>The latest articles on Forem by Localang (@localang).</description>
    <link>https://forem.com/localang</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1852277%2F99d3849b-b26a-4e65-ad5f-97af753bc311.png</url>
      <title>Forem: Localang</title>
      <link>https://forem.com/localang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/localang"/>
    <language>en</language>
    <item>
      <title>Simplify Localization</title>
      <dc:creator>Localang</dc:creator>
      <pubDate>Thu, 08 Aug 2024 21:43:31 +0000</pubDate>
      <link>https://forem.com/localang/simplify-localization-3b20</link>
      <guid>https://forem.com/localang/simplify-localization-3b20</guid>
      <description>&lt;p&gt;Localization is essential yet often cumbersome in modern web development. Managing translation files, ensuring consistency, and integrating updates can become overwhelming, especially in large codebases. Traditional i18n libraries require developers to handle these complexities manually, leading to inefficiencies and potential errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Existing i18n Libraries
&lt;/h2&gt;

&lt;p&gt;Many existing i18n libraries require developers to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manually create and manage JSON files&lt;/strong&gt;: developers have to create and update JSON files for translations, which can be error-prone and time-consuming.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store all translations in one file&lt;/strong&gt;: this can make it difficult to manage translations for large applications, resulting in bloated files that are hard to navigate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use arbitrary keys&lt;/strong&gt;: simple keys that don’t correspond to actual text make it harder to search for specific translations in the codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These challenges add overhead and complexity, making localization a dreaded task.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I'm Handling It
&lt;/h2&gt;

&lt;p&gt;I created a &lt;a href="https://github.com/localang/localang-i18n-js" rel="noopener noreferrer"&gt;JS library&lt;/a&gt; and an eco-system around it that addresses these pain points with features designed to make localization straightforward and hassle-free:&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Translation File Generation
&lt;/h3&gt;

&lt;p&gt;Using an integrated ESLint plugin, &lt;code&gt;localang-i18n-js&lt;/code&gt; automatically generates translation files based on the text in your code. This means no more manual creation or updating of JSON files. The plugin ensures your translation files are always up-to-date and accurate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnfd31i284tdm8uor5bir.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnfd31i284tdm8uor5bir.gif" alt="Image description" width="1954" height="1062"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Localized Translation Files
&lt;/h3&gt;

&lt;p&gt;Translation files are placed right next to the corresponding code files. This localized approach makes it easier to manage translations, as each component or module has its own set of translation files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Text-Based Keys
&lt;/h3&gt;

&lt;p&gt;Instead of using arbitrary keys, &lt;code&gt;localang-i18n-js&lt;/code&gt; uses the actual text as the key. This makes it easy to search for and find specific translations within your codebase. If you see a piece of text in the UI, you can quickly locate it in the code by searching for that exact text.&lt;/p&gt;

&lt;p&gt;For example, if you write &lt;code&gt;i18n('What is love?')&lt;/code&gt; and &lt;code&gt;i18n('{count} left')&lt;/code&gt; in the &lt;code&gt;index.js&lt;/code&gt; file, an &lt;code&gt;index.i18n.js&lt;/code&gt; file will be created next to it with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;makeI18n&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localang-i18n-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// or const { makeI18n } = require('localang-i18n-js');&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keyset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What is love?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What is love?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;ar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{count} left&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nothing left&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;one&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;One left&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;two&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Two left&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;few&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A few left&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;many&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Many left&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;other&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{count} left&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;ar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;one&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;two&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;few&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;many&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;other&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;i18n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeI18n&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyset&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// or module.exports = makeI18n(keyset);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SaaS Integration
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;localang-i18n-js&lt;/code&gt; integrates with a &lt;a href="https://localang.xyz/" rel="noopener noreferrer"&gt;SaaS platform&lt;/a&gt; for managing translations, allowing non-developers to update translations directly within the codebase. This means your localization team can handle updates without needing to involve developers, streamlining the process and reducing the risk of errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Actions for Automation
&lt;/h3&gt;

&lt;p&gt;To further streamline the localization process, &lt;code&gt;localang-i18n-js&lt;/code&gt; has ready to use GitHub Actions for automatic synchronization of translation files. You can set up workflows to pull the latest translations from the translation platform or push new translations to platform directly from your codebase. This automation ensures that your translations are always up-to-date without manual intervention.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>localization</category>
      <category>i18n</category>
    </item>
  </channel>
</rss>
