{"id":21929,"date":"2020-01-08T12:19:06","date_gmt":"2020-01-08T12:19:06","guid":{"rendered":"https:\/\/www.heartinternet.uk\/blog\/?p=21929"},"modified":"2020-01-08T12:19:06","modified_gmt":"2020-01-08T12:19:06","slug":"the-importance-of-localisation-and-how-to-implement-and-test-it-in-react","status":"publish","type":"post","link":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/","title":{"rendered":"The importance of localisation and how to implement and test it in React"},"content":{"rendered":"<p>In this article, we\u2019ll be covering the foundational principles of localisation in React. We\u2019ll start by looking at what localisation is and why it\u2019s important before jumping into code samples to prepare your app for a global audience.<\/p>\n<p>According to a study done by the <a href=\"https:\/\/ec.europa.eu\/commfrontoffice\/publicopinion\/flash\/fl_313_en.pdf\">European Commission<\/a>, only 53% of internet users would use a website in English if their native language wasn\u2019t available, and over 44% felt as if they might be missing information or receiving inaccurate information because a website wasn\u2019t in their native language. Above all, 72% of participants reported they spend \u201cmost\u201d or \u201call\u201d of their internet time on websites that offer their native language, and even those with high proficiency in English spend 60% more time browsing in their own language.<\/p>\n<p>It\u2019s clear that making users feel comfortable with your product is important, especially when it comes to being inclusive of their language and cultural needs. The goal of localisation is to do exactly that. With a good infrastructure in place, you can easily set your product up for success on a global scale and ensure your users are getting the experience that\u2019s right for them.<\/p>\n<h2>What is localisation?<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-21939\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/localisation-diagram.png\" alt=\"\" width=\"1392\" height=\"869\" \/><\/p>\n<p>In software development, localisation is the process of adapting a product to meet your users\u2019 language and cultural requirements. It\u2019s often shortened to <em>l10n<\/em>, as there are ten letters between the <em>l<\/em> and <em>n<\/em>. This includes formatting numeric values (such as date, time, and currency), imagery (such as icons, symbols, and colours), and translating text. As a rule of thumb, everything that your users see is fair game to be localised.<\/p>\n<p>You\u2019ll often see the term <em>internationalisation<\/em> (shortened to <em>intl<\/em> or <em>i18n<\/em>) thrown around when localisation is mentioned. These concepts both share the same goal, but internationalisation is a broader term that describes the overall process of creating a product that can be shipped on a global scale. It focuses on the infrastructure and architecture of a product, whereas localisation dives deeper into the details of what needs to be accomplished before a product can be considered \u201cready\u201d for a global user base.<\/p>\n<p>Internationalisation does, however, significantly affect the ease of a product\u2019s localisation. Retrofitting a linguistically- and culturally-centered set of features for a global user base is much more difficult and time-consuming than designing a feature with the intent of shipping it globally from the very beginning. Think back to the Y2K problem \u2014 hundreds of thousands of computer systems worldwide relied on two-digit year fields, rather than four. When the turn of the century hit, systems reported the year as 1900 rather than 2000, leading to many serious real-world issues. If these systems had been built with this scenario in mind, the transition would have been much smoother for everyone involved.<\/p>\n<p>Similarly, even if you don\u2019t think you\u2019ll be shipping globally now (and maybe not even for a long time), it can still be useful to build with internationalisation in mind. Some of the techniques we\u2019ll cover are generally good practices in any software development. The overarching goal of both localisation and internationalisation is to remove barriers for a global product, including bidirectional text support, Unicode support, and support for dynamic UI, minimising hardcoded strings and string concatenation.<\/p>\n<h2>Why is localisation important?<\/h2>\n<p>Besides providing us with a method for handling strings in a structured way, localisation is important for three major reasons.<\/p>\n<p>First, while it can cost a lot of development time to set up the infrastructure and money on professional translations, localising your product expands your user base and therefore your income stream. <a href=\"https:\/\/www.internetworldstats.com\/stats7.htm\">Only 25.2% of internet users worldwide speak English, and 76.3% of all internet users are spread out across ten languages<\/a>.<\/p>\n<p>Second, it\u2019s important to be sensitive across all cultures. During my time at Microsoft, a bug report was filed titled \u201c<a href=\"https:\/\/developercommunity.visualstudio.com\/content\/problem\/475341\/vs-installer-welcome-image-contains-offensive-elem.html\">VS Installer welcome image contains offensive element for Chinese [users]<\/a>\u201d. This was a huge problem for our Chinese market, and a fix was released to production within ten days.<\/p>\n<p>Finally, in the context of web apps, localisation allows us the opportunity to provide in-context translations that focus on quality and experience, rather than automatic translations provided by browsers.<\/p>\n<h2>Localisation goals<\/h2>\n<p>When we think about how to implement a localisation solution in our app, it\u2019s important to lay out a few goals to help guide us.<\/p>\n<h2>Single source of truth<\/h2>\n<p>There should be no confusion about which version of an English string is the correct one. This helps eliminate inconsistencies across the product (for example: we shouldn\u2019t have some features that say \u201cRemove\u201d and others that say \u201cDelete\u201d when they perform the same action).<\/p>\n<h2>Arbitrary number of languages<\/h2>\n<p>There should be no upper bound to how many languages we\u2019re able to support. Adding support for a new language to the product should require minimal effort from developers.<\/p>\n<h2>Decoupled<\/h2>\n<p>Adding translations and developing features should be kept as independently as possible, so that both tasks can happen in parallel and without conflicts.<\/p>\n<h2>Automated<\/h2>\n<p>We should strive to automate as much of this process as possible to make our solution more efficient and less error-prone.<\/p>\n<p><em>Watch Isabela\u2019s Nordic.js talk on localisation:<\/em><\/p>\n<p><iframe loading=\"lazy\" src=\"https:\/\/www.youtube.com\/embed\/mh_Ck6Snoyw\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<h2>Localisation in React<\/h2>\n<p>One library you may have come across for localisation in React is <code>react-intl<\/code>. This is a fine solution for very simple React apps, but it doesn\u2019t support vanilla JavaScript or other frameworks (as the name implies).<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/02a3ccdc58a58c19b2e7366a64272035.js\"><\/script><\/p>\n<p>A side effect of this restriction is that, even if you\u2019re working within a React app, a scenario where you have a generic <code>.js<\/code> or <code>.ts<\/code> file that needs to handle text (and therefore localisation) isn\u2019t supported. Additionally, this library also requires that the React component using it be wrapped by a <a href=\"https:\/\/reactjs.org\/docs\/higher-order-components.html\">Higher Order Component<\/a>. This breaks our decoupling goal because now when we\u2019re developing features, we need to keep in mind that they must be HOC-wrapped and limits our tech stack to React. So what\u2019s the alternative?<\/p>\n<p>The best alternative I\u2019ve found is <code>react-universal-intl<\/code>. Despite its name, it can handle all your localisation needs for any JavaScript app, including vanilla JS. The basic approach is that you define a JSON file with all the supported locales and the string resources used in your app. Then in the <code>.js<\/code> or <code>.ts<\/code> file, you call <code>intl.get()<\/code> with the key for your string resource.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/b198cfd83940b710307f65e342c8e7f6.js\"><\/script><\/p>\n<p>This solution is nice because your strings are separated from your app, and you don\u2019t have hardcoded values anymore. We\u2019re not done with the localisation yet since we\u2019re only pulling English values in our JSON file, but we have a strong architecture in place to support it. This is also a great approach for strings in general, since they\u2019re isolated to a single JSON file, to ensure consistency across your product.<\/p>\n<h3>Using react-intl-universal<\/h3>\n<p>In order for localisation to work, a message has to be written and translated as a single unit. For strings with proper nouns and names, or numerical values that need to appear within a phrase, passing in a variable like we did in the example above is a fine approach.<\/p>\n<p>Besides that, however, you should never concatenate your own strings from various formatted elements and your own injected variables. Not only does this make it extremely hard for translators to understand the full meaning of your message, but these translated strings could end up with the wrong grammar. This is most commonly seen in languages that differentiate between masculine and feminine words. If you rely on passing in a data type as a variable to your translation, you might end up with incorrect pronouns.<\/p>\n<p>For example, in Portuguese, the word \u201cmessage\u201d is feminine, so the feminine form of \u201cnew\u201d should be used to describe it. The correct translation for the phrase \u201cNew message\u201d then is \u201cNova mensagem\u201d and not \u201cNovo mensagem\u201d. However, the word \u201cemail\u201d (adopted directly from English) is considered masculine, so the masculine of \u201cnew\u201d should be used. The correct translation for \u201cNew email\u201d then is \u201cNovo email\u201d. If these had been translated as a single string with variables passed in for the different supported data types (eg message, email and activity), you would have ended up with the wrong form of the word \u201cnew\u201d in at least one instance, depending on if you hardcoded \u201cnovo\u201d or \u201cnova\u201d in your JSON file.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/ade00a94200d6fc4a42cc236ab7cc90d.js\"><\/script><\/p>\n<p>This is where the ICU MessageFormat comes into play. It provides a programming language agnostic format for translating strings and is enforced by the <code>react-universal-intl<\/code> library. The ICU MessageFormat requires the following structure: <code>{ name, type, format }<\/code>.<\/p>\n<p><code>name<\/code> is the key in the locale JSON file, <code>type<\/code> is the set of variables or data types (such as number, data, time, or plural), and <code>format<\/code> is optional and provides additional context for how the value should be displayed.<\/p>\n<p><strong>Pluralisation: <\/strong>You can pass variables to the library call and corresponding numerical values to determine what string you want for each variant.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/3fb23b2fe8dd40b6cded40b992b7bd52.js\"><\/script><\/p>\n<p><strong>Dates:<\/strong> You can pass in a <code>Date<\/code> object and a format type to choose how to display the date. This format can be either short, medium, long, or full and defaults to short if not provided.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/b253bdd9abe97667a3f290589177b89c.js\"><\/script><\/p>\n<p><strong>Times:<\/strong> Similar to dates, timestamps from <code>Date<\/code> objects can be localised and formatted.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/3aae47027ef2f4a52244696dc7f32828.js\"><\/script><\/p>\n<p><strong>Currency:<\/strong> As we covered earlier, currency also needs to be localised. This is done similarly to dates and times, with the format parameter representing the <strong><a href=\"https:\/\/www.currency-iso.org\/en\/home\/tables\/table-a1.html\">ISO standards country code<\/a><\/strong>.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/8f0360a73cee22dd69f38fb5cb95b427.js\"><\/script><\/p>\n<p>The formatting for dates, times, and currency can also be dynamically detected once the library is initialised, so you can use the default formatting for the user\u2019s region.<\/p>\n<h3>Implementing localisation in React<\/h3>\n<p>In order to make localisation low-friction for end users, we should automatically recognise the user\u2019s default locale. To round out the experience, we should also allow the user to change this from a settings page. Finally, we should leverage the common locale data mentioned above for formatting numerical values whenever possible.<\/p>\n<p>The first thing needed is the setup of determining the user\u2019s current locale when the app loads. Most of this article will be in React for simplicity, but since <code>react-universal-intl<\/code> is also compatible with vanilla JS, the examples shown should work with minor tweaks. We also define an array of dropdown objects, <code>SUPPORTED_LANGUAGES<\/code>, that can be used by a settings page to allow users to set their preferred locale.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/fa247ec1b7fc47dd693c5fd8c0c00f04.js\"><\/script><\/p>\n<p>As you can see in the code above, we can use the user\u2019s preferred locale if it exists in our state (perhaps stored in Redux). Otherwise, we can determine their locale by checking the URL or cookies for a lang token. If none of these options exist or are not supported by the app (as defined by <code>SUPPORTED_LANGUAGES<\/code>), it\u2019s reasonable to default to English (or whatever language you choose depending on your main audience). I also highly suggest using the <a href=\"https:\/\/www.npmjs.com\/package\/json-loader\">json-loader npm package<\/a> to dynamically require your locale JSON files. This will <a href=\"https:\/\/stackoverflow.com\/questions\/33650399\/es6-modules-implementation-how-to-load-a-json-file\/33650470#33650470\">prevent your app from importing unnecessary locale data files<\/a>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-21940\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/file-structure.png\" alt=\"\" width=\"304\" height=\"370\" \/><\/p>\n<p>The overall file structure of your app should resemble the above image. Each locale has its own JSON file of translated strings, which all live in a <code>localeData<\/code> directory. This helps keep the string file isolated from the rest of the code and allows developers to see which languages are supported at a quick glance.<\/p>\n<p>Finally, hooking up the dropdown for the user\u2019s preferred locale can update the Redux state, or perhaps change the URL parameter used by <code>intl.determineLocale()<\/code> to update the localisation strategy (<code>location.search = `?lang={e.target.value}`<\/code>).<\/p>\n<p>As localisation also includes symbols and images, we can use the <code>currentLocale<\/code> from the library to determine what elements to render as well.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/f721d97641ffd3aa1665e8f32c574377.js\"><\/script><\/p>\n<h2>Testing localisation<\/h2>\n<p>We\u2019ve covered a lot about how we\u2019d localise strings across our product, but an important aspect of doing so is testing that we haven\u2019t missed any strings. You may be thinking that you only know one language or don\u2019t want to rely on faking a locale or toggling user settings to manually test strings across the product.<\/p>\n<p>To solve this, we can use a strategy called pseudo-localisation. By leveraging this, we can force our development environment to use a specific locale file that returns Unicode text that closely matches English, but looks obviously different with various accent marks and ligatures. We used this technique a lot when I worked at Microsoft. This is a screenshot of what <a href=\"https:\/\/www.windowscentral.com\/xbox-one-os-preview-fonts\">a development build of Xbox looks like with pseudo-localisation enabled<\/a>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-21943\" src=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/xbox-localisation.png\" alt=\"\" width=\"800\" height=\"450\" \/><\/p>\n<p>As you can see from this screenshot, the text is still legible but makes it very apparent what strings are still hard coded and aren\u2019t being sent through the localisation service. In this case, we can see that the \u201cCancel\u201d button doesn\u2019t show up in the Unicode font, so we know it hasn\u2019t been translated.<\/p>\n<p>My preferred method of setting up pseudo-localisation for projects is with CLI tools that generate the pseudo-localised JSON files. These files can then be used in place of the locale JSON files in local development builds. I like the <a href=\"https:\/\/www.npmjs.com\/package\/pseudo-localization\">pseudo-localization npm package<\/a>. Once installed (<code>npm install pseudo-localization<\/code>), you can use the CLI version to generate the JSON file by running <code>npx pseudo-localization .\/path\/to\/locales\/en.json -o .\/path\/to\/locales\/pseudo.json<\/code>. From there, we can do something like this in our app code:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/86d8bc10aea711a954acc487ea725c56.js\"><\/script><\/p>\n<p>If the process environment is development, we can immediately require the pseudo.json file. Otherwise, we\u2019ll require whatever locale was detected. The only thing you need to remember to do (or automate!) is to re-run the pseudo-localisation CLI tool whenever you create or edit a string in your base locale JSON file. Otherwise, an empty string will be rendered if it doesn\u2019t exist in the pseudo.json file.<\/p>\n<p>We should also update our unit and integration tests to make sure they catch any non-localised strings and make our tests independent of what locale they\u2019re run under. This is pretty straightforward to do. You can write your test like normal but, instead of expecting the text to equal a hard coded string, you can expect it to equal a value returned by the intl library.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/isabelacmor\/be9e9c69c5c22924b460d4a68e5c468f.js\"><\/script><\/p>\n<h2>Wrapping up<\/h2>\n<p>To wrap things up, you should avoid hard coded strings in your product. Even if you don\u2019t think you\u2019ll be localising in the near future (or ever!), it&#8217;s useful to have all your strings in one JSON file, and it can be beneficial to have an architecture in place that can easily support localisation.<\/p>\n<p>You should also translate messages as single units, minimise non-numerical string variables, and avoid manual string concatenation. It\u2019s important to think about localisation at a high level and not focus only on the translation of strings. Dates, currencies, and time formats should all be taken into account. It\u2019s also crucial to avoid direct translations if possible (for example, using automatic translation services), as they usually result in very literal string translations that don\u2019t take into account the context and function of a particular string. Overall, I\u2019d suggest using the <code>react-intl-universal<\/code> and <code>pseudo-localization<\/code> libraries and avoiding DIY localisation strategies.<\/p>\n<p>The most important thing to keep in mind when considering localisation is that you\u2019re building a product for your users. It\u2019s your responsibility to give them a positive experience through inclusive design, and this includes minimising language and cultural barriers. By localising your product, you can not only ensure this, but also expand your user base to the over 75% of users who aren\u2019t native English speakers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we\u2019ll be covering the foundational principles of localisation in React. We\u2019ll start by looking at what localisation is and why it\u2019s important before jumping into code samples to prepare your app for a global audience.<\/p>\n","protected":false},"author":2,"featured_media":21949,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[],"class_list":{"0":"post-21929","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-web-design"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>The importance of localisation and how to implement and test it in React - Heart Internet<\/title>\n<meta name=\"description\" content=\"The importance of localisation and how to implement and test it in React - Written by the team at Heart Internet.\" \/>\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.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The importance of localisation and how to implement and test it in React - Heart Internet\" \/>\n<meta property=\"og:description\" content=\"The importance of localisation and how to implement and test it in React - Written by the team at Heart Internet.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/\" \/>\n<meta property=\"og:site_name\" content=\"Heart Internet\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/heartinternet\/\" \/>\n<meta property=\"article:published_time\" content=\"2020-01-08T12:19:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/12\/globe-on-desk.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"733\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Eliot Chambers-Ostler\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@heartinternet\" \/>\n<meta name=\"twitter:site\" content=\"@heartinternet\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Eliot Chambers-Ostler\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/\"},\"author\":{\"name\":\"Eliot Chambers-Ostler\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28\"},\"headline\":\"The importance of localisation and how to implement and test it in React\",\"datePublished\":\"2020-01-08T12:19:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/\"},\"wordCount\":2546,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/12\/globe-on-desk.jpg\",\"articleSection\":[\"Web Design\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/\",\"name\":\"The importance of localisation and how to implement and test it in React - Heart Internet\",\"isPartOf\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/12\/globe-on-desk.jpg\",\"datePublished\":\"2020-01-08T12:19:06+00:00\",\"description\":\"The importance of localisation and how to implement and test it in React - Written by the team at Heart Internet.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#primaryimage\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/12\/globe-on-desk.jpg\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/12\/globe-on-desk.jpg\",\"width\":1100,\"height\":733},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.heartinternet.uk\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"The importance of localisation and how to implement and test it in React\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/heartblog.victory.digital\/#website\",\"url\":\"https:\/\/heartblog.victory.digital\/\",\"name\":\"Heart Internet\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/heartblog.victory.digital\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\",\"name\":\"Heart Internet\",\"url\":\"https:\/\/heartblog.victory.digital\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp\",\"width\":992,\"height\":252,\"caption\":\"Heart Internet\"},\"image\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/heartinternet\/\",\"https:\/\/x.com\/heartinternet\",\"https:\/\/www.linkedin.com\/company\/heart-internet-ltd\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28\",\"name\":\"Eliot Chambers-Ostler\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg\",\"caption\":\"Eliot Chambers-Ostler\"},\"url\":\"https:\/\/www.heartinternet.uk\/blog\/author\/eliot-chambers-ostler\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The importance of localisation and how to implement and test it in React - Heart Internet","description":"The importance of localisation and how to implement and test it in React - Written by the team at Heart Internet.","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.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/","og_locale":"en_GB","og_type":"article","og_title":"The importance of localisation and how to implement and test it in React - Heart Internet","og_description":"The importance of localisation and how to implement and test it in React - Written by the team at Heart Internet.","og_url":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/","og_site_name":"Heart Internet","article_publisher":"https:\/\/www.facebook.com\/heartinternet\/","article_published_time":"2020-01-08T12:19:06+00:00","og_image":[{"width":1100,"height":733,"url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/12\/globe-on-desk.jpg","type":"image\/jpeg"}],"author":"Eliot Chambers-Ostler","twitter_card":"summary_large_image","twitter_creator":"@heartinternet","twitter_site":"@heartinternet","twitter_misc":{"Written by":"Eliot Chambers-Ostler","Estimated reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#article","isPartOf":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/"},"author":{"name":"Eliot Chambers-Ostler","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28"},"headline":"The importance of localisation and how to implement and test it in React","datePublished":"2020-01-08T12:19:06+00:00","mainEntityOfPage":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/"},"wordCount":2546,"commentCount":0,"publisher":{"@id":"https:\/\/heartblog.victory.digital\/#organization"},"image":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#primaryimage"},"thumbnailUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/12\/globe-on-desk.jpg","articleSection":["Web Design"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/","url":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/","name":"The importance of localisation and how to implement and test it in React - Heart Internet","isPartOf":{"@id":"https:\/\/heartblog.victory.digital\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#primaryimage"},"image":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#primaryimage"},"thumbnailUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/12\/globe-on-desk.jpg","datePublished":"2020-01-08T12:19:06+00:00","description":"The importance of localisation and how to implement and test it in React - Written by the team at Heart Internet.","breadcrumb":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#primaryimage","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/12\/globe-on-desk.jpg","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2019\/12\/globe-on-desk.jpg","width":1100,"height":733},{"@type":"BreadcrumbList","@id":"https:\/\/www.heartinternet.uk\/blog\/the-importance-of-localisation-and-how-to-implement-and-test-it-in-react\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.heartinternet.uk\/blog\/"},{"@type":"ListItem","position":2,"name":"The importance of localisation and how to implement and test it in React"}]},{"@type":"WebSite","@id":"https:\/\/heartblog.victory.digital\/#website","url":"https:\/\/heartblog.victory.digital\/","name":"Heart Internet","description":"","publisher":{"@id":"https:\/\/heartblog.victory.digital\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/heartblog.victory.digital\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Organization","@id":"https:\/\/heartblog.victory.digital\/#organization","name":"Heart Internet","url":"https:\/\/heartblog.victory.digital\/","logo":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp","width":992,"height":252,"caption":"Heart Internet"},"image":{"@id":"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/heartinternet\/","https:\/\/x.com\/heartinternet","https:\/\/www.linkedin.com\/company\/heart-internet-ltd"]},{"@type":"Person","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28","name":"Eliot Chambers-Ostler","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/image\/","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg","caption":"Eliot Chambers-Ostler"},"url":"https:\/\/www.heartinternet.uk\/blog\/author\/eliot-chambers-ostler\/"}]}},"_links":{"self":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts\/21929","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/comments?post=21929"}],"version-history":[{"count":0,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts\/21929\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/media\/21949"}],"wp:attachment":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/media?parent=21929"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/categories?post=21929"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/tags?post=21929"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}