{"id":4198,"date":"2024-04-22T10:52:03","date_gmt":"2024-04-22T08:52:03","guid":{"rendered":"https:\/\/juannunezblasco.es\/internacionalizacion-en-next-js-react-i18next\/"},"modified":"2024-05-08T20:33:11","modified_gmt":"2024-05-08T18:33:11","slug":"internacionalizacion-en-next-js-react-i18next","status":"publish","type":"post","link":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/","title":{"rendered":"Internationalization in Next.js with React-i18next [REPO]"},"content":{"rendered":"\n<p>In today&#8217;s tutorial we are going to see how to configure Next.js to display your content in multiple languages to support the internationalization process of your product.<\/p>\n\n<p>You can see the code on GitHub and the project deployed in codesandbox:<\/p>\n\n<p><a href=\"https:\/\/codesandbox.io\/p\/github\/juannunezblasco\/nextjs-localized-i18n\/main\">https:\/\/codesandbox.io\/p\/github\/juannunezblasco\/nextjs-localized-i18n\/main<\/a><\/p>\n\n<p><a href=\"https:\/\/github.com\/juannunezblasco\/nextjs-localized-i18n\">https:\/\/github.com\/juannunezblasco\/nextjs-localized-i18n<\/a><\/p>\n\n<p>To carry out the implementation, I am going to use three libraries that I think are great:<\/p>\n\n<ul><li><strong>react-i18next: This is a super powerful solution for internationalizing React and Next.js applications.<\/strong> It allows me to easily translate my app into multiple languages and provides me with easy-to-use React components. Best of all, it is very flexible and works on both the server and the client, making it perfect for my Next.js projects.<\/li><li><strong>i18next-resources-to-backend: This library allows me to upload and save translations to the backend server.<\/strong> This is very useful, especially in large projects where I need to manage translations centrally and load them dynamically as needed. Additionally, it helps me improve performance by reducing the amount of data I need to load to the client.<\/li><li><strong>i18next-browser-languagedetector: This is an extension for i18next that detects the user&#8217;s language in the browser.<\/strong> It&#8217;s great because it allows me to automatically set the app&#8217;s language based on the user&#8217;s language settings. The library supports language detection through various methods, including browser language, cookies, URL, etc.<\/li><\/ul>\n\n<h2 id=\"configuracion-global-i18n\">i18n global configuration<\/h2>\n\n<pre class=\"wp-block-code lang-tsx\"><code>\/\/ i18n\/index.ts\nimport { createInstance } from 'i18next'\nimport resourcesToBackend from 'i18next-resources-to-backend'\nimport { initReactI18next } from 'react-i18next\/initReactI18next'\nimport { getOptions } from '.\/settings'\n\nexport async function useTranslation(lng: string, ns?: string, options: { keyPrefix?: string } = {}) {\n  const i18nextInstance = await initI18next(lng, ns)\n  return {\n    t: i18nextInstance.getFixedT(lng, Array.isArray(ns) ? ns&#91;0] : ns, options.keyPrefix),\n    i18n: i18nextInstance\n  }\n}\n\nconst initI18next = async (lng: string, ns?: string) =&gt; {\n  const i18nInstance = createInstance()\n  await i18nInstance\n    .use(initReactI18next)\n    .use(resourcesToBackend((language: string, namespace: string) =&gt; import(`.\/locales\/${language}\/${namespace}.json`)))\n    .init(getOptions(lng, ns))\n  return i18nInstance\n}<\/code><\/pre>\n\n<p>The code block above shows how to configure internationalization in Next.js using the i18next library. A function <code>useTranslation<\/code> is defined that initializes an instance of <code>i18next<\/code> with the specified language and namespace. This function returns an object with a translation function <code>t<\/code> and the instance of <code>i18next<\/code>.<\/p>\n\n<p>The <code>initI18next<\/code> function is responsible for creating and initializing the i18next instance, using the provided language and namespace. This function uses <code>initReactI18next<\/code> to integrate i18next with React and <code>resourcesToBackend<\/code> to load translations from the backend server. The options for i18next initialization are obtained from the <code>getOptions<\/code> function.<\/p>\n\n<pre class=\"wp-block-code lang-tsx\"><code>\/\/ i18n\/settings.ts \n\t\nexport const fallbackLng: string = 'es'\nexport const languages: string&#91;] = &#91;fallbackLng, 'en']\nexport const cookieName: string = 'i18next'\nexport const defaultNS: string = 'translation'\n\nexport function getOptions (lng = fallbackLng, ns = defaultNS) {\n  return {\n    \/\/ debug: true,\n    supportedLngs: languages,\n    fallbackLng,\n    lng,\n    fallbackNS: defaultNS,\n    defaultNS,\n    ns\n  }\n}<\/code><\/pre>\n\n<p>In the code above, I set i18n. I defined a couple of constants: <code>fallbackLng<\/code>, which is the language we use by default, and <code>languages<\/code>, an array with all the languages we use. I think it would be more flexible if we took these values from the environment variables.<\/p>\n\n<p>I also defined <code>cookieName<\/code>, which is how we call the cookie where we save the selected language, and <code>defaultNS<\/code>, which is our default namespace. In the end, I have a function <code>getOptions<\/code> that returns an object with all the options we will use to initialize i18n.<\/p>\n\n<p>Just a note: normally, in a production environment, we would define these constants as environment variables. In this way, we can have more control and security, since they can vary depending on the environment and would not be visible in the code. But, to make it easier to understand, I have left them written directly in the code.<\/p>\n\n<pre class=\"wp-block-code lang-tsx\"><code>\/\/ i18n\/client.ts\n\n'use client'\n\nimport { useEffect, useState } from 'react'\nimport i18next from 'i18next'\nimport { initReactI18next, useTranslation as useTranslationOrg } from 'react-i18next'\nimport { useCookies } from 'react-cookie'\nimport resourcesToBackend from 'i18next-resources-to-backend'\nimport LanguageDetector from 'i18next-browser-languagedetector'\nimport { getOptions, languages, cookieName } from '.\/settings'\n\nconst runsOnServerSide = typeof window === 'undefined'\n\n\/\/ \ni18next\n  .use(initReactI18next)\n  .use(LanguageDetector)\n  .use(resourcesToBackend((language: string, namespace: string) =&gt; import(`.\/locales\/${language}\/${namespace}.json`)))\n  .init({\n    ...getOptions(),\n    lng: undefined, \/\/ let detect the language on client side\n    detection: {\n      order: &#91;'path', 'htmlTag', 'cookie', 'navigator'],\n    },\n    preload: runsOnServerSide ? languages : &#91;]\n  })\n\n\n\nexport function useTranslation(lng: string, ns?: string, options: any = {}) {\n  const &#91;cookies, setCookie] = useCookies(&#91;cookieName])\n  const ret = useTranslationOrg(ns, options)\n  const { i18n } = ret\n  if (runsOnServerSide &amp;&amp; lng &amp;&amp; i18n.resolvedLanguage !== lng) {\n    i18n.changeLanguage(lng)\n  } else {\n    \/\/ eslint-disable-next-line react-hooks\/rules-of-hooks\n    const &#91;activeLng, setActiveLng] = useState(i18n.resolvedLanguage)\n    \/\/ eslint-disable-next-line react-hooks\/rules-of-hooks\n    useEffect(() =&gt; {\n      if (activeLng === i18n.resolvedLanguage) return\n      setActiveLng(i18n.resolvedLanguage)\n    }, &#91;activeLng, i18n.resolvedLanguage])\n    \/\/ eslint-disable-next-line react-hooks\/rules-of-hooks\n    useEffect(() =&gt; {\n      if (!lng || i18n.resolvedLanguage === lng) return\n      i18n.changeLanguage(lng)\n    }, &#91;lng, i18n])\n    \/\/ eslint-disable-next-line react-hooks\/rules-of-hooks\n    useEffect(() =&gt; {\n      if (cookies.i18next === lng) return\n      setCookie(cookieName, lng, { path: '\/' })\n    }, &#91;lng, cookies.i18next])\n  }\n  return ret\n}<\/code><\/pre>\n\n<p>Finally, in <code>i18n\/client.ts<\/code>, I fine-tuned the client part of the internationalization. Here, I initialized i18next with react-i18next to integrate with React, <code>LanguageDetector<\/code> to detect the user&#8217;s language in the browser, and <code>resourcesToBackend<\/code> to load the translations from the backend server. I also defined a function <code>useTranslation<\/code> that is responsible for changing the language and saving the selected language in a cookie.<\/p>\n\n<h2 id=\"componente-react-para-cambiar-de-idioma\">React component to change language<\/h2>\n\n<p>I show you a React component that I called <code>LanguageSwitcher<\/code>. This component allows you to change the language of the app. You will see that it first shows the language you are using and when you click on it, it displays a list with all the available languages. When you choose one from the list, the app changes to the language you selected.<\/p>\n\n<pre class=\"wp-block-code lang-tsx\"><code>'use client'\n\nimport { useState } from 'react'\nimport Link from 'next\/link'\nimport { FalChevronRight } from '@\/assets\/icons\/FalChevronRight'\nimport { languages } from '..\/settings'\n\nexport const LanguageSwitcher = ({ locale, className }: { locale: string, className?: string }) =&gt; {\n\n  const &#91;showLocales, setShowLocales] = useState(false)\n\n  const handleShowLocales = () =&gt; {\n    setShowLocales(!showLocales)\n  }\n\n  return (\n    &lt;div className={'relative cursor-pointer ml-3 LanguageSwitcher' + className } onClick={handleShowLocales}&gt;\n      &lt;div\n        className=\"text-center cursor-pointer \"\n        \/\/ className=\"route.params.url == item.url ? 'border-white' : 'border-transparent'\"\n      &gt;\n        &lt;div className=\"flex items-center justify-between\"&gt;\n          &lt;span className=\"mr-1\"&gt;{ locale }&lt;\/span&gt;\n          &lt;span className=\"transition-all\"&gt;\n            &lt;FalChevronRight\n              className={\"h-3 fill-white rotate-90 transition-all duration-150 \" + (showLocales &amp;&amp; '-rotate-90')} \/&gt;\n          &lt;\/span&gt;\n        &lt;\/div&gt;\n      &lt;\/div&gt;\n      {\n        showLocales &amp;&amp;\n          &lt;div className=\"flex flex-col absolute shadow-md bg-white\"&gt;\n            {languages.filter((l) =&gt; locale !== l).map((l) =&gt; {\n              return (\n                &lt;Link className='hover:bg-black-300\/10 px-2 py-1 text-black' key={l} href={`\/${l}`}&gt;\n                  {l}\n                &lt;\/Link&gt;\n              )\n            })}\n          &lt;\/div&gt;\n      }\n    &lt;\/div&gt;\n  )\n}<\/code><\/pre>\n\n<p>Now the only point we are missing is to include a middleware to redirect all those who try to enter our website without including the language string that we have set.<\/p>\n\n<h2 id=\"middleware-para-incluir-cookie-y-redirecciones\">Middleware to include cookies and redirects<\/h2>\n\n<p>This code shows how we use middleware in Next.js to handle URL redirects based on the app&#8217;s language. The middleware checks if you have set a cookie with the current language. If it exists, it outputs the language from the cookie. If it does not exist, remove the language from the browser&#8217;s <code>'Accept-Language'<\/code> header. If none of these options give a language, set a default language.<\/p>\n\n<p>The middleware then checks if the request URL includes a language we support. If not, and the URL is not one of Next.js&#8217;s internal routes (such as &#8216;\/_next&#8217;), redirect the request to a URL that includes the language we selected.<\/p>\n\n<p>Additionally, if the &#8216;referer&#8217; header of the request contains a language that we support, this language is saved in a cookie. This can be useful for remembering the user&#8217;s preferred language between different sessions.<\/p>\n\n<pre class=\"wp-block-code lang-ts\"><code>\/\/ middleware.ts\n\nimport { NextResponse, NextRequest } from 'next\/server'\nimport acceptLanguage from 'accept-language'\nimport { cookieName, fallbackLng, languages } from '.\/modules\/i18n\/settings'\n\nexport const config = {\n  matcher: &#91;'\/((?!api|_next\/static|_next\/image|assets|images|styles|icons|favicon.ico|sw.js).*)']\n}\n\nexport async function middleware(request: NextRequest) {\n\n  const response = NextResponse.next()\n\n  let locale\n  if (request.cookies.has(cookieName)) locale = acceptLanguage.get(request.cookies.get(cookieName)?.value)\n  if (!locale) locale = acceptLanguage.get(request.headers.get('Accept-Language'))\n  if (!locale) locale = fallbackLng\n\n  \/\/ Redirect if locale in path is not supported\n  if (\n    !languages.some(locale =&gt; request.nextUrl.pathname.startsWith(`\/${locale}`)) &amp;&amp;\n    !request.nextUrl.pathname.startsWith('\/_next')\n  ) {\n    return NextResponse.redirect(new URL(`\/${locale}${request.nextUrl.pathname}`, request.url))\n  }\n\n  if (request.headers.has('referer')) {\n    const refererUrl = new URL(request.headers.get('referer') ?? '')\n    const lngInReferer = languages.find((locale) =&gt; refererUrl.pathname.startsWith(`\/${locale}`))\n    const response = NextResponse.next()\n    if (lngInReferer) response.cookies.set(cookieName, lngInReferer)\n    \n  }\n\n  return response\n\n}\n<\/code><\/pre>\n\n<h2 id=\"conclusiones\">Conclusions<\/h2>\n\n<p>\u00a1Voil\u00e0! We just showed you how to implement internationalization in your Next.js app with react-i18next, i18next-resources-to-backend, and i18next-browser-languagedetector.<\/p>\n\n<p>Now your app is ready to conquer the world, that sounds great! If this tutorial has been useful to you, why don&#8217;t you share it on your networks? I&#8217;m sure it can help your fellow developers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In today&#8217;s tutorial we are going to see how to configure Next.js to display your content in multiple languages to support the internationalization process of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":4125,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[73,74],"tags":[],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v18.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Internationalization in Next.js with React-i18next [REPO] | J - Desarrollo Aplicaciones Web<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Internationalization in Next.js with React-i18next [REPO] | J - Desarrollo Aplicaciones Web\" \/>\n<meta property=\"og:description\" content=\"In today&#8217;s tutorial we are going to see how to configure Next.js to display your content in multiple languages to support the internationalization process of [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/\" \/>\n<meta property=\"og:site_name\" content=\"J - Desarrollo Aplicaciones Web\" \/>\n<meta property=\"article:published_time\" content=\"2024-04-22T08:52:03+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-08T18:33:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/juannunezblasco.es\/content\/uploads\/2024\/04\/internacionalizacion-nextjs.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1260\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Juan N\u00fa\u00f1ez Blaco\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https:\/\/juannunezblasco.es\/#organization\",\"name\":\"J - Desarrollo Aplicaciones Web\",\"url\":\"https:\/\/juannunezblasco.es\/\",\"sameAs\":[],\"logo\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/juannunezblasco.es\/#logo\",\"inLanguage\":\"en-US\",\"url\":\"http:\/\/juannunezblasco.local\/content\/uploads\/2022\/02\/logo-jnb-positivo.png\",\"contentUrl\":\"http:\/\/juannunezblasco.local\/content\/uploads\/2022\/02\/logo-jnb-positivo.png\",\"width\":512,\"height\":513,\"caption\":\"J - Desarrollo Aplicaciones Web\"},\"image\":{\"@id\":\"https:\/\/juannunezblasco.es\/#logo\"}},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/juannunezblasco.es\/#website\",\"url\":\"https:\/\/juannunezblasco.es\/\",\"name\":\"J - Desarrollo Aplicaciones Web\",\"description\":\"Dise\u00f1o y desarrollos de productos digitales a medida\",\"publisher\":{\"@id\":\"https:\/\/juannunezblasco.es\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/juannunezblasco.es\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/juannunezblasco.es\/content\/uploads\/2024\/04\/internacionalizacion-nextjs.jpg\",\"contentUrl\":\"https:\/\/juannunezblasco.es\/content\/uploads\/2024\/04\/internacionalizacion-nextjs.jpg\",\"width\":1260,\"height\":630,\"caption\":\"Internationalization in Next.js with React-i18next\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#webpage\",\"url\":\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/\",\"name\":\"Internationalization in Next.js with React-i18next [REPO] | J - Desarrollo Aplicaciones Web\",\"isPartOf\":{\"@id\":\"https:\/\/juannunezblasco.es\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#primaryimage\"},\"datePublished\":\"2024-04-22T08:52:03+00:00\",\"dateModified\":\"2024-05-08T18:33:11+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/juannunezblasco.es\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Internationalization in Next.js with React-i18next [REPO]\"}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#webpage\"},\"author\":{\"@id\":\"https:\/\/juannunezblasco.es\/#\/schema\/person\/31582cd4a29af7055b4c3b0508601b29\"},\"headline\":\"Internationalization in Next.js with React-i18next [REPO]\",\"datePublished\":\"2024-04-22T08:52:03+00:00\",\"dateModified\":\"2024-05-08T18:33:11+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#webpage\"},\"wordCount\":850,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/juannunezblasco.es\/#organization\"},\"image\":{\"@id\":\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/juannunezblasco.es\/content\/uploads\/2024\/04\/internacionalizacion-nextjs.jpg\",\"articleSection\":[\"Next.js\",\"React\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#respond\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/juannunezblasco.es\/#\/schema\/person\/31582cd4a29af7055b4c3b0508601b29\",\"name\":\"Juan N\u00fa\u00f1ez Blaco\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/juannunezblasco.es\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/23b8417ac4b489153038755511de438e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/23b8417ac4b489153038755511de438e?s=96&d=mm&r=g\",\"caption\":\"Juan N\u00fa\u00f1ez Blaco\"},\"description\":\"Full Stack Developer\",\"sameAs\":[\"https:\/\/juannunezblasco.es\"],\"url\":\"https:\/\/juannunezblasco.es\/en\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Internationalization in Next.js with React-i18next [REPO] | J - Desarrollo Aplicaciones Web","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:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/","og_locale":"en_US","og_type":"article","og_title":"Internationalization in Next.js with React-i18next [REPO] | J - Desarrollo Aplicaciones Web","og_description":"In today&#8217;s tutorial we are going to see how to configure Next.js to display your content in multiple languages to support the internationalization process of [&hellip;]","og_url":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/","og_site_name":"J - Desarrollo Aplicaciones Web","article_published_time":"2024-04-22T08:52:03+00:00","article_modified_time":"2024-05-08T18:33:11+00:00","og_image":[{"width":1260,"height":630,"url":"https:\/\/juannunezblasco.es\/content\/uploads\/2024\/04\/internacionalizacion-nextjs.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Written by":"Juan N\u00fa\u00f1ez Blaco","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Organization","@id":"https:\/\/juannunezblasco.es\/#organization","name":"J - Desarrollo Aplicaciones Web","url":"https:\/\/juannunezblasco.es\/","sameAs":[],"logo":{"@type":"ImageObject","@id":"https:\/\/juannunezblasco.es\/#logo","inLanguage":"en-US","url":"http:\/\/juannunezblasco.local\/content\/uploads\/2022\/02\/logo-jnb-positivo.png","contentUrl":"http:\/\/juannunezblasco.local\/content\/uploads\/2022\/02\/logo-jnb-positivo.png","width":512,"height":513,"caption":"J - Desarrollo Aplicaciones Web"},"image":{"@id":"https:\/\/juannunezblasco.es\/#logo"}},{"@type":"WebSite","@id":"https:\/\/juannunezblasco.es\/#website","url":"https:\/\/juannunezblasco.es\/","name":"J - Desarrollo Aplicaciones Web","description":"Dise\u00f1o y desarrollos de productos digitales a medida","publisher":{"@id":"https:\/\/juannunezblasco.es\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/juannunezblasco.es\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#primaryimage","inLanguage":"en-US","url":"https:\/\/juannunezblasco.es\/content\/uploads\/2024\/04\/internacionalizacion-nextjs.jpg","contentUrl":"https:\/\/juannunezblasco.es\/content\/uploads\/2024\/04\/internacionalizacion-nextjs.jpg","width":1260,"height":630,"caption":"Internationalization in Next.js with React-i18next"},{"@type":"WebPage","@id":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#webpage","url":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/","name":"Internationalization in Next.js with React-i18next [REPO] | J - Desarrollo Aplicaciones Web","isPartOf":{"@id":"https:\/\/juannunezblasco.es\/#website"},"primaryImageOfPage":{"@id":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#primaryimage"},"datePublished":"2024-04-22T08:52:03+00:00","dateModified":"2024-05-08T18:33:11+00:00","breadcrumb":{"@id":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/juannunezblasco.es\/en\/"},{"@type":"ListItem","position":2,"name":"Internationalization in Next.js with React-i18next [REPO]"}]},{"@type":"Article","@id":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#article","isPartOf":{"@id":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#webpage"},"author":{"@id":"https:\/\/juannunezblasco.es\/#\/schema\/person\/31582cd4a29af7055b4c3b0508601b29"},"headline":"Internationalization in Next.js with React-i18next [REPO]","datePublished":"2024-04-22T08:52:03+00:00","dateModified":"2024-05-08T18:33:11+00:00","mainEntityOfPage":{"@id":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#webpage"},"wordCount":850,"commentCount":0,"publisher":{"@id":"https:\/\/juannunezblasco.es\/#organization"},"image":{"@id":"https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#primaryimage"},"thumbnailUrl":"https:\/\/juannunezblasco.es\/content\/uploads\/2024\/04\/internacionalizacion-nextjs.jpg","articleSection":["Next.js","React"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/juannunezblasco.es\/en\/internacionalizacion-en-next-js-react-i18next\/#respond"]}]},{"@type":"Person","@id":"https:\/\/juannunezblasco.es\/#\/schema\/person\/31582cd4a29af7055b4c3b0508601b29","name":"Juan N\u00fa\u00f1ez Blaco","image":{"@type":"ImageObject","@id":"https:\/\/juannunezblasco.es\/#personlogo","inLanguage":"en-US","url":"https:\/\/secure.gravatar.com\/avatar\/23b8417ac4b489153038755511de438e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/23b8417ac4b489153038755511de438e?s=96&d=mm&r=g","caption":"Juan N\u00fa\u00f1ez Blaco"},"description":"Full Stack Developer","sameAs":["https:\/\/juannunezblasco.es"],"url":"https:\/\/juannunezblasco.es\/en\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/posts\/4198"}],"collection":[{"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/comments?post=4198"}],"version-history":[{"count":2,"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/posts\/4198\/revisions"}],"predecessor-version":[{"id":4204,"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/posts\/4198\/revisions\/4204"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/media\/4125"}],"wp:attachment":[{"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/media?parent=4198"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/categories?post=4198"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/juannunezblasco.es\/en\/wp-json\/wp\/v2\/tags?post=4198"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}