Get a free advice now!

    Pick the topic

    [checkbox* "Developer Outsourcing" "Web developing" "App developing" "Digital Marketing" "eCommerce systems" "eEntertainment systems"]

    Thank you for your message. It has been sent.

    Tags

    i18next React – links inside translations

    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

    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

    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 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

    Using i18next in React

    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.

    Comments
    0 response

    Add comment

    Your email address will not be published. Required fields are marked *

    Popular news

    PHPStorm – fix long load time of a directory window
    • Dev Tips and Tricks

    PHPStorm – fix long load time of a directory window

    January 20, 2023 by createIT
    reCAPTCHA v3 – WordPress implementation
    • Dev Tips and Tricks

    reCAPTCHA v3 – WordPress implementation

    January 20, 2023 by createIT
    How to compare GIT and server files
    • Dev Tips and Tricks

    How to compare GIT and server files

    January 19, 2023 by createIT
    How to trigger a click event inside iframe?
    • Dev Tips and Tricks

    How to trigger a click event inside iframe?

    January 19, 2023 by createIT
    FOOEvents – generate a custom CSV report
    • Dev Tips and Tricks

    FOOEvents – generate a custom CSV report

    January 19, 2023 by createIT
    Headless chrome – testing webgl using playwright
    • Dev Tips and Tricks

    Headless chrome – testing webgl using playwright

    January 18, 2023 by createIT
    Preview big SQL files with PilotEdit
    • Dev Tips and Tricks

    Preview big SQL files with PilotEdit

    January 18, 2023 by createIT
    Outsourcing a team of backend developers
    • Our Highlights

    Outsourcing a team of backend developers

    January 18, 2023 by createIT
    A new look for an aspiring brand
    • Our Highlights

    A new look for an aspiring brand

    January 18, 2023 by createIT
    Percy AI visual regressions – playwright example
    • Dev Tips and Tricks

    Percy AI visual regressions – playwright example

    January 17, 2023 by createIT

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

    Contact us