Search code examples
reactjsnext.jsi18nextreact-i18nextnext-i18next

Next.js and i18next - two variables in single translation - instead of Link I get [object Object]


I have a Footer component:

export default function Footer() {
  const { t } = useTranslation("layout-footer");
  const currentYear = new Date().getFullYear();

  return (
    <footer className='py-6 mt-20 border-t-[1px] border-opacity-50'>
      <p className='text-sm text-center mb-6'>{t("addresses")}</p>
      <p className='text-sm text-center mb-6'>
        <Trans
          i18nKey='information'
          t={t}
          components={{
            currentYear,
            link: (
              <Link
                href='https://www.signinsolutions.com'
                className='text-green-600'
                rel='noreferrer'
                target='_blank'
              >
                Sign In Solutions
              </Link>
            ),
          }}
        />
      </p>
    </footer>
  );
}

json file:

{
  "information": "© {{currentYear}} Sign In App Ltd is part of the {{link}} suite of brands providing global, cloud-based solutions to manage visitors, employees, workplaces and beyond."
}

I tried multiple different things without success - I just can't get seem to get that currentYear and Link component rendered in my translation at the same time - Link will always be as [Object object]

Screenshot


Solution

  • I would suggest to use i18next interpolation in this example. let me provide the draft of solution for you:

    footer component should look like that:

    export default function Footer() {
      const { t } = useTranslation("layout-footer");
      const currentYear = new Date().getFullYear();
      const link = "LINK HERE";
    
      return (
        <footer className='py-6 mt-20 border-t-[1px] border-opacity-50'>
          <p className='text-sm text-center mb-6'>{t("addresses")}</p>
          <p className='text-sm text-center mb-6'>
            {t("information", {currentYear, link} )}
          </p>
        </footer>
      );
    }
    

    if you want to disable escaping then in your translation JSON file please use little minus character after opening double curly brackets {{- variable_name}} like that:

    {
      "information": "© {{currentYear}} Sign In App Ltd is part of the {{- link}} suite of brands providing global, cloud-based solutions to manage visitors, employees, workplaces and beyond."
    }
    

    ANOTHER SOLUTION TO USE COMPONENT WITH TRANSLATION

    In the case when you want to use the whole component the best option is to use Trans component from next-i18next. The below example is showing how to do that:

    export default function Footer() {
      const { t } = useTranslation("layout-footer");
      const currentYear = new Date().getFullYear();
    
      return (
        <footer className='py-6 mt-20 border-t-[1px] border-opacity-50'>
          <p className='text-sm text-center mb-6'>{t("addresses")}</p>
          <p className='text-sm text-center mb-6'>
            <Trans 
              i18nKey="information"
              t={t}
              components={[ <a href='https://www.signinsolutions.com' className='text-green-600' rel='noreferrer' target='_blank' /> ]}
              values={{currentYear}}
            />
          </p>
        </footer>
      );
    }
    

    and then in JSON file:

    {
      "information": "© {{currentYear}} Sign In App Ltd is part of the <0>Sign In Solutions</0> suite of brands providing global, cloud-based solutions to manage visitors, employees, workplaces and beyond."
    }