14

I have a react project configured with Vite.
Hot reload works great, but I use react-i18next for multiple language support and this is my structure:

public
  -> en
    -> translation.json
  -> ru
    -> translation.json

When I change the translation.json files, Vite doesn't watch it, and I have to refresh the page to see the changes.

Is there a way to tell Vite to watch all the files in the public directory?

Two Horses
  • 1,401
  • 3
  • 14
  • 35

2 Answers2

11

Edit: You must read and use the answer below.


You can achieve that with a plugin.

I made a mistake on my first answer, it should be a full-reload event and not a update event

export default function CustomHmr() {
    return {
      name: 'custom-hmr',
      enforce: 'post',
      // HMR
      handleHotUpdate({ file, server }) {
        if (file.endsWith('.json')) {
          console.log('reloading json file...');
  
          server.ws.send({
            type: 'full-reload',          
            path: '*'
          });
        }
      },
    }
}

then add the plugin in vite.config.js :

{
  plugins: [
    CustomHmr()   <---  custom plugin
  ]
}

Check the example published on Stackblitz:

Result Illustration

enter image description here

flydev
  • 4,327
  • 2
  • 31
  • 36
  • Tried it, doesn't work. Also I'm using Typescript and the return type of the custom plugin doesn't match to what Vite accepts in the plugins array which is ```Plugin``` – Two Horses Oct 21 '21 at 05:58
  • Please show us your `vite.config.js` please, as I just tested it again and it work as expected. – flydev Oct 21 '21 at 06:13
  • @TwoHorses I updated my answer, you will find a Gituhb repo with full working example. – flydev Oct 21 '21 at 12:42
  • Thanks this works. One question, I notice that when I update a json file, the entire window is reloaded. But when you just change a component content, it only updates that part of the app, without full reload. Is that impossible to achieve? – Two Horses Oct 21 '21 at 14:43
  • 1
    Did you mean updating the json content without full-reload ? if yes, no I am afraid, at least at this moment. If I find how to do it, I will update the answer. – flydev Oct 21 '21 at 14:50
9

I've modified flydev's answer so that it can hot-reload the i18n-dependent components without reloading the whole page. (Currently using in a typescript project)

import { PluginOption } from "vite";

export default function I18nHotReload(): PluginOption {
  return {
    name: 'i18n-hot-reload',
    handleHotUpdate({ file, server }) {
      if (file.includes('locales') && file.endsWith('.json')) {
        console.log('Locale file updated')
        server.ws.send({
          type: "custom",
          event: "locales-update",
        });
      }
    },
  }
}

Then adding it to the vite's plugins:

plugins: [
    ...,
    i18nHotReload(),
]

And then adding the listener anywhere your code can reach (I'm using it in the i18n initial config file)

if (import.meta.hot) {
  import.meta.hot.on('locales-update', () => {
    i18n.reloadResources().then(() => {
      i18n.changeLanguage(i18n.language)
    })
  })
}

i18n.reloadResources() alone doesn't trigger the translations hot reload

Dharman
  • 30,962
  • 25
  • 85
  • 135
Erick Lima
  • 91
  • 1
  • 2