i18next React – links inside translations - createIT
Get a free advice now!

    Pick the topic
    Developer OutsourcingWeb developingApp developingDigital MarketingeCommerce systemseEntertainment systems

    Thank you for your message. It has been sent.

    i18next React – links inside translations

    December 22, 2022
    Last update: August 29, 2024
    3 min read
    82
    0
    0
    i18next React – links inside translations

    CHALLENGE: add dynamic translation to links in React

    SOLUTION: use the LinkText component and the Trans Component from the i18next library

    This article has been reviewed and updated in August 2024 to make it up to date.

    react-i18next is probably the most popular NPM package for translating a React application. It’s downloaded over 1 million times every week. I18next as internationalization-framework is really a complete solution for making a multi-language app: it can detect user language, cache translations, add post-processing (sprinf support) or load files on demand.

    Problem with i18next translation

    As awesome as it is, it does not provide an easy way for translating phrases with variables inside. Let’s say we have a Privacy Policy text with two url values inside the text. The naive approach will be to hardcode urls for pages in every available json translation file.

    The documentation doesn’t really provide a better solution. There is something like replacement tags, but the suggestion is to use the React Developer Tool to inspect an element and find out what node number is assigned to the word ( https://react.i18next.com/latest/trans-component#how-to-get-the-correct-translation-string ). In this article, we will describe how to do it better / easier.

    React-i18next use variables in translations

    We have a privacy policy text that is displayed in the registration form. It includes 2 external links. We would like to pass those as variables to the main translation. This way, we will maintain a separation between i18n link constants and different translations of texts.

    I agree to the Privacy Policy and Terms and Conditions

    This solution provides a universal way to pass dynamic variables to internationalized strings. Your code will be cleaner and more readable.

    Trans and LinkText component

    Pure component LinkText uses props.children to put a text node label between opening and closing A Link tag. You can also pass other arguments, like: title or rel=”nofollow”.

    Here is the entire trick to have a translation that uses predefined variables passed to the Trans component:

    <Trans
        i18nKey="gdpr_policy_links"
        components={{
            link1: <LinkText to={link1} title="My link1" />,
            link2: <LinkText to={link2} title="Another link" />
        }}
    />

    and the definition of the LinkText component:

    export const LinkText = (props) => {
        return (
            <a href={props.to || '#'} target="_blank" title={props.title || ''}>
                {props.children}
            </a>
        );
    };
    Preview

    Now, let’s start from the beginning and let’s prepare a fully working example. The first step is to install the following dependency:

    npm install react-i18next

    Import i18n config:

    // index.jsx
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    import './i18n/config';
    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById('root')
    );
    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();

    Add a standard config file:

    // src/i18n/config.js
    import i18n from 'i18next';
    import { initReactI18next } from 'react-i18next';
    i18n.use(initReactI18next).init({
        fallbackLng: 'en',
        lng: 'en',
        resources: {
            en: {
                translations: require('./locales/en/translations.json')
            },
        },
        ns: ['translations'],
        defaultNS: 'translations'
    });
    i18n.languages = ['en'];
    export default i18n;

    Add a json file with the translation to: src/i18n/locales/en/translations.json

    {
      "gdpr_policy_links": "I agree to <link1>Privacy Policy</link1> and <link2>Terms and Conditions</link2>",
      "gdpr_required_msg": "Please accept Privacy Policy"
    }

    The Main app with the Register Form and predefined links:

    // src/App.jsx
    import React from 'react';
    import './App.css';
    import {RegisterForm} from "./RegisterForm";
    const LINK1 = 'https://www.example1.com';
    const LINK2 = 'https://www.example2.com';
    function App() {
        return (
            <div className="App">
                <RegisterForm link1={LINK1} link2={LINK2} />
            </div>
        );
    }
    export default App;

    Here is an example of how to display translations using i18next. For advanced translations with a link, we’re using the Trans component that is provided by react-i18next:

    // RegisterForm.jsx
    import React from 'react';
    import {Trans, useTranslation} from 'react-i18next'
    import {LinkText} from './LinkText';
    export const RegisterForm = (props) => {
        const {link1, link2} = props;
        const {t} = useTranslation();
        return (
           <>
                <h3>Standard translation</h3>
                {t('gdpr_required_msg')}
                <h3>Translation with variables</h3>
                <Trans
                    i18nKey="gdpr_policy_links"
                    components={{
                        link1: <LinkText to={link1} title="My link1" />,
                        link2: <LinkText to={link2} title="Another link" />
                    }}
                />
            </>
        );
    }
    

    The last piece of the puzzle will be the LinkText component to apply links in the translation text:

    // LinkText.jsx
    import React from 'react';
    export const LinkText = (props) => {
        return (
            <a href={props.to || '#'} target="_blank" title={props.title || ''}>
                {props.children}
            </a>
        );
    };
    Animated preview

    That’s it for today’s tutorial. Make sure to follow us for other tips and guidelines and don’t forget to sign up for our newsletter.

    Do you need someone to implement this i18next solution for you? You may need help from our experienced developers – check our software outsourcing and custom web development pages!

    Support – Tips and Tricks
    All tips in one place, and the database keeps growing. Stay up to date and optimize your work!

    Contact us