So by default all namespaces are sent down to the client, so if you open a page without declaring namespacesRequired you will get a warning:
You have not declared a namespacesRequired array on your page-level component:
ErrorPage. 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
Some observations:
It seems that this only happens when initially load on a page that doesn't declare namespacesRequired even if it doesn't use or import any i18next functionality. So if you start on a page that has namespacesRequired, you're ok as long as those other pages don't use i18next.
adding defaultNS doesn't prevent all of the namespace data from being sent down.
Is there any way to prevent all namespaces by default being sent down? I'd rather not have to create a custom _error.js page and ensure that all other pages have i18next code on them to have efficient code splitting.
Are you saying you want to have untranslated pages in your app? Why not add an empty array?
Essentially that would work, though i'm just thinking of a scenario where you have a lot of pages and would rather just tweak a setting instead of making sure all of those pages have
static async getInitialProps() {
return {
namespacesRequired: [],
}
}
on them.
I think I might have found a solution to do this, we can edit the getInitialProps return value for each page through _app.js
// pages/_app.js
// This will run on initial load & on route changes
static async getInitialProps({ Component, ctx }) {
let pageProps = {} // This is how pages will get their own getinitialprops
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
// If a page does not have namespacesRequired set, add one in with an empty array
/* we could also just check if pageProps.i18n exists, if it exists it means the page is wrapped with the withTranslation() HOC.
But in the case where the withTranslation() HOC is declared and namespacesRequired is not set, we still dont want all namespaces to be loaded. */
if (!pageProps.namespacesRequired) {
pageProps.namespacesRequired = []
}
return { pageProps }
}
Now every page that has not declared namespacesRequired will always return namespacesRequired: [] in their getInitialProps. Now only the default namespace (which by default is 'common') gets passed down unless specified otherwise.
I did this test by initial loading on a page without namespacesRequired, then going to a page that does and call console.log(this.props.i18n.translator.resourceStore.data) to show the loaded namespaces.
Would be nice if this could be a config option within i18next. Though I understand that it's purely convenience, this might prevent people from making a mistake of forgetting to put in a namespacesRequired on a page.
it's purely convenience
I think you've fundamentally misunderstood. The reason we send all namespaces down is if people decide _not_ to split their namespaces.
Deciding to default to an empty array is not a convenience, it would be a bug.
Ahh i understand, but unless i'm missing something here I think there is a use case for developers who want to use namespace splitting but don't want all namespaces to be sent down as default behavior for performance reasons (as long as they set it in the config options and opt in of course), and ensuring its specified on every page might not be reliable especially if there are a lot of pages to track down. Feel free to close this issue as the _app.js code i've posted above seems to solve this for me.
You might be able to do some overrides within the getInitialProps of your _app, and return an empty array if the component itself isn't passing a value up.
Good luck!
in my case, we are using SSG and thus can't define the getInitialProps at all. so when we don't define it, we get this error. need a way as described here to disable that logic. I am generating all locales statically anyways, so dumping all the namespaces is a performance issue and its not needed in this case.
also worth commenting, we thought ignoreRoutes would say "ignore trying to translate/add translation to these routes.", couldn't find really good docs about that online so sharing here.
Most helpful comment
Essentially that would work, though i'm just thinking of a scenario where you have a lot of pages and would rather just tweak a setting instead of making sure all of those pages have
on them.
I think I might have found a solution to do this, we can edit the getInitialProps return value for each page through
_app.jsNow every page that has not declared namespacesRequired will always return namespacesRequired: [] in their getInitialProps. Now only the default namespace (which by default is 'common') gets passed down unless specified otherwise.
I did this test by initial loading on a page without namespacesRequired, then going to a page that does and call
console.log(this.props.i18n.translator.resourceStore.data)to show the loaded namespaces.Would be nice if this could be a config option within i18next. Though I understand that it's purely convenience, this might prevent people from making a mistake of forgetting to put in a namespacesRequired on a page.