Next-i18next: Warning ["not declared namespacesRequired array"] is happening even if name spaces is declared

Created on 17 Mar 2020  路  6Comments  路  Source: isaachinman/next-i18next

Describe the bug

I've been receiving this warning for all pages on console when I run the server.

You have not declared a namespacesRequired array on your page-level component: withI18nextTranslation(HomePage). This will cause all namespaces to be sent down to the client, possibly negatively impacting the performance of your app. For more info, see: https://github.com/isaachinman/next-i18next#4-declaring-namespace-dependencies

My locales:

| - public
|  | - static
|  |  | - locales
|  |  |  | - en
|  |  |  |  | - common.json
|  |  |  |  | - home.json
|  |  |  | - pt
|  |  |  |  | - common.json
|  |  |  |  | - home.json

I created the server.js

const express = require('express');
const next = require('next');
const nextI18NextMiddleware = require('next-i18next/middleware').default;

const nextI18next = require('./i18n');

const port = process.env.PORT || 3000;
const app = next({ dev: process.env.NODE_ENV !== 'production' });
const handle = app.getRequestHandler();

(async () => {
    await app.prepare();
    const server = express();

    await nextI18next.initPromise;
    server.use(nextI18NextMiddleware(nextI18next));

    server.get('*', (req, res) => handle(req, res));

    await server.listen(port);
    // eslint-disable-next-line no-console
    console.log(`> Ready on http://localhost:${port}`);
})();

i18n.js

const NextI18Next = require('next-i18next').default;
const { initReactI18next } = require('react-i18next');

module.exports = new NextI18Next({
  defaultLanguage: 'en',
  otherLanguages: ['en', 'pt'],
  use: [initReactI18next],
  localeSubpaths: {
    en: 'en',
    pt: 'pt',
  },
});

It's my _app.js:

import React, { useEffect } from 'react';
import { func, object } from 'prop-types';
import Router from 'next/router';
import { ThemeProvider } from '@material-ui/core/styles';
import { ThemeProvider as SCThemeProvider } from 'styled-components';

import { appWithTranslation } from '../i18n';
import * as gtag from '../utils/gtag';
import muiTheme from '../styles/theme';
import GlobalStyle from '../styles/GlobalStyle';

Router.events.on('routeChangeComplete', (url) => gtag.pageview(url));

const MyApp = ({ Component, pageProps }) => {
  useEffect(() => {
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) {
      jssStyles.parentElement.removeChild(jssStyles);
    }
  }, []);

  return (
    <SCThemeProvider theme={muiTheme}>
      <ThemeProvider theme={muiTheme}>
        <GlobalStyle />
        <Component {...pageProps} />
      </ThemeProvider>
    </SCThemeProvider>
  );
};

MyApp.propTypes = {
  Component: func.isRequired,
  pageProps: object.isRequired,
};

export default appWithTranslation(MyApp);

And my index.js

import React from 'react';
import { func } from 'prop-types';

import { withTranslation } from '../i18n';

const HomePage = ({ t }) => (
  <div>{t('banner title')}</div>
);

HomePage.getInitialProps = async () => ({
  namespacesRequired: ['common', 'home'],
});

HomePage.propTypes = {
  t: func.isRequired,
};

export default withTranslation('home')(HomePage);

Occurs in next-i18next version

"i18next": "^19.3.2",
"next": "^9.3.0",
"next-i18next": "^4.2.0",

Steps to reproduce

It's happened after run the server
Screen Shot 2020-03-17 at 15 02 52

Expected behaviour

To not show any warning about namespacesRequired, it's warning about performance negative impacts.

Screenshots

If applicable, add screenshots or a GIF to help explain your problem.

OS (please complete the following information)

  • Device: MB air 2017 13
  • Browser: Chrome 80.0.3987.106

Additional context

The i18n is working fine, it's translating using the routes, that's ok. The only trouble is this warning and the impact about performance I can have with this.

I'm not used to create issues like this, but I don't know more where I can find a help. I've already read the document explaining about it and I believe that I'm doing everything ok.

All 6 comments

Read the docs carefully.

Your app component must either extend App if it's a class component or define a getInitialProps if it's a function component (explanation here).

@joaolavoierfh if your _app.js is functions(which is) you should define getInitialProps as follow:

import App from 'next/app'

.
.
.

MyApp.getInitialProps = async (appContext) => {
  const appProps = await App.getInitialProps(appContext)
  return { ...appProps }
}

To be fair, this could've gotten its separate point in the steps. It really is way too easy to miss.

Looking at the amount of false bug submissions about this issue (and the amount of time I've spent trying to figure this out :)), this was easily overlooked

@timohermans What do you feel should be in the docs? Both problems discussed in this issue are in the README.

So I think the README could be improved to this:

1. Create an _app.js file inside your pages directory, and wrap it with the NextI18Next.appWithTranslation higher order component (HOC). You can see this approach in the examples/simple/pages/_app.js. 

2. Make sure the initial props from the Next App are passed down. Your app component must either extend App if it's a class component or define a getInitialProps if it's a functional component (explanation here).

3. Create a next.config.js file inside your root directory if you want to use locale subpaths. You can see this approach in the examples/simple/next.config.js.

So all the info is already there, however point 2 above is easily missed, because it's in the same paragraph as the HOC explanatino

edit: Btw, I love the work you've done :D. It works like a charm. Kudos!

I have fixed it in nextjs template
1: config getInitialProps in file _app.tsx
import { FC } from 'react';
import { appWithTranslation } from 'i18n';

import NextApp, { AppProps, AppContext } from 'next/app';

const App: FC = ({ Component, pageProps }) => {
return ;
};

App.getInitialProps = async (appContext: AppContext): any => ({
...(await NextApp.getInitialProps(appContext)),
});

export default appWithTranslation(App);

2: in file parent, i have config
import React from 'react';
import CampaignsV from '@lib/view/pages/campaigns';
import { withTranslation } from 'i18n';

import { WithTranslation } from 'next-i18next';

const CampaignsVM: NextPage = ({ t }) => {
return ;
};

CampaignsVM.getInitialProps = async (): any => ({
namespacesRequired: ['common', 'table', 'campaign'],
});
export default withTranslation('common')(CampaignsVM);

3: in file children, i used
import React from 'react';
import { withTranslation } from 'i18n';
import { WithTranslation } from 'next-i18next';
import { NextPage } from 'next';
const CampaignsV: NextPage> = ({
t,
test
}) => {
return (

{test}


);
};
CampaignsV.getInitialProps = async (): any => ({
namespacesRequired: ['table', 'campaign', 'common'],
});

export default withTranslation(['table', 'campaign'])(CampaignsV);

and file i18n i have configured like this

const NextI18Next = require('next-i18next').default;

const config = {
defaultLanguage: 'en',
otherLanguages: ['th'],
localeSubpaths: {
th: 'th',
en: 'en',
},
};
const NextI18NextInstance = new NextI18Next(config);

module.exports = NextI18NextInstance;

Was this page helpful?
0 / 5 - 0 ratings