i18next-hmr: Client-HMR not working for getStaticPages in NextJS

Describe the bug Client-HMR does not update resource that required in SSG page but not loaded by default in the I18N configuration.

To Reproduce

  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');

const config = {
  i18n: {
    defaultLocale: 'fa',
    locales: ['en', 'fa'],
    localeDetection: false,
  },
  localePath: './public/locales',
  use: typeof window !== 'undefined' ? [HttpBackend] : [],
};

module.exports = config;
  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
  1. Create a SSG page (here faq):
import { GetStaticProps } from 'next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

const Faq = () => {
  return (
    // Content of page
    <></>
  );
};

export const getStaticProps: GetStaticProps = async ({ locale }) => {
  return {
    props: { ...(await serverSideTranslations(locale, ['common', 'faq', 'footer'])) },
  };
};

export default Faq;
  1. Update content of faq.json (any language)
  2. Update content of common.json (any language)

Expected behavior

  • faq.json updates don’t apply to client-side.
  • But Update of common.json, affecting client-side as well.

I am using:

  • OS: Win
  • i18next-hmr version: 1.7.7
  • next-i18next version: 11.0.0
  • i18next-http-backend version: 1.4.0

It seems Client-HMR only works in case that all namespaces declared in next-i18next-config, because the plugin check for i18n.options.ns by default.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 16 (10 by maintainers)

Most upvoted comments

Thank you @felixmosh. Now, it works as expected.