The Problem:
In a Next.js app using Next-i18next for localization, an array of objects is passed as props to a custom BannerCarousel
component, and the component maps through the array to create its content. The data for the carousel items is loaded through t('home:banner-carousel', { returnObjects: true })
in the getServerSideProps
function. However, when the page is rendered, the client-side content does not match the server-rendered HTML, resulting in the following error: Text content does not match server-rendered HTML
. Despite attempts to address the issue, such as using a useEffect with a boolean flag to gate the rendering of the carousel or loading the array through a separate instance of i18n.t()
, the problem persists.
The Solutions:
Solution 1: Import UseTranslation from Next-i18next and Wrap App with AppWithTranslation
Ensure you import useTranslation
from next-i18next
rather than react-i18next
. serverSideTranslations
returns a customized object that includes the _nextI18Next
property, which is why this is necessary.
To enable client-side hydration of server-rendered data, including _nextI18Next
, wrap your entry component App
with the appWithTranslation
higher-order component. Here’s how it should look like:
//App.tsx
import { appWithTranslation } from 'next-i18next';
const App = () => {
return <Home />;
};
export default appWithTranslation(App);
Q&A
Why do I get a hydration error when mapping an array using Next I18Next?
Ensure useTranslation
is imported from next-i18next
and wrap App
with appWithTranslation
.
What is the difference between i18n.useTranslation() and next-i18next.useTranslation()?
i18next.useTranslation() is not aware of _nextI18Next
while next-i18next.useTranslation() is.