i18next / next-i18next

The easiest way to translate your NextJs apps.
https://next.i18next.com
MIT License
5.61k stars 762 forks source link

Missing information about how to translate Children Components #2093

Closed BrodaNoel closed 1 year ago

BrodaNoel commented 1 year ago

Documentation issue

It's literally 3:29AM... I have been trying to find a fix for this during around 5 hours, and considering HOW OFTEN this problem should happen, I guess we should have it documented in some super-simple-and-easy-to-find place :)

How to translate a Children Component?

I have a blog page, in pages/blog/[id].js.

This file is rendering ALL the blog post. In the bottom of this [id].js I have a component that shows a marketing text. This one:

<JoinToday />

"JoinToday" is a marketing text that I use in 3 million places, and this is the content:

import React from 'react';
import Download from '../Download';
import styles from './JoinToday.module.css';

const JoinToday = () => {
  return (
    <div className={styles.root}>
      <div className="content-wrapper">
        <h2>{t('header')}!</h2>

        <div className={styles.download_wrapper}>
          <Download />
        </div>
      </div>
    </div>
  );
};

export default JoinToday;

As you can see, there is a t function, but... t doesn't come in props, and if I add serverSideTranslations, the whole component gets broken. So... How can I access to the translator there? How can I translate that header label?

How can I translate that header label?! I already have a public/locale/en/jointoday.json

BrodaNoel commented 1 year ago

I am checking some code here and there and seems like this should be the way, and it works, but... I can't find this documentation in any official website:

import React from 'react';
import { withTranslation } from 'next-i18next';
import Download from '../Download';
import styles from './JoinToday.module.css';

const JoinToday = ({ t }) => {
  return (
    <div className={styles.root}>
      <div className="content-wrapper">
        <h2>{t('header')}!</h2>

        <div className={styles.download_wrapper}>
          <Download />
        </div>
      </div>
    </div>
  );
};

export default withTranslation('jointoday')(JoinToday);
BrodaNoel commented 1 year ago

And as far as I see, the parent component [id].js should be:

...(await serverSideTranslations(locale, ['blog', 'jointoday'])),

instead of

...(await serverSideTranslations(locale, ['blog'])),

But I also can't see documentation about it.

adrai commented 1 year ago

You have multiple ways to use the t function in your child component:

  1. Pass the t function via props down to the children
  2. Pass the translated text via props down to the children, like in this example: https://github.com/i18next/next-i18next/blob/master/examples/simple/components/Header.tsx#L12
  3. Use the useTranslation function, like in this example: https://github.com/i18next/next-i18next/blob/e6b5085b5e92004afa9516bd444b19b2c8cf5758/examples/simple/components/Footer.tsx#L6
  4. Use the withTranslation function, like you described

And in general, you always needs to be sure serverSideTranslations contains all namespaces you need in the tree.

=> https://github.com/i18next/next-i18next#translate-in-child-components