Next-i18next: Aggressive caching makes development hard

Created on 26 Jan 2020  Â·  20Comments  Â·  Source: isaachinman/next-i18next

Describe the bug

As far as I could understand from reading other issues like https://github.com/isaachinman/next-i18next/issues/447, https://github.com/isaachinman/next-i18next/issues/369, https://github.com/isaachinman/next-i18next/issues/282, and https://github.com/isaachinman/next-i18next/issues/169 this package loads the translations from the filesystem when the Next.js server is started and keeps them in memory. While this is a good strategy for production it makes development painful – one needs to restart the whole server in order to see an updated translated content.

This could be partially handled by returning namespacesRequired: [] during the development, in this case the server returns the page with the missing content, but the browser fetches updated translations client-side. Unfortunately the defaultNS from the config is always cached, so one needs something like defaultNS: 'empty' to work around this behaviour.

Occurs in next-i18next version

Commit 484450d

Steps to reproduce

git clone https://github.com/isaachinman/next-i18next.git
cd next-i18next
yarn
yarn build
cd examples/simple
yarn
yarn dev
  • Open http://localhost:3000/
  • Now assuming that your system/browser locale is not German, edit the description in the public/static/locales/en/footer.json
  • Refresh the page – no content has changed
  • Edit the Homepage.getInitialProps in pages/index.js to return namespacesRequired: ['common']
  • Refresh the page – the footer's content would get updated and during the short window between the initial load and your browser recreating the page on the client side you will see a "description" instead of any string that you have specified under the description key in the public/static/locales/en/footer.json

Expected behaviour

I would expect the next-i18next not to attempt to cache the translations while Next.js is running in a development mode and always load the fresh version from the filesystem.

OS (please complete the following information)

  • Device: MacBook Pro (Retina, 13-inch, Early 2015), macOS 10.14.6 (18G1012)
  • Browser: Chrome 79.0.3945.130, Safari 13.0.4 (14608.4.9.1.4), Firefox 72.0.2

Most helpful comment

I've developed i18next-hmr that HMR client & server side exactly for this issue.
I'm using it for more then 9 months and really happy with it :]

For server side, it calls reloadResources with the changed translation file, at client side it attaches a cache killer for the xhr request & refetches the new json file.

All 20 comments

As you've seen in other issues, it is quite easy to set up a watch/restart on your locale assets. Building some sort of sophisticated/opinionated hot reload within this package is not a priority at this time. Keep in mind some users consume their assets via network/cdn.

If you'd like to put forward a proof of concept PR, feel free.

@isaachinman And how to achieve this specifically? Would be awesome to have a development guide in the documentation.

nodemon server.js --watch public/static/locales

@isaachinman I think that we do not have a complete understanding among us. While a sophisticated/opinionated hot reload would've been indeed a sweet addition I am talking about the cache invalidation. Currently it is never updated, my suggestion is simple – by detecting that Next.js is running in a development mode the in-memory cache could've been recreated on every network request. Being able to hit the refresh button in the browser and see the updated content would already generate a lot of value to the users of next-i18next, especially to those who consume their assets via network/cdn, since in this case the nodemon solution is not suitable. Additionally server restarts can be quite expensive, for example in our setup the frontend server also acts as a gateway proxy to the backend server. I suppose that the certain performance drop in the development mode (due to the attempts to always load the fresh version of the translations) can be tolerated given the drastic improvement in the developer experience

As I said, POC PRs are welcomed. I can reopen the issue if you plan on working on this.

Yes, please reopen it

@wasd171 Please let me know, if I can assist you, when working on this one.

@iDuuck I have opened a POC PR, feel free to take a look

Saw it, looks good. Will give it a try on my current project. Let's see how it turns out.

Update: Not able to use it, since my compiler keeps bugging that something is not defined, or some random "Unexpected token" errors.

Based on your changes, I created a small monkey-patch, which is working quite well for me for now. Just add the following to your '*' route for express:

if (req && req.i18n) {
  const namespacesToLoad = ['common', 'footer', 'home']
  namespacesToLoad.forEach(ns => {
    req.i18n.reloadResources(req.i18n.languages[0], ns)
  })
}

I think that you could even do the following if you do not have much content (to be more generic)

await req.i18n.reloadResources()

since on the express side req would always be defined

I've developed i18next-hmr that HMR client & server side exactly for this issue.
I'm using it for more then 9 months and really happy with it :]

For server side, it calls reloadResources with the changed translation file, at client side it attaches a cache killer for the xhr request & refetches the new json file.

Hey @felixmosh, looks cool! I think when next-i18next is rewritten as an official NextJs plugin, it might be a good time to pull that functionality into the core.

Hey @felixmosh, looks cool! I think when next-i18next is rewritten as an official NextJs plugin, it might be a good time to pull that functionality into the core.

@isaachinman there is a plan to migrate next-i18next to be an official plugin? why?

The lib is generic, without a dependency on next nor next-i18next (see examples folder, it supports vue & more :])

Has anyone had any luck using i18next-hmr. I've tried without success unfortunately. It would be a nice work around as an alternative as opposed to restarting the server.

@bruqui what is the issue that you get?
I work with it every day :]

For not spamming this thread, you are welcome to open an issue in the lib repo, I will try to help you

@bruqui what is the issue that you get?
I work with it every day :]

For not spamming this thread, you are welcome to open an issue in the lib repo, I will try to help you

Oh, sweet... yeah, I'll open an issue on that repo.

So after @felixmosh helped me figure out my code mistake in the above issue, the i18next-hmr library is working out really great for me.

Also, here's a starter repo with the settings to add i18next-hmr library...
nextjs-starter-with-scss-and-i18n

i18next-hmr works smoothly for me

Was this page helpful?
0 / 5 - 0 ratings