{"id":20805,"date":"2023-05-08T09:26:00","date_gmt":"2023-05-08T07:26:00","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/?p=20805"},"modified":"2023-10-25T11:20:36","modified_gmt":"2023-10-25T09:20:36","slug":"multilingual-site-in-next-js-with-next-i18next","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/","title":{"rendered":"How to Create a Multilingual Site in Next.js With next-i18next"},"content":{"rendered":"\n<p>Next.js provides built-in internationalized routing capabilities. At the same time, it does not offer a translation content management system. <strong>All it does is keep your locales and URLs synchronized<\/strong>. To actually create a multilingual site in Next.js, you need to handle the translations yourself. That is cumbersome and boilerplate. Thankfully, there is <code>next-i18next<\/code>, a Next.js 18n library that makes localization easier.<\/p>\n\n\n\n<p>At the end of this tutorial, you will know how to set up i18n in Next.js. Let\u2019s get started!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-is-next-i18next-\">What Is next-i18next?<\/h2>\n\n\n\n<p><a href=\"https:\/\/github.com\/i18next\/next-i18next\" class=\"ek-link\"><code>next-i18next<\/code><\/a> is a full-featured localization framework for Next.js applications. It provides an <strong>easy way to manage internationalization and localization<\/strong>. Set it up and you can start adding your translated content into some JSON files. The library with take care of the rest.<\/p>\n\n\n\n<p>The framework relies on <a href=\"https:\/\/www.i18next.com\/\" class=\"ek-link\"><code>i18next<\/code><\/a> and <a href=\"https:\/\/github.com\/i18next\/react-i18next\" class=\"ek-link\"><code>react-i18next<\/code><\/a>. These are the two most popular i18n libraries for <a href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/javascript-guide\/\" target=\"_blank\" aria-label=\"JavaScript  (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">JavaScript <\/a>and <a href=\"https:\/\/www.codemotion.com\/magazine\/languages\/a-complete-introduction-to-the-react-library\/\" target=\"_blank\" aria-label=\"React (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">React<\/a>, respectively. <strong>In detail, <code>next-i18next<\/code> adds support for server-side rendering (SSR)<\/strong>, static site generation (SSG), and incremental static regeneration (ISR). Note that if you are using Next.js 13 with the <a href=\"https:\/\/beta.nextjs.org\/docs\/routing\/fundamentals\"><code>app<\/code><\/a> directory, you do not need <code>next-i18next<\/code>. You can directly use <code>i18next<\/code> and <code>react-i18next<\/code> as explained in the <a href=\"https:\/\/locize.com\/blog\/next-13-app-dir-i18n\/\" class=\"ek-link\">guide mentioned in the documentation<\/a>.<\/p>\n\n\n\n<p>With <code>next-i18next<\/code>, you can build a Next.js site that supports multiple languages with no effort. Check out what it has to offer in the official <a href=\"https:\/\/next.i18next.com\/\" class=\"ek-link\">live demo<\/a>!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"why-is-next-i18next-better-than-other-i18n-libraries-\">Why Is next-i18next Better Than Other i18n Libraries?<\/h2>\n\n\n\n<p>There are many Next.js i18n libraries available. For example, <a href=\"https:\/\/www.npmjs.com\/package\/react-intl\"><code>react-intl<\/code><\/a> has millions of weekly downloads. Yet, none of them is as complete as <code>next-i18next<\/code>. Specifically, it is easy to use, requires little setup, and offers a lot of features. This is what makes it the best Next.js i18n library.<\/p>\n\n\n\n<p>Integrating <code>next-i18next<\/code> into a Next.js app takes only a few steps. Configuring it is even simpler. You can then start passing translations to your page-level components as props through <a href=\"https:\/\/nextjs.org\/docs\/basic-features\/data-fetching#getserversideprops-server-side-rendering\"><code>getServerSideProps()<\/code><\/a> or <a href=\"https:\/\/nextjs.org\/docs\/basic-features\/data-fetching#getstaticprops-static-generation\"><code>getStaticProps()<\/code><\/a>. This complements the <a href=\"https:\/\/nextjs.org\/docs\/advanced-features\/i18n-routing\">internationalized routing<\/a> functionality offered by Next.js, equipping you with everything you need to deal with localized content.<\/p>\n\n\n\n<p>Some key features provided by <code>next-i18next<\/code> include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Support for SSR and SSG<\/li>\n\n\n\n<li>Components and hooks to translate your React components<\/li>\n\n\n\n<li>Code-splitting capabilities with translations stored in JSON files and not in components<\/li>\n\n\n\n<li>Customizable language-switching behavior<\/li>\n\n\n\n<li>Support for placeholders, pluralization, and namespaces from <code>i18next<\/code><\/li>\n\n\n\n<li>Automatic language detection based on user&#8217;s browser language<\/li>\n<\/ul>\n\n\n\n<p>Overall, <code>next-i18next<\/code> is a powerful and flexible i18n framework. It is now time to learn how to use it to build a multi-language Next.js site!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"how-to-set-up-next-i18next-in-next-js\">How to Set Up next-i18next in Next.js<\/h2>\n\n\n\n<p>In this step-by-step section, you will see how to integrate <code>next-i18next<\/code> into an existing Next.js site.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"prerequisites\">Prerequisites<\/h3>\n\n\n\n<p>To follow this tutorial, you first need a Next.js app to localize. If you want to start from scratch, you can initialize a Next.js project with:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">npx<\/span> <span class=\"hljs-selector-tag\">create-next-app<\/span><span class=\"hljs-keyword\">@latest<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Answer all questions, wait for the dependencies to be installed, and run the command below to launch the development server:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">npm run dev<\/code><\/span><\/pre>\n\n\n<p>If the initialization process terminated as expected, you should be seeing the default&nbsp;<a href=\"https:\/\/nextjs.org\/docs\/api-reference\/create-next-app\">Create Next App<\/a>&nbsp;page that follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_191A662EDA462332388B4BD2B7D72CAA60238F6E34C4854D37969598EE3708A1_1679600583465_image.png\" alt=\"The Create Next App general view. How to create a multilingual site with next.js\"\/><\/figure>\n\n\n\n<p>Fantastic! You now have a Next.js project ready to be turned into a multilingual site!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"install-next-i18next\">Install next-i18next<\/h3>\n\n\n\n<p>Add <code>next-i18next<\/code> to your project\u2019s dependencies with:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">npm install next-i18next react-i18next i18next<\/code><\/span><\/pre>\n\n\n<p>Note that the installation command also involves <code>react-i18next<\/code> and <code>i18next<\/code>. This is because those two libraries are <code>next-i18next<\/code>&#8216;s peer dependencies. In other words, <code>next-i18next<\/code> will not work without them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"configure-your-next-js-app\">Configure Your Next.js App<\/h3>\n\n\n\n<p>Create a <code>next-i18next.config.js<\/code> file in the root of your project. That is the configuration file required by <code>next-i18next<\/code>. Initialize it as follows:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ next-i18next.config.js<\/span>\n\n<span class=\"hljs-built_in\">module<\/span>.exports = {\n  <span class=\"hljs-attr\">i18n<\/span>: {\n    <span class=\"hljs-comment\">\/\/ all the locales supported in the application<\/span>\n    <span class=\"hljs-attr\">locales<\/span>: &#91;<span class=\"hljs-string\">'en'<\/span>, <span class=\"hljs-string\">'it'<\/span>, <span class=\"hljs-string\">'es'<\/span>], \n    <span class=\"hljs-comment\">\/\/ the default locale to be used when visiting<\/span>\n    <span class=\"hljs-comment\">\/\/ a non-localized route (e.g. `\/about`)   <\/span>\n    <span class=\"hljs-attr\">defaultLocale<\/span>: <span class=\"hljs-string\">'en'<\/span>\n  },\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This file has to export an <code>i18n<\/code> object with a structure <a href=\"https:\/\/nextjs.org\/docs\/advanced-features\/i18n-routing\">as defined by Next.js<\/a>. In particular, that should contain a <code>locales<\/code> array with the languages supported by your site and a <code>defaultLocale<\/code> variable with one of the locales included in the array. Note that locales must be specified using their <a href=\"https:\/\/www.unicode.org\/reports\/tr35\/tr35-59\/tr35.html#Identifiers\">UTS locale identifiers<\/a>.<\/p>\n\n\n\n<p>To enable the Next.js localized routing feature, you then need to pass the <code>i18n<\/code> object to the <code>next.config.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ next.config.js<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> { i18n } = <span class=\"hljs-built_in\">require<\/span>(<span class=\"hljs-string\">'.\/next-i18next.config'<\/span>)\n \n<span class=\"hljs-keyword\">const<\/span> nextConfig = {\n  i18n,\n  <span class=\"hljs-attr\">reactStrictMode<\/span>: <span class=\"hljs-literal\">true<\/span>,\n}\n\n<span class=\"hljs-built_in\">module<\/span>.exports = nextConfig<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Finally, update your <a href=\"https:\/\/nextjs.org\/docs\/advanced-features\/custom-app\"><code>src\/pages\/_app.js<\/code><\/a> file with this code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ src\/pages\/_app.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { appWithTranslation } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'next-i18next'<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ Component, pageProps }<\/span>) =&gt;<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Component<\/span> {<span class=\"hljs-attr\">...pageProps<\/span>} \/&gt;<\/span><\/span>\n)\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> appWithTranslation(App)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In detail, you need to wrap your top-level <code>App<\/code> component with <a href=\"https:\/\/github.com\/i18next\/next-i18next#appwithtranslation\"><code>appWithTranslation()<\/code><\/a>. This is a React HOC (High-Order Component) that enables the i18n features exposed by <code>next-i18next<\/code> globally in your Next.js app.<\/p>\n\n\n\n<p>Perfect! Your Next.js app is now ready to accept some translation content.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"structure-your-project\">Structure Your Project<\/h3>\n\n\n\n<p><code>next-i18next<\/code> expects your translation JSON files to be organized in the <code>public<\/code> folder as such:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span>\n    \u2514\u2500\u2500 locales\n        \u251c\u2500\u2500 en\n        |   \u2514\u2500\u2500 common.json\n        \u251c\u2500\u2500 es\n        |   \u2514\u2500\u2500 common.json\n        \u2514\u2500\u2500 it\n            \u2514\u2500\u2500 common.json<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>You can customize this default behavior by setting the <code>localePath<\/code> and <code>localeStructure<\/code> values in your <code>next-i18next.config.js<\/code> file.<\/p>\n\n\n\n<p>This is what your project structure now looks like:<\/p>\n\n\n\n<figure class=\"wp-block-image alignfull\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_BC40C0853C0EC0693F1303AB7D959D84618893E1F6E0A665758D66711F0BDB27_1683104144947_image.png\" alt=\"next.js, i18next. Multilingual site.\"\/><\/figure>\n\n\n\n<p>Note the structure of the <code>locales<\/code> folder in the <code>public<\/code> directory. For now, the <code>common.json<\/code> files are empty.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"define-a-localized-page\">Define a Localized Page<\/h3>\n\n\n\n<p>It is now time to build a Next.js page with some multilingual content. Modify the home page of your site by updating the <code>src\/pages\/index.js<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ src\/pages\/index.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { serverSideTranslations } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'next-i18next\/serverSideTranslations'<\/span>\n<span class=\"hljs-keyword\">import<\/span> { useTranslation } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'next-i18next'<\/span>\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">Home<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> { t } = useTranslation()\n\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;&gt;<\/span>\n     <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>{t(\"HELLO_WORLD\")}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/&gt;<\/span><\/span>\n  )\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getStaticProps<\/span>(<span class=\"hljs-params\">context<\/span>) <\/span>{\n  <span class=\"hljs-comment\">\/\/ extract the locale identifier from the URL<\/span>\n  <span class=\"hljs-keyword\">const<\/span> { locale } = context\n\n  <span class=\"hljs-keyword\">return<\/span> {\n    <span class=\"hljs-attr\">props<\/span>: {\n      <span class=\"hljs-comment\">\/\/ pass the translation props to the page component<\/span>\n      ...(<span class=\"hljs-keyword\">await<\/span> serverSideTranslations(locale)),\n    },\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Let&#8217;s understand how this component works, breaking it down into smaller steps.<\/p>\n\n\n\n<p>The <code>getStaticProps()<\/code> Next.js function takes care of defining the rendering strategy for the page. As explained in the <a href=\"https:\/\/nextjs.org\/docs\/advanced-features\/i18n-routing#accessing-the-locale-information\">official doc<\/a>, you can retrieve the current locale read from the page URL from the context provided to the function. In particular, <code>\/<\/code>, <code>\/es<\/code>, and <code>\/it<\/code> all redirect to the home page, but:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In <code>\/<\/code>, <code>locale<\/code> is <code>en<\/code> because <code>defaultLocale<\/code> is <code>en<\/code><\/li>\n\n\n\n<li>In <code>\/es<\/code>, <code>locale<\/code> is <code>es<\/code><\/li>\n\n\n\n<li>In <code>\/it<\/code>, <code>locale<\/code> is <code>it<\/code><\/li>\n<\/ul>\n\n\n\n<p>This is how the Next.js internationalization routing functionality works.<\/p>\n\n\n\n<p>Then, the <code><a href=\"https:\/\/github.com\/i18next\/next-i18next#serversidetranslations\" class=\"ek-link\">serverSideTranslations()<\/a><\/code> HOC from <code>next-i18next<\/code> accepts the locale as a parameter and is responsible for passing translations and configuration options as props to the frontend component pages. You need to add the result of this function to the props of any page that requires translations.<\/p>\n\n\n\n<p>Keep in mind that you can use this same backend logic in both <code>getStaticProps()<\/code> or <code>getServerSideProps()<\/code>.<\/p>\n\n\n\n<p>The page-level component or any components under its tree can now use the <code>useTranslation()<\/code> hook from <code>next-i18next<\/code>. As stressed in the <a href=\"https:\/\/github.com\/i18next\/next-i18next#usetranslation\">doc<\/a>, do not import <code>useTranslation()<\/code> from <code>react-i18next<\/code>. This hook returns the <code>t<\/code> function, which accepts a key string and returns the value read from the corresponding <code>common.json<\/code> translation file. If no matching translations are found, it returns the key string.<\/p>\n\n\n\n<p>Verify that behavior by launching the development server with:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">npm run dev <\/code><\/span><\/pre>\n\n\n<p>Open <code>http:\/\/localhost:3000<\/code> in your browser.<\/p>\n\n\n\n<p>Since all <code>common.json<\/code> file are empty, no matter what <code>\/<\/code>, <code>\/es<\/code>, or <code>\/it<\/code> page you visit, you will always see:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_BC40C0853C0EC0693F1303AB7D959D84618893E1F6E0A665758D66711F0BDB27_1683106277129_image.png\" alt=\"multilingual site with next.js, english.\"\/><\/figure>\n\n\n\n<p>Time to add some translations!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"translate-your-content\">Translate Your Content<\/h3>\n\n\n\n<p>In your <code>common.json<\/code> files, add a <code>HELLO_WORLD<\/code> key:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>\/en\/common.json<\/code>: <code>{ \"HELLO_WORLD\": \"Hello, World!\" }<\/code><\/li>\n\n\n\n<li><code>\/es\/common.json<\/code>: <code>{ \"HELLO_WORLD\": \"\u00a1Hola, mundo!\" }<\/code><\/li>\n\n\n\n<li><code>\/it\/common.json<\/code>: <code>{ \"HELLO_WORLD\": \"Ciao, mondo!\" } <\/code><\/li>\n<\/ul>\n\n\n\n<p>Do not forget that every time you modify something in the <code>public<\/code> folder, you need to restart the development server to see the changes. Kill the current instance and relaunch it. Unlike the <a href=\"https:\/\/writech.run\/blog\/how-to-enable-hot-reloading-for-env-files-in-next-js-1e9ef3d1dc87\/\" class=\"ek-link\"><code>.env<\/code> files<\/a>, the files under <code>public<\/code> are not hot reloaded.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"put-all-together\">Multilingual site in Next.JS: last steps<\/h3>\n\n\n\n<p>Open the three localized versions of your home page in your browser, you will see:<\/p>\n\n\n\n<p><code>http:\/\/localhost:3000\/<\/code>: <img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_BC40C0853C0EC0693F1303AB7D959D84618893E1F6E0A665758D66711F0BDB27_1683106715652_image.png\" alt=\"\"><\/p>\n\n\n\n<p class=\"has-normal-font-size\"><code>http:\/\/localhost:3000\/es<\/code>: <img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_BC40C0853C0EC0693F1303AB7D959D84618893E1F6E0A665758D66711F0BDB27_1683106759741_image.png\" alt=\"\"><\/p>\n\n\n\n<p><code>http:\/\/localhost:3000\/it<\/code>: <img decoding=\"async\" src=\"https:\/\/paper-attachments.dropboxusercontent.com\/s_BC40C0853C0EC0693F1303AB7D959D84618893E1F6E0A665758D66711F0BDB27_1683106785090_image.png\" alt=\"\"><\/p>\n\n\n\n<p>Et voil\u00e0! You just learn how to build a multilingual site in Next.js!<\/p>\n\n\n\n<p>You can find the entire code of the i18n Next.js sample app developed here in the <a href=\"https:\/\/github.com\/Tonel\/i18n-next-demo\">GitHub repository supporting the tutorial<\/a>. Clone it and launch the blog locally with:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">git <span class=\"hljs-keyword\">clone<\/span> https:<span class=\"hljs-comment\">\/\/github.com\/Tonel\/i18n-next-demo<\/span>\ncd i18n-next-demo\nnpm i\nnpm run dev<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Visit <code>http:\/\/localhost:3000<\/code> and enjoy your localized demo app!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>In this article, you saw how to create a multi-language app in Next.js. With the help of <code>next-i18next<\/code>, you can easily implement i18n in Next.js, making it easy to integrate translated content into your site.<\/p>\n\n\n\n<p>First, you understood what <strong>i18n features<\/strong> Next.js natively offers and why you need an extra dependency to handle translation logic. You learned why <code>next-i18next<\/code> is the best i18n library for that, and how to set it up in a step-by-step tutorial. Building a localized site in Next.js has never been easier!<\/p>\n\n\n\n<p>Thanks for reading! We hope you found this article helpful!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong><em>You might also want to read about<\/em><br><\/strong><em><a aria-label=\"How to Create an MDX Blog (opens in a new tab)\" href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/how-to-create-an-mdx-blog-in-typescript-with-next-js\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">How to Create an MDX Blog<\/a> in TypeScript With Next.js<\/em><br><a aria-label=\"How to optimize Next.JS for production (opens in a new tab)\" href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/optimize-next-js-for-production\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\"><em>How to optimize Next.JS for production<\/em><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Next.js provides built-in internationalized routing capabilities. At the same time, it does not offer a translation content management system. All it does is keep your locales and URLs synchronized. To actually create a multilingual site in Next.js, you need to handle the translations yourself. That is cumbersome and boilerplate. Thankfully, there is next-i18next, a Next.js&#8230; <a class=\"more-link\" href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/\">Read more<\/a><\/p>\n","protected":false},"author":160,"featured_media":20811,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[6],"tags":[10006],"collections":[],"class_list":{"0":"post-20805","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-frontend","8":"tag-nextjs","9":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Multilingual site in Next.js With next-i18next - Codemotion<\/title>\n<meta name=\"description\" content=\"Follow this step-by-step tutorial and learn how to manage and create a multilingual site in Next.js with next-i18next. Code examples included!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Create a Multilingual Site in Next.js With next-i18next\" \/>\n<meta property=\"og:description\" content=\"Follow this step-by-step tutorial and learn how to manage and create a multilingual site in Next.js with next-i18next. Code examples included!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-05-08T07:26:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-10-25T09:20:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1193\" \/>\n\t<meta property=\"og:image:height\" content=\"879\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Antonello Zanini\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Antonello Zanini\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/\"},\"author\":{\"name\":\"Antonello Zanini\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/person\\\/1fd4f55ec0d9743347559c715b9edf4a\"},\"headline\":\"How to Create a Multilingual Site in Next.js With next-i18next\",\"datePublished\":\"2023-05-08T07:26:00+00:00\",\"dateModified\":\"2023-10-25T09:20:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/\"},\"wordCount\":1273,\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2023\\\/05\\\/iStock-498555620.jpg\",\"keywords\":[\"NextJS\"],\"articleSection\":[\"Frontend\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/\",\"name\":\"Multilingual site in Next.js With next-i18next - Codemotion\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2023\\\/05\\\/iStock-498555620.jpg\",\"datePublished\":\"2023-05-08T07:26:00+00:00\",\"dateModified\":\"2023-10-25T09:20:36+00:00\",\"description\":\"Follow this step-by-step tutorial and learn how to manage and create a multilingual site in Next.js with next-i18next. Code examples included!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2023\\\/05\\\/iStock-498555620.jpg\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2023\\\/05\\\/iStock-498555620.jpg\",\"width\":1193,\"height\":879,\"caption\":\"World map made of colorful speech bubbles. Translating, language interpreter and communication vector concept illustration\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/multilingual-site-in-next-js-with-next-i18next\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Frontend\",\"item\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"How to Create a Multilingual Site in Next.js With next-i18next\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#website\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/codemotionlogo.png\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/Codemotion.Italy\\\/\",\"https:\\\/\\\/x.com\\\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/person\\\/1fd4f55ec0d9743347559c715b9edf4a\",\"name\":\"Antonello Zanini\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8df9ffe2e0d01ee1cf62c1307c69fd078041934eefd24c47eda05b4f57b4550e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8df9ffe2e0d01ee1cf62c1307c69fd078041934eefd24c47eda05b4f57b4550e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8df9ffe2e0d01ee1cf62c1307c69fd078041934eefd24c47eda05b4f57b4550e?s=96&d=mm&r=g\",\"caption\":\"Antonello Zanini\"},\"description\":\"I'm a software engineer, but I prefer to call myself a Technology Bishop. Spreading knowledge through writing is my mission.\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/antonello-zanini?originalSubdomain=it\"],\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/author\\\/antonello-zanini\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Multilingual site in Next.js With next-i18next - Codemotion","description":"Follow this step-by-step tutorial and learn how to manage and create a multilingual site in Next.js with next-i18next. Code examples included!","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:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/","og_locale":"en_US","og_type":"article","og_title":"How to Create a Multilingual Site in Next.js With next-i18next","og_description":"Follow this step-by-step tutorial and learn how to manage and create a multilingual site in Next.js with next-i18next. Code examples included!","og_url":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2023-05-08T07:26:00+00:00","article_modified_time":"2023-10-25T09:20:36+00:00","og_image":[{"width":1193,"height":879,"url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620.jpg","type":"image\/jpeg"}],"author":"Antonello Zanini","twitter_card":"summary_large_image","twitter_creator":"@CodemotionIT","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"Antonello Zanini","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/"},"author":{"name":"Antonello Zanini","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/1fd4f55ec0d9743347559c715b9edf4a"},"headline":"How to Create a Multilingual Site in Next.js With next-i18next","datePublished":"2023-05-08T07:26:00+00:00","dateModified":"2023-10-25T09:20:36+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/"},"wordCount":1273,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620.jpg","keywords":["NextJS"],"articleSection":["Frontend"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/","url":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/","name":"Multilingual site in Next.js With next-i18next - Codemotion","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620.jpg","datePublished":"2023-05-08T07:26:00+00:00","dateModified":"2023-10-25T09:20:36+00:00","description":"Follow this step-by-step tutorial and learn how to manage and create a multilingual site in Next.js with next-i18next. Code examples included!","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620.jpg","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620.jpg","width":1193,"height":879,"caption":"World map made of colorful speech bubbles. Translating, language interpreter and communication vector concept illustration"},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/multilingual-site-in-next-js-with-next-i18next\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"Frontend","item":"https:\/\/www.codemotion.com\/magazine\/frontend\/"},{"@type":"ListItem","position":3,"name":"How to Create a Multilingual Site in Next.js With next-i18next"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/1fd4f55ec0d9743347559c715b9edf4a","name":"Antonello Zanini","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/8df9ffe2e0d01ee1cf62c1307c69fd078041934eefd24c47eda05b4f57b4550e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/8df9ffe2e0d01ee1cf62c1307c69fd078041934eefd24c47eda05b4f57b4550e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8df9ffe2e0d01ee1cf62c1307c69fd078041934eefd24c47eda05b4f57b4550e?s=96&d=mm&r=g","caption":"Antonello Zanini"},"description":"I'm a software engineer, but I prefer to call myself a Technology Bishop. Spreading knowledge through writing is my mission.","sameAs":["https:\/\/www.linkedin.com\/in\/antonello-zanini?originalSubdomain=it"],"url":"https:\/\/www.codemotion.com\/magazine\/author\/antonello-zanini\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-600x400.jpg","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-600x600.jpg","author_info":{"display_name":"Antonello Zanini","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/antonello-zanini\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620.jpg",1193,879,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-150x150.jpg",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-300x221.jpg",300,221,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-768x566.jpg",768,566,true],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-1024x754.jpg",1024,754,true],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620.jpg",1193,879,false],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620.jpg",1193,879,false],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620.jpg",100,74,false],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-180x128.jpg",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-896x504.jpg",896,504,true],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-400x225.jpg",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-600x400.jpg",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/05\/iStock-498555620-600x600.jpg",600,600,true]},"uagb_author_info":{"display_name":"Antonello Zanini","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/antonello-zanini\/"},"uagb_comment_info":0,"uagb_excerpt":"Next.js provides built-in internationalized routing capabilities. At the same time, it does not offer a translation content management system. All it does is keep your locales and URLs synchronized. To actually create a multilingual site in Next.js, you need to handle the translations yourself. That is cumbersome and boilerplate. Thankfully, there is next-i18next, a Next.js&#8230;&hellip;","lang":"en","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/20805","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/160"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=20805"}],"version-history":[{"count":2,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/20805\/revisions"}],"predecessor-version":[{"id":24083,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/20805\/revisions\/24083"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/20811"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=20805"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=20805"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=20805"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=20805"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}