{"id":5646,"date":"2024-12-12T07:54:44","date_gmt":"2024-12-12T07:54:44","guid":{"rendered":"https:\/\/poeditor.com\/blog\/?p=5646"},"modified":"2024-12-12T07:54:45","modified_gmt":"2024-12-12T07:54:45","slug":"react-localization-i18next","status":"publish","type":"post","link":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/","title":{"rendered":"React localization with i18next: How-to guide"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"823\" height=\"591\" src=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/react-localization-i18next.png\" alt=\"react localization i18next\" class=\"wp-image-5663\" srcset=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/react-localization-i18next.png 823w, https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/react-localization-i18next-300x215.png 300w, https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/react-localization-i18next-768x552.png 768w\" sizes=\"auto, (max-width: 823px) 100vw, 823px\" \/><\/figure>\n\n\n\n<p>If you want to build sites targeting a global audience, React is a great option due to its Virtual DOM, modular structure, and server-side rendering, which allow you to create large-scale applications that support the performance required by a user base across the world. <\/p>\n\n\n\n<p>However, scalability and performance are not enough when it comes to global-level applications; you also need to cater to various audiences who use different languages. <\/p>\n\n\n\n<p>This is where React localization comes into play, helping you adapt your applications for different languages and cultural contexts. To ensure your applications effectively reach a diverse worldwide audience, you need to be well-versed in two concepts: internationalization (i18n) and localization (l10n).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">About internationalization and localization<\/h2>\n\n\n\n<p>Before we get into this React localization guide, we need to understand what <a href=\"\/blog\/localization-vs-internationalization\/\">internationalization and localization<\/a> mean. Internationalization (i18n) is a process carried out during the application development phase to make the application adaptable to different languages and regions.<\/p>\n\n\n\n<p>Localization (l10n), on the other hand, is performed after internationalization, during the deployment phase. Its goal is to adapt an application to a specific language or region by translating text and adjusting number\/date formats.<\/p>\n\n\n<div class=\"call-action my-4 d-flex justify-content-between align-items-md-center gap-4 flex-column flex-lg-row\"><div><h3 class=\"fs-4\">Improve your localization process<\/h3><span class=\"fs-6\">Discover an easy to use and affordable localization app.<\/span><\/div><a class=\"btn btn-b-primary d-flex align-items-center justify-content-center px-4 py-3 flex-shrink-0\" \n\t\t\t\t\thref=\"https:\/\/poeditor.com\/register\/?utm_source=blog&#038;utm_medium=btn&#038;utm_campaign=cta_register\">Get started<\/a><\/div>\n\n\n\n<p>For example, adding support for multi-language capabilities, such as dynamic text rendering and character encoding, is part of internationalization. Translating &#8220;Submit&#8221; to &#8220;Enviar&#8221; for Spanish users and changing &#8220;mm\/dd\/yyyy&#8221; to &#8220;dd\/mm\/yyyy&#8221; for European users are examples of localization.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why should you use the i18next library for React internationalization?<\/h2>\n\n\n\n<p>While you can implement i18n from scratch, it can be a hefty task and an unnecessary effort. It&#8217;s akin to reinventing the wheel, which is something you should avoid in software development. Existing frameworks like i18next greatly simplify the process for several reasons:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>i18next provides pre-built functionalities for managing translations, handling language switching, and formatting dates, numbers, and currencies.<\/li>\n\n\n\n<li>With a standardized structure for managing translations and robust tooling, i18next simplifies updates and reduces the risk of errors during language expansion.<\/li>\n\n\n\n<li>i18next also supports dynamic loading of translations, namespace-based separation, and multi-language fallbacks.<\/li>\n\n\n\n<li>It can handle edge cases such as pluralization, context-based translations, and nested keys, which are challenging to implement manually.<\/li>\n\n\n\n<li>By eliminating the need to write and debug these features from scratch, it allows developers to focus on core application functionality.<\/li>\n<\/ul>\n\n\n\n<p>Compared to the alternatives, i18next shows excellent performance while maintaining the possibility of integration with third-party tools like POEditor.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setting up prerequisites<\/h2>\n\n\n\n<p>For this React localization tutorial, we are going to create a small app demonstrating the functionalities discussed here. You can access it on <a href=\"https:\/\/codesandbox.io\/p\/sandbox\/hardcore-payne-gk6thz\" rel=\"nofollow\">CodeSandbox<\/a>.<\/p>\n\n\n\n<p>For this article, we assume you have the basic idea of React and its key functions.<\/p>\n\n\n\n<p>To start the tutorial, we assume you have a React app. If not you can create one with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx create-react-app my-app<\/code><\/pre>\n\n\n\n<p>Replace &#8220;my-app&#8221; with any name you want for your project.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXd280-mwppI64Iv7H0AfQGY4C0SM3oYpz1D_l5YvVcRIGeKMEMANoCEIZTE0y_Kkey-69-OkuDmrLIz8uAEDvQ0gpXZ9fgf6dmHJVMKiZORjBTR0HtyeUiuTDfBa9O-ZCgyTFbC-A?key=xaOAqVG9BZI7iFYFd2BPzKa5\" alt=\"\"\/><\/figure>\n\n\n\n<p>Then, move towards the folder to initiate our React localization workflow.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd my-app<\/code><\/pre>\n\n\n\n<p>You can also create a React app easily on <a href=\"https:\/\/codesandbox.io\/s\/react-new\" rel=\"nofollow\">Codesandbox<\/a> (which I am using for this article) and try the steps mentioned in this article.<\/p>\n\n\n\n<p>Before going further, we\u2019ll see how to properly maintain the project structure to load the translation files.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">File structure<\/h2>\n\n\n\n<p>To keep things clearer, we are going to explain the file structure for this project now including all the files we are going to create during this article.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"513\" src=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image.png\" alt=\"\" class=\"wp-image-5672\" srcset=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image.png 250w, https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image-146x300.png 146w\" sizes=\"auto, (max-width: 250px) 100vw, 250px\" \/><\/figure>\n\n\n\n<p>The <strong>public\/index.html<\/strong>, <strong>src\/App.js<\/strong>, <strong>src\/index.js<\/strong>, and <strong>package.json<\/strong> files come by default when you create a React app. They are standard files in a React project, and we assume you are already familiar with their roles.<\/p>\n\n\n\n<p>As the first step, we have to create the translation files where we are going to add the localized text. For the sample app, we are creating translation files for German, English, and Spanish.<\/p>\n\n\n\n<p>To create translation files, first, create a <strong>locales <\/strong>folder inside the <strong>public <\/strong>directory. Then create separate folders for each language. In this case, they will be named <strong>de<\/strong>, <strong>en<\/strong>, and <strong>es<\/strong>. These folder names are standard acronyms recognized by i18next for these locales. Now, create a translation.json file under each folder, where we are going to include localized texts as key-value pairs.<\/p>\n\n\n\n<p>In this React localization tutorial, we handle translation files manually. There are third-party libraries that support managing translation files automatically, such as <a href=\"https:\/\/i18next.github.io\/i18next-scanner\/\" rel=\"nofollow\">i18next-scanner<\/a>. It will scan your React components or other JavaScript files to identify the translation keys and create or update your translation files automatically.<\/p>\n\n\n\n<p>However, to better understand what happens under the hood, I recommend managing the translation files manually for this tutorial.<\/p>\n\n\n\n<p>The <strong>src\/components\/<\/strong> folder will hold the React components that make up the app. You will learn about each component we create as you follow along with the article.<\/p>\n\n\n\n<p>You also have to create the <strong>src\/i18n.js<\/strong> file, which sets up i18next, initializes the translations, and configures it to work with the app.<\/p>\n\n\n\n<p>So what\u2019s next? As for all software, we need to get the dependencies and libraries required for our task.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installing required libraries and dependencies<\/h2>\n\n\n\n<p>To internationalize your React app with i18next, you need four main libraries, which can be installed using the following command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install i18next react-i18next i18next-http-backend i18next-browser-languagedetector<\/code><\/pre>\n\n\n\n<p>Let\u2019s understand why each of these libraries is necessary.<\/p>\n\n\n\n<p><strong>i18next<\/strong>: The core library that handles all internationalization tasks, like managing translations, formatting, and language switching.<\/p>\n\n\n\n<p><strong>react-i18next<\/strong>: Integrates i18next with React, providing features i18next can\u2019t do alone. For example, it provides React-Specific hooks like <strong><em>useTranslation <\/em><\/strong>for accessing translations directly in React components.&nbsp;<\/p>\n\n\n\n<p><strong>i18next-http-backend<\/strong>: Fetches translation files from an external source. This feature is essential when translations are managed dynamically.<\/p>\n\n\n\n<p><strong>i18next-browser-languagedetector<\/strong>: Automatically detects the user&#8217;s language based on browser settings.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Getting started<\/h2>\n\n\n\n<p>Now, let\u2019s get our hands dirty and start writing code. To set up i18next in your React application, you need to create and configure the localization instance, load the necessary modules, and integrate it into your app.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 1. Create i18n.js for configuration<\/h4>\n\n\n\n<p>In your project\u2019s src directory, create a new file called<strong> i18n.js<\/strong> to initialize and configure <strong>i18next<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import i18n from \"i18next\";\nimport { initReactI18next } from \"react-i18next\";\nimport HttpApi from \"i18next-http-backend\";\nimport LanguageDetector from \"i18next-browser-languagedetector\";\n\n\ni18n\n  .use(HttpApi)\n  .use(LanguageDetector)\n  .use(initReactI18next)\n  .init({\n    fallbackLng: \"en\",\n    debug: true,\n    interpolation: {\n      escapeValue: false,\n    },\n    backend: {\n      loadPath: \"\/locales\/{{lng}}\/{{ns}}.json\",\n    },\n  });\n\n\n\nexport default i18n;\n<\/code><\/pre>\n\n\n\n<p>Let us give you a brief idea of what the above code does. The <strong><em>.use<\/em><\/strong> method in i18next is used to register plugins or middleware that extend the functionality of i18next. Each<strong><em> .use<\/em><\/strong> call adds a specific feature or capability to the i18next instance.<\/p>\n\n\n\n<p><strong>.use(HttpBackend) &#8211; <\/strong>Registers the <strong>HttpBackend<\/strong> plugin to load translation files dynamically.<\/p>\n\n\n\n<p><strong>.use(LanguageDetector) &#8211;<\/strong><strong> <\/strong>Registers the <strong>LanguageDetector<\/strong> plugin, which automatically detects the user&#8217;s preferred language (e.g., from browser settings, cookies, or query parameters).<\/p>\n\n\n\n<p><strong>.use(initReactI18next) &#8211;<\/strong><strong> <\/strong>Registers the <strong>React integration plugin<\/strong> to use react withi18next. It also offers features like React hooks (<strong>useTranslation<\/strong>) and components (<strong>&lt;Trans&gt;<\/strong>) for managing translations in React components.<\/p>\n\n\n\n<p><strong>.init()<\/strong> method sets up the i18next instance with all the required configuration options. It specifies how translations are loaded, which language to fall back to, and how dynamic placeholders are handled.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2. Import i18n.js in src\/index.js<\/h4>\n\n\n\n<p>To ensure your application uses the i18n.js configuration, import it into your entry point file (src\/index.js).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { StrictMode } from \"react\";\nimport { createRoot } from \"react-dom\/client\";\n\n\nimport App from \".\/App\";\nimport \".\/i18n\";\n\n\nconst rootElement = document.getElementById(\"root\");\nconst root = createRoot(rootElement);\n\n\nroot.render(\n  &lt;StrictMode&gt;\n    &lt;App \/&gt;\n  &lt;\/StrictMode&gt;\n);\n&nbsp;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 3. Use Suspense for Asynchronous loading<\/h4>\n\n\n\n<p>Since translation files may be loaded asynchronously (especially with HTTP), wrap your application in a <strong><em>Suspense <\/em><\/strong>component to handle loading states. You need to update the <strong>src\/App.js<\/strong>&nbsp; file with the below code.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import \".\/styles.css\";\n\n\nimport { Suspense } from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\n\nfunction App() {\n  const { t, i18n } = useTranslation();\n  return (\n    &lt;div&gt;\n      &lt;h1&gt;&lt;\/h1&gt;\n    &lt;\/div&gt;\n  );\n}\nexport default function WrappedApp() {\n  return (\n    &lt;Suspense fallback=\"...loading\"&gt;\n      &lt;App \/&gt;\n    &lt;\/Suspense&gt;\n  );\n}\n<\/code><\/pre>\n\n\n\n<p>Here, we imported the libraries and used the Suspense component to render a fallback (Loading translations\u2026) while translations were being fetched. The useTranslation hook is used to access the t function for performing translations.<\/p>\n\n\n\n<p>Now, we may directly move to perform the translation. But wait a minute; we haven\u2019t yet added anything to the translation.json file. Let&#8217;s add some basic content to the JSON for initialization. (Of course, you can get more structured .json files on the internet.)<\/p>\n\n\n\n<p>Example: en\/translation.json<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"main\": {\n    \"welcome\": \"Welcome to our app!\",\n    \"description\": \"This is a localized React application.\"\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Example: es\/translation.json<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"main\": {\n    \"welcome\": \"\u00a1Bienvenido a nuestra aplicaci\u00f3n!\",\n    \"description\": \"Esta es una aplicaci\u00f3n React localizada.\"\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Example: de\/translation.json<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"main\": {\n    \"welcome\": \"Willkommen in unserer App!\",\n    \"description\": \"Dies ist eine lokalisierte React-Anwendung.\"\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Here, the header (welcome) and description (description) are keys in the translation file representing text elements in your React application. These keys act as identifiers for the respective content, allowing i18next to replace them with the appropriate translations depending on the selected language. The main is the parent key, often used to follow a proper structure for the translation file.<\/p>\n\n\n\n<p>Let\u2019s see how the translation works.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Text translation<\/h2>\n\n\n\n<p>To initialize the translation and visualize the difference, you may easily change the app function in the <strong>App.js<\/strong> file below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function App() {\n  const { t } = useTranslation();\n\n\n  return (\n    &lt;div&gt;\n      &lt;h1&gt;{t('main.welcome')}&lt;\/h1&gt;\n      &lt;p&gt;{t('main.description')}&lt;\/p&gt;\n    &lt;\/div&gt;\n  );\n}\n<\/code><\/pre>\n\n\n\n<p><br>As mentioned, the <strong><em>\u2018t\u2019 <\/em><\/strong>function creates the magic, and you can quickly note it by running the code. For instance, add the code below to the i18n.js file to check the translation.<\/p>\n\n\n\n<p><strong><em>i18n.changeLanguage(&#8216;es&#8217;);<\/em><\/strong><br><strong><em>export default i18n;<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"420\" height=\"117\" src=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image1.png\" alt=\"\" class=\"wp-image-5648\" srcset=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image1.png 420w, https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image1-300x84.png 300w\" sizes=\"auto, (max-width: 420px) 100vw, 420px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"627\" height=\"130\" src=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image4.png\" alt=\"\" class=\"wp-image-5649\" srcset=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image4.png 627w, https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image4-300x62.png 300w\" sizes=\"auto, (max-width: 627px) 100vw, 627px\" \/><\/figure>\n\n\n\n<p>But is it a good approach to alter the <strong>App.js<\/strong> directly? As developers, it is best practice to keep individual files\/classes. Functions for each task, right? So from this stage onwards, we\u2019ll maintain separate files under a folder called components(create it under src) for each par and add them correctly to the <strong>App.js<\/strong> file.<\/p>\n\n\n\n<p>Let\u2019s continue with our initial translation.<\/p>\n\n\n\n<p>We\u2019ll create a file called<strong> Welcome.js<\/strong> and add the initial translation codes as below.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\n\nconst Welcome = () =&gt; {\n  const { t } = useTranslation();\n\n\n  return (\n    &lt;div&gt;\n      &lt;h1&gt;{t(\"main.welcome\")}&lt;\/h1&gt;\n      &lt;p&gt;{t(\"main.description\")}&lt;\/p&gt;\n    &lt;\/div&gt;\n  );\n};\n\n\nexport default Welcome;\n<\/code><\/pre>\n\n\n\n<p>Note that you must alter the <strong>app.js<\/strong> file like below to integrate the <strong>welcome.js<\/strong> file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import \".\/styles.css\";\n\n\nimport { Suspense } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport Welcome from \".\/components\/welcome\"; \/\/ import the welcome package\nconst App = () =&gt; {\n  return (\n    &lt;div&gt;\n      &lt;Welcome \/&gt; \/\/ call the welcome function\n    &lt;\/div&gt;\n  );\n};\nexport default function WrappedApp() {\n  return (\n    &lt;Suspense fallback=\"Loading translations...\"&gt;\n      &lt;App \/&gt;\n    &lt;\/Suspense&gt;\n  );\n}\n\n<\/code><\/pre>\n\n\n\n<p>If you run the app, you will get the same output as the images above. You need to import and call the specific functions similarly throughout the process.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Number and date format translation<\/h2>\n\n\n\n<p>We are done with text translation. Let\u2019s see how the numbers and dates can be easily handled using i18next in React.&nbsp;<\/p>\n\n\n\n<p>We\u2019ll need to install an additional library called Luxon, which makes working with DateTime in JavaScript easy. Install it using <strong><em>npm install luxon<\/em><\/strong>.<\/p>\n\n\n\n<p>As the next step, create a file named <strong>DateAndNumber.js<\/strong> in <strong>src\/components<\/strong> and add the below code to that file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\n\nconst DateAndNumber = () =&gt; {\n  const { t } = useTranslation();\n\n\n  const today = new Date();\n  const price = 1234.56;\n\n\n  return (\n    &lt;div&gt;\n      &lt;p&gt;{t(\"main.currency\", { value: price })}&lt;\/p&gt;\n      &lt;p&gt;{t(\"main.date\", { value: today })}&lt;\/p&gt;\n    &lt;\/div&gt;\n  );\n};\n\n\nexport default DateAndNumber;\n<\/code><\/pre>\n\n\n\n<p>Then call the functional component in <strong>App.js<\/strong> like we did for <em>Welcome<\/em>.&nbsp;<\/p>\n\n\n\n<p>Wait, have we completed the task? We still need to know what about the translation file. We need to add the currency and date there.<\/p>\n\n\n\n<p>So, in the translation file, please add the respective codes under the main branch of each <strong><em>translation.json<\/em><\/strong> file in all the language folders; I\u2019ll show the altered code below for the <strong>en<\/strong>, <strong>es<\/strong>, and <strong>de<\/strong> files.<\/p>\n\n\n\n<p>For en,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"main\": {\n    \"welcome\": \"Welcome to our app!\",\n    \"description\": \"This is a localized React application.\"\n    \"currency\": \"{{value, currency(USD)}}\",\n    \"date\": \"{{value, datetime}}\",\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>For es,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"main\": {\n    \"welcome\": \"\u00a1Bienvenido a nuestra aplicaci\u00f3n!\",\n    \"description\": \"Esta es una aplicaci\u00f3n React localizada.\",\n    \"currency\": \"{{value, currency(EUR)}}\",\n    \"date\": \"{{value, datetime}}\",\n \n  }\n}\n<\/code><\/pre>\n\n\n\n<p>For de,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"main\": {\n    \"welcome\": \"Willkommen in unserer App!\",\n    \"description\": \"Dies ist eine lokalisierte React-Anwendung.\",\n    \"currency\": \"{{value, currency(EUR)}}\",\n    \"date\": \"{{value, datetime}}\",\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Now you can see the following outputs.<\/p>\n\n\n\n<p><strong><em>For English<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"443\" height=\"206\" src=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image8.png\" alt=\"\" class=\"wp-image-5651\" srcset=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image8.png 443w, https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image8-300x140.png 300w\" sizes=\"auto, (max-width: 443px) 100vw, 443px\" \/><\/figure>\n\n\n\n<p><strong><em>For Spanish<\/em><\/strong><br><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"622\" height=\"201\" src=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image3.png\" alt=\"\" class=\"wp-image-5652\" srcset=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image3.png 622w, https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image3-300x97.png 300w\" sizes=\"auto, (max-width: 622px) 100vw, 622px\" \/><\/figure>\n\n\n\n<p>Similar to the Date and Time, you must add the respective key to the<strong> translation.json<\/strong> file for the upcoming tasks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pluralization<\/h2>\n\n\n\n<p>Pluralization adjusts text based on the quantity of an item. Here, we count the items that are added to the cart, and for that, we first create a <strong>Cart.js<\/strong> file in the folder <strong>src\/components<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\n\nconst Cart = ({ itemCount }) =&gt; {\n  const { t } = useTranslation();\n\n\n  return &lt;p&gt;{t(\"main.cart\", { count: itemCount })}&lt;\/p&gt;;\n};\n\n\nexport default Cart;<\/code><\/pre>\n\n\n\n<p>Add the Cart component to <strong>App.js<\/strong> as well.&nbsp;<\/p>\n\n\n\n<p>In the<strong> App.js return<\/strong>, you need to add the cart as below, where we need to mention the item_count.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;Cart itemCount={2} \/&gt;<\/code><\/pre>\n\n\n\n<p>In the translation.json file, we need to add the cart part below.<\/p>\n\n\n\n<p>For en,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"cart_one\": \"You have {{count}} item in your cart.\",\n\"cart_other\": \"You have {{count}} items in your cart.\",\n<\/code><\/pre>\n\n\n\n<p>For es,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"cart_one\": \"Tienes {{count}} art\u00edculo en tu carrito.\",\n\"cart_other\": \"Tienes {{count}} art\u00edculos en tu carrito.\",\n<\/code><\/pre>\n\n\n\n<p>For de,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> \"cart_one\": \"Sie haben {{count}} Artikel in Ihrem Warenkorb.\",\n \"cart_other\": \"Sie haben {{count}} Artikel in Ihrem Warenkorb.\",\n<\/code><\/pre>\n\n\n\n<p>Where is the <strong>cart_one <\/strong>and <strong>cart_other <\/strong>in the <strong>Cart.js<\/strong> code? Here, the i18next gives another great solution: the <strong><em>t<\/em><\/strong> function automatically selects the appropriate translation key (<strong>cart_one<\/strong> or <strong>cart_plural<\/strong>) based on the value of the count.&nbsp;<\/p>\n\n\n\n<p>Rather than changing the item count manually, we could also increase the count with a mouse click. You must add the state and mouseclick function to the text, as they usually add the mouseclick in React. You can leave this part if you don\u2019t need it.&nbsp;<\/p>\n\n\n\n<p>Alter <strong>Cart.js<\/strong> as below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\n\nconst Cart = ({ itemCount, addItemToCart }) =&gt; {\n  const { t } = useTranslation();\n\n\n  return (\n    &lt;div&gt;\n      {\/* Display the current count of items in the cart *\/}\n      &lt;p&gt;{t(\"main.cart\", { count: itemCount })}&lt;\/p&gt;\n\n\n      {\/* Button to add an item to the cart *\/}\n      &lt;button onClick={addItemToCart}&gt;+1 Item&lt;\/button&gt;\n    &lt;\/div&gt;\n  );\n};\n\n\nexport default Cart;<\/code><\/pre>\n\n\n\n<p><br>Then, alter the<strong> App.js<\/strong> file as below. For your understanding, the respective comments have also been added to the modified part.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import \".\/styles.css\";\n\n\nimport { Suspense, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport Welcome from \".\/components\/Welcome\";\nimport DateAndNumber from \".\/components\/DateAndNumber\";\nimport Cart from \".\/components\/Cart\";\nimport Greeting from \".\/components\/Greeting\";\n\n\nconst App = () =&gt; {\n  \/\/ State for managing item count in the cart\n  const &#091;itemCount, setItemCount] = useState(10);\n\n\n  \/\/ Function to increase item count\n  const addItemToCart = () =&gt; {\n    setItemCount(itemCount + 1);\n  };\n\n\n  return (\n    &lt;div&gt;\n      &lt;Cart itemCount={itemCount} addItemToCart={addItemToCart} \/&gt;\n\n\n    &lt;\/div&gt;\n  );\n};\n\n\nexport default function WrappedApp() {\n  return (\n    &lt;Suspense fallback=\"Loading translations...\"&gt;\n      &lt;App \/&gt;\n    &lt;\/Suspense&gt;\n  );\n}\n\n<\/code><\/pre>\n\n\n\n<p>Great, now you know how to handle the pluralization.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Interpolation<\/h2>\n\n\n\n<p>So far, we\u2019ve been hardcoding all the content in the translation files. But what if need to include variables, such as user names or dynamic data, in these translations? This is where interpolation comes in. It allows you to insert dynamic values into your translations. Let\u2019s see how it works.<\/p>\n\n\n\n<p>Here, I am going to greet a person with his name. So, I created a file called <strong>Greeting.js<\/strong> in the folder <strong>src\/components<\/strong> and added the code below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\n\nconst Greeting = ({ name }) =&gt; {\n  const { t } = useTranslation();\n\n\n  return &lt;p&gt;{t(\"main.greeting\", { name })}&lt;\/p&gt;;\n};\n\n\nexport default Greeting;<\/code><\/pre>\n\n\n\n<p>The t(&#8220;main.greeting&#8221;, { name }) function fetches the translation associated with the key main.greeting from your translation files. The { name } object is passed as a dynamic value that will replace placeholders in the translation text.<\/p>\n\n\n\n<p>In our translations file, we will include the main.greeting key as shown below.<\/p>\n\n\n\n<p>For en,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"greeting\": \"Hallo, {{name}}! Willkommen in der App.\"<\/code><\/pre>\n\n\n\n<p>For es,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"greeting\": \"Bonjour, {{name}}! Bienvenue dans l'application.\"<\/code><\/pre>\n\n\n\n<p>Then you have to add the Greeting component to <strong>App.js&nbsp; <\/strong>and change the name using the below code to see the output<strong>.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;Greeting name=\"Alan\" \/&gt;<\/code><\/pre>\n\n\n\n<p>Output<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"692\" height=\"248\" src=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image5-1-e1733929672640.png\" alt=\"react localization i18next\" class=\"wp-image-5653\" srcset=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image5-1-e1733929672640.png 692w, https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image5-1-e1733929672640-300x108.png 300w\" sizes=\"auto, (max-width: 692px) 100vw, 692px\" \/><\/figure>\n\n\n\n<p>Now, if you want to change the name, you only need to update it in one place: &lt;Greeting name=&#8221;name&#8221; \/&gt;. However, if you didn\u2019t use interpolation and directly hardcoded the name in the translation.json file, you would need to update every instance of the name across all translation.json fields whenever you want to make a change.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Language switcher<\/h2>\n\n\n\n<p>A language switcher is a feature that allows users to switch between different languages as they wish.&nbsp;<\/p>\n\n\n\n<p>In our app, we still have to change the language manually using<strong><em> i18n.changeLanguage<\/em><\/strong>. This is not something your website visitors can do. Let\u2019s give the users an option to choose their preferred language.<\/p>\n\n\n\n<p>First, create a Language switcher component named <strong>LanguageSwitcher.js<\/strong> in the <strong>src\/components<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\n\n\nconst LanguageSwitcher = () =&gt; {\n  const { i18n } = useTranslation();\n\n\n  const changeLanguage = (lng) =&gt; {\n    i18n.changeLanguage(lng); \/\/ Change language dynamically\n  };\n\n\n  return (\n    &lt;div className=\"language-switcher\"&gt;\n      &lt;button onClick={() =&gt; changeLanguage(\"en\")}&gt;English&lt;\/button&gt;\n      &lt;button onClick={() =&gt; changeLanguage(\"es\")}&gt;Espa\u00f1ol&lt;\/button&gt;\n      &lt;button onClick={() =&gt; changeLanguage(\"de\")}&gt;Deutsch&lt;\/button&gt;\n    &lt;\/div&gt;\n  );\n};\n\n\nexport default LanguageSwitcher;<\/code><\/pre>\n\n\n\n<p>Here, the <strong><em>useTranslation <\/em><\/strong>hook provides access to i18next&#8217;s translation functions and the current language. The button function creates a clickable icon for a specific language. To complete the setup, add the <strong><em>LanguageSwitcher <\/em><\/strong>component to the <strong>App.js<\/strong> file.<\/p>\n\n\n\n<p>Here is the final output of our app. You can change the language by clicking the button relevant to the desired language.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"653\" height=\"391\" src=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image2.png\" alt=\"\" class=\"wp-image-5654\" srcset=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image2.png 653w, https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/image2-300x180.png 300w\" sizes=\"auto, (max-width: 653px) 100vw, 653px\" \/><\/figure>\n\n\n\n<p>If you want to see these functionalities and the complete code in action, you can visit the <a href=\"https:\/\/codesandbox.io\/p\/sandbox\/hardcore-payne-gk6thz\" rel=\"nofollow\">CodeSandbox here<\/a>.<\/p>\n\n\n\n<p>Great! Now, you have learned the basic concepts of i18next-react in the localization process. Let\u2019s consider some parts you need to consider while working with i18next.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Best practices to follow<\/h2>\n\n\n\n<p>While building apps, it is always great to have proper practices. In the case of i18next, we need to give extra care to certain parts in customizing the application as it might affect the integrity of their native language and cultural landscapes. We\u2019ll see the best practices to handle the 18next here.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Avoid hardcoding text directly and <strong>use descriptive keys<\/strong>.&nbsp; As discussed earlier, using the<strong><em> \u2018t\u2019<\/em><\/strong> to mention a specific phrase or language that can later be quickly adapted to further languages with JSON files is essential.&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>For example, instead of hardcoding text like this:<strong><em> &lt;button&gt;Submit&lt;\/button&gt;<\/em><\/strong>, Use a translation key: <strong><em>&lt;button&gt;{t(&#8216;buttons.submit&#8217;)}&lt;\/button&gt;<\/em><\/strong> and add <strong><em>&#8220;submit&#8221;: &#8220;Submit&#8221;<\/em><\/strong> in your <strong>en\/translation.json<\/strong> file under <strong>\u201cbuttons\u201d<\/strong> parent key.<\/p>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li>Add a default language in the<strong> i18n.js<\/strong> code file using the <strong><em>fallbackLng<\/em><\/strong> function. For example, we used <strong><em>(fallbackLng: &#8216;en\u2019)<\/em><\/strong> in our code.<\/li>\n<\/ol>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>Rather than adding all the language JSON files, using only the required files is always good for reducing app bundle size, increasing performance, and more effortless organization.&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li>Finally, before publishing your app, it is always important to check the translation thoroughly because a single letter might change the meaning of a language.&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>Now that you have learned to use I18next, let&#8217;s look at another straightforward way to do the translations with POEditor.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Simplify React localization using POEditor<\/h2>\n\n\n\n<p>Translating each of your keywords to the desired language is a hectic process and mostly leads to errors.&nbsp; To avoid mistakes and ease your process, POEditor can help simplify the translation process.<\/p>\n\n\n\n<p>POEditor allows you to upload your translation files, manage languages collaboratively, and automate the import\/export of translations. Let\u2019s look at it in detail.<\/p>\n\n\n\n<p>First, you need to log in to your POEditor account. If you don&#8217;t have an account, you can create one using <a href=\"\/register\/\">this link<\/a> and then follow the steps below:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Integrate POEditor with Git<\/strong>. The easiest way to connect POEditor with your React app is to link your repository to the POEditor project. Go to the Integrations section in POEditor and connect it to your Git hosting platform (e.g., GitHub, GitLab, Bitbucket) to synchronize your translation files with your repository. This feature is available starting with the <a href=\"\/pricing\/\">Plus plan<\/a>.<\/li>\n\n\n\n<li><strong>Link translation files<\/strong>. Select your React localization project in POEditor, choose a language, and link it to the corresponding<strong> translation.json<\/strong> file in your repository by specifying the repo, branch, and file. Repeat this process for all language files in your React app.<\/li>\n\n\n\n<li><strong>Import keys and translations<\/strong>. Use the &#8220;Import terms and translations&#8221; option to upload your keys and source language translations. You can also set a default reference language in POEditor.<\/li>\n\n\n\n<li><strong>Export translations<\/strong>. After completing translations in POEditor, export the updated strings to your repository to update the respective translation.json files.<\/li>\n\n\n\n<li><strong>Automate with webhooks<\/strong>. Set up webhooks to sync terms and translations automatically between your repository and POEditor whenever changes are made.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>In this React localization guide, we looked at how to use i18next, a robust package for translation requirements, to localize React apps. Text translation, date and number formatting, pluralization, interpolation, and building a language switcher were among the essential topics we discussed. These methods were used to create a React application that was straightforward but scalable to a larger global audience.<\/p>\n\n\n\n<p>We also showed how to incorporate POEditor, our robust translation management system, into the React localization process. We streamlined the process of managing numerous languages by utilizing its uploading, managing, and automated translation tools. This made it simpler to work with translators and ensure consistency across projects.<\/p>\n\n\n\n<p>POEditor and i18next work together to guarantee that your application is globally available and easy to use.<\/p>\n\n\n<div class=\"call-action my-4 d-flex justify-content-between align-items-md-center gap-4 flex-column flex-lg-row\"><div><h3 class=\"fs-4\">Ready to power up localization?<\/h3><span class=\"fs-6\">Subscribe to the POEditor platform today!<\/span><\/div><a class=\"btn btn-b-primary d-flex align-items-center justify-content-center px-4 py-3 flex-shrink-0\" \n\t\t\t\t\thref=\"https:\/\/poeditor.com\/pricing\/?utm_source=blog&#038;utm_medium=btn&#038;utm_campaign=cta_pricing\">See pricing<\/a><\/div>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you want to build sites targeting a global audience, React is a great option due to its Virtual DOM, modular structure, and server-side rendering, which allow you to create large-scale applications that support the performance required by a user base across the world. However, scalability and performance are not enough when it comes to [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-5646","post","type-post","status-publish","format-standard","hentry","category-tutorials"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>React localization with i18next: How-to guide - POEditor Blog<\/title>\n<meta name=\"description\" content=\"Check out our React localization tutorial on how to use i18next, a robust package for translation requirements, to localize React apps.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/poeditor.com\/blog\/react-localization-i18next\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"React localization with i18next: How-to guide - POEditor Blog\" \/>\n<meta property=\"og:description\" content=\"Check out our React localization tutorial on how to use i18next, a robust package for translation requirements, to localize React apps.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/poeditor.com\/blog\/react-localization-i18next\/\" \/>\n<meta property=\"og:site_name\" content=\"POEditor Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/POEditor\" \/>\n<meta property=\"article:published_time\" content=\"2024-12-12T07:54:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-12-12T07:54:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/react-localization-i18next.png\" \/>\n\t<meta property=\"og:image:width\" content=\"823\" \/>\n\t<meta property=\"og:image:height\" content=\"591\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"POEditor\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@poeditor\" \/>\n<meta name=\"twitter:site\" content=\"@poeditor\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"POEditor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/\"},\"author\":{\"name\":\"POEditor\",\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/#\\\/schema\\\/person\\\/db77eb2d09539eaac83dcd8f2af06b17\"},\"headline\":\"React localization with i18next: How-to guide\",\"datePublished\":\"2024-12-12T07:54:44+00:00\",\"dateModified\":\"2024-12-12T07:54:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/\"},\"wordCount\":3075,\"publisher\":{\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/react-localization-i18next.png\",\"articleSection\":[\"Tutorials\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/\",\"url\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/\",\"name\":\"React localization with i18next: How-to guide - POEditor Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/react-localization-i18next.png\",\"datePublished\":\"2024-12-12T07:54:44+00:00\",\"dateModified\":\"2024-12-12T07:54:45+00:00\",\"description\":\"Check out our React localization tutorial on how to use i18next, a robust package for translation requirements, to localize React apps.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/#primaryimage\",\"url\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/react-localization-i18next.png\",\"contentUrl\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/react-localization-i18next.png\",\"width\":823,\"height\":591,\"caption\":\"react localization i18next\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/react-localization-i18next\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"React localization with i18next: How-to guide\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/\",\"name\":\"POEditor Blog\",\"description\":\"All about translation and localization management\",\"publisher\":{\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/#organization\",\"name\":\"POEditor\",\"url\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/logo_head_512_transparent.png\",\"contentUrl\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/logo_head_512_transparent.png\",\"width\":512,\"height\":512,\"caption\":\"POEditor\"},\"image\":{\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/POEditor\",\"https:\\\/\\\/x.com\\\/poeditor\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/poeditor\\\/\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCXAk1u8N49VRMAqNneENCFA\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/#\\\/schema\\\/person\\\/db77eb2d09539eaac83dcd8f2af06b17\",\"name\":\"POEditor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/95bca2c465fe6134f210cb2f2fbed4f71bf37833fb285624320e808c865695c1?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/95bca2c465fe6134f210cb2f2fbed4f71bf37833fb285624320e808c865695c1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/95bca2c465fe6134f210cb2f2fbed4f71bf37833fb285624320e808c865695c1?s=96&d=mm&r=g\",\"caption\":\"POEditor\"},\"url\":\"https:\\\/\\\/poeditor.com\\\/blog\\\/author\\\/poeditor\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"React localization with i18next: How-to guide - POEditor Blog","description":"Check out our React localization tutorial on how to use i18next, a robust package for translation requirements, to localize React apps.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/","og_locale":"en_US","og_type":"article","og_title":"React localization with i18next: How-to guide - POEditor Blog","og_description":"Check out our React localization tutorial on how to use i18next, a robust package for translation requirements, to localize React apps.","og_url":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/","og_site_name":"POEditor Blog","article_publisher":"https:\/\/www.facebook.com\/POEditor","article_published_time":"2024-12-12T07:54:44+00:00","article_modified_time":"2024-12-12T07:54:45+00:00","og_image":[{"width":823,"height":591,"url":"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/react-localization-i18next.png","type":"image\/png"}],"author":"POEditor","twitter_card":"summary_large_image","twitter_creator":"@poeditor","twitter_site":"@poeditor","twitter_misc":{"Written by":"POEditor","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/#article","isPartOf":{"@id":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/"},"author":{"name":"POEditor","@id":"https:\/\/poeditor.com\/blog\/#\/schema\/person\/db77eb2d09539eaac83dcd8f2af06b17"},"headline":"React localization with i18next: How-to guide","datePublished":"2024-12-12T07:54:44+00:00","dateModified":"2024-12-12T07:54:45+00:00","mainEntityOfPage":{"@id":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/"},"wordCount":3075,"publisher":{"@id":"https:\/\/poeditor.com\/blog\/#organization"},"image":{"@id":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/#primaryimage"},"thumbnailUrl":"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/react-localization-i18next.png","articleSection":["Tutorials"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/","url":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/","name":"React localization with i18next: How-to guide - POEditor Blog","isPartOf":{"@id":"https:\/\/poeditor.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/#primaryimage"},"image":{"@id":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/#primaryimage"},"thumbnailUrl":"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/react-localization-i18next.png","datePublished":"2024-12-12T07:54:44+00:00","dateModified":"2024-12-12T07:54:45+00:00","description":"Check out our React localization tutorial on how to use i18next, a robust package for translation requirements, to localize React apps.","breadcrumb":{"@id":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/poeditor.com\/blog\/react-localization-i18next\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/#primaryimage","url":"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/react-localization-i18next.png","contentUrl":"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2024\/12\/react-localization-i18next.png","width":823,"height":591,"caption":"react localization i18next"},{"@type":"BreadcrumbList","@id":"https:\/\/poeditor.com\/blog\/react-localization-i18next\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/poeditor.com\/blog\/"},{"@type":"ListItem","position":2,"name":"React localization with i18next: How-to guide"}]},{"@type":"WebSite","@id":"https:\/\/poeditor.com\/blog\/#website","url":"https:\/\/poeditor.com\/blog\/","name":"POEditor Blog","description":"All about translation and localization management","publisher":{"@id":"https:\/\/poeditor.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/poeditor.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/poeditor.com\/blog\/#organization","name":"POEditor","url":"https:\/\/poeditor.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/poeditor.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2019\/11\/logo_head_512_transparent.png","contentUrl":"https:\/\/poeditor.com\/blog\/wp-content\/uploads\/2019\/11\/logo_head_512_transparent.png","width":512,"height":512,"caption":"POEditor"},"image":{"@id":"https:\/\/poeditor.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/POEditor","https:\/\/x.com\/poeditor","https:\/\/www.linkedin.com\/company\/poeditor\/","https:\/\/www.youtube.com\/channel\/UCXAk1u8N49VRMAqNneENCFA"]},{"@type":"Person","@id":"https:\/\/poeditor.com\/blog\/#\/schema\/person\/db77eb2d09539eaac83dcd8f2af06b17","name":"POEditor","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/95bca2c465fe6134f210cb2f2fbed4f71bf37833fb285624320e808c865695c1?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/95bca2c465fe6134f210cb2f2fbed4f71bf37833fb285624320e808c865695c1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/95bca2c465fe6134f210cb2f2fbed4f71bf37833fb285624320e808c865695c1?s=96&d=mm&r=g","caption":"POEditor"},"url":"https:\/\/poeditor.com\/blog\/author\/poeditor\/"}]}},"_links":{"self":[{"href":"https:\/\/poeditor.com\/blog\/wp-json\/wp\/v2\/posts\/5646","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/poeditor.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/poeditor.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/poeditor.com\/blog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/poeditor.com\/blog\/wp-json\/wp\/v2\/comments?post=5646"}],"version-history":[{"count":27,"href":"https:\/\/poeditor.com\/blog\/wp-json\/wp\/v2\/posts\/5646\/revisions"}],"predecessor-version":[{"id":5697,"href":"https:\/\/poeditor.com\/blog\/wp-json\/wp\/v2\/posts\/5646\/revisions\/5697"}],"wp:attachment":[{"href":"https:\/\/poeditor.com\/blog\/wp-json\/wp\/v2\/media?parent=5646"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/poeditor.com\/blog\/wp-json\/wp\/v2\/categories?post=5646"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/poeditor.com\/blog\/wp-json\/wp\/v2\/tags?post=5646"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}