Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server HMR not working on Next.js v13 #137

Open
geoapostolidis opened this issue May 15, 2023 · 11 comments
Open

Server HMR not working on Next.js v13 #137

geoapostolidis opened this issue May 15, 2023 · 11 comments

Comments

@geoapostolidis
Copy link

I used this one practice

  1. Install these two dependencies:
yarn add i18next-hmr i18next-http-backend --dev
  1. Update the next.config.js like so:
const { resolve } = require("path")
const { I18NextHMRPlugin } = require("i18next-hmr/plugin")

const localesDir = resolve("public/locales")

module.exports = {
  // ...other next config options
  webpack(config, context) {
    if (!context.isServer && context.dev) {
      config.plugins.push(new I18NextHMRPlugin({ localesDir }))
    }

    return config
  },
}
  1. Update the next-i18next.config.js like so:
const HttpBackend = require("i18next-http-backend/cjs")

module.exports = {
  // ...other next-i18next config options
  use: process.browser ? [HttpBackend] : [],
}
  1. Create a hook for applying the HMR code during development. I created mine in hooks/use-hmr.ts and it looks like this:
import { useTranslation } from "next-i18next"
import { useEffect } from "react"

export const useHMR = (): void => {
  const { i18n } = useTranslation()

  if (process.env.NODE_ENV === "development" && !process.browser) {
    import("i18next-hmr/server").then(({ applyServerHMR }) => {
      applyServerHMR(i18n)
    })
  }

  useEffect(() => {
    if (process.env.NODE_ENV === "development") {
      import("i18next-hmr/client").then(({ applyClientHMR }) => {
        applyClientHMR(i18n)
      })
    }
  }, [i18n])
}
  1. Import and pass next-i18next.config.js to appWithTranslation (typically in pages/_app.tsx) and use the HMR hook created above within the body of the App component:
import { AppProps } from "next/app"
import { FunctionComponent } from "react"
import { appWithTranslation } from "next-i18next"
import { useHMR } from "../hooks/use-hmr"
import i18nextConfig from "../../next-i18next.config"

export const App: FunctionComponent<AppProps> = ({ Component, pageProps }) => {
  useHMR()

  return <Component {...pageProps} />
}

export default appWithTranslation(App, i18nextConfig) // Required to use the HttpBackend that enables HMR on the client

The beauty in this solution is the useHMR hook since it will re-apply the HMR code whenever the i18n instance changes on the client. It also nicely encapsulates the logic for applying the HMR code on the server and client.

@felixmosh perhaps this is something that the repo should export from a nested react module eg.

import { useHMR } from "i18next-hmr/react"

Wrapping the 2 dynamic imports for the client and server "apply HMR" functions with the process.env checks means that the code is stripped out during production builds.

Happy HMR'in! 🕺

and when i update the translation json it correctly updates the translation with hmr but when i reload the page the translations go back to the file that loaded on server start so then i must close server and re-run it to load the updated translations or simply make one change to json file in order to reload it

@felixmosh
Copy link
Owner

Hi, thank you for reporting this issue.
What version of Next.js / next-i18next do you use?

@geoapostolidis
Copy link
Author

"next": "13.3.1",
"next-i18next": "^13.2.2",
"react-i18next": "^12.2.2"

@felixmosh
Copy link
Owner

Cool, from the code snippets that you were posted looks like you are not configured the lib from next-with-next-i18next-v11 example, can you review the example and align your code with it?

Specifically,

  1. you are ignoring serverside HMR in next.config.js (with !context.isServer)
  2. there is missing server config in next-i18next.config.js

@geoapostolidis
Copy link
Author

yes i fixed them but again the same issue

@felixmosh
Copy link
Owner

Did you restart the next server?

@geoapostolidis
Copy link
Author

yes i restarted the server

@felixmosh
Copy link
Owner

Can you prepare a small repository with your setup that reproduces the issue, I will debug it?

@geoapostolidis
Copy link
Author

geoapostolidis commented May 15, 2023

@felixmosh
Copy link
Owner

Thanx, I'll review it asap

@felixmosh
Copy link
Owner

felixmosh commented May 16, 2023

I've tested your version, looks like there are 2 things wrong with i18next values, I need to check the reason for this.

for a mean while, you can remove the server side HMR & use the built-in hack,

export async function getServerSideProps({ locale }) {
  return {
    props: {
      ...(await serverSideTranslations(locale, ['common'], { reloadOnPrerender: process.env.NODE_ENV==='development' }))
      //  ------------------------------------------------------^ reloads on every page load
    }
  };
}

or in the global config

// next-i18next.config.js
const HttpBackend = require("i18next-http-backend/cjs")

module.exports = {
  // ...other next-i18next config options,
  reloadOnPrerender: process.env.NODE_ENV==='development',
  use: process.browser ? [HttpBackend] : [],
}

I need more time to investigate the issue.

@felixmosh felixmosh changed the title Error updating translations on dev Server HMR not working on Next.js v13 May 21, 2023
@felixmosh
Copy link
Owner

felixmosh commented May 22, 2023

Looks like it is an issue in Next v13...
I've tested the same setup in Next v12, it works.

I've added a question here...
vercel/next.js#50164

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants