# Block Editor Development with HMR Support

**URL:** https://discourse.roots.io/t/block-editor-development-with-hmr-support/24963
**Category:** blog
**Tags:** bud, gutenberg
**Created:** 2023-03-14T18:36:57Z
**Posts:** 5

## Post 1 by @kellymears — 2023-03-14T18:36:57Z

Find out how to use the [`@roots/wordpress-hmr` library](https://bud.js.org/extensions/bud-preset-wordpress/editor-integration) to build WordPress blocks and other block editor customizations with hot reload (HMR) support.

> **[Block Editor Development with HMR Support](https://roots.io/block-editor-development-with-hmr-support/)**
>
> Find out how to use the `@roots/wordpress-hmr` library to build WordPress blocks and other block editor customizations with hot reload (HMR) support.

---

## Post 2 by @dave_m — 2023-05-02T10:31:00Z

In this blog post it says “Moreover, the wordpress-hmr package can be used independently of bud.js or even webpack.”

I’m trying to achieve exactly that (we use vite & TS) but am struggling to get hot reloading working for our custom blocks. The documentation is a bit difficult to understand (even in the bud context). I checked the code to make sense of it and maybe derive from there how to get this working but without success.

I would be very grateful for some pointers in the right direction as hmr is something I’ve been wanting to get working in the block editor for ages. Thanks in advance.

---

## Post 3 by @kellymears — 2023-05-02T15:46:15Z

The `src/loader.ts` module is just sugar for theme/plugin developers. It replaces `roots.register` with the actual call. Without the loader `roots.register('./blocks')` is desugared to:

```
import * as blocks from '@roots/wordpress-hmr/blocks';

blocks.register(
  () => import.meta.webpackContext(
    './',
    {recursive: true, regExp: /.*\\.blocks\\..*$/}
  ),
  (id, context) => {
    if (import.meta.webpackHot) return import.meta.webpackHot.accept(id, context)
  },
);
```

If you check out [the source for the `blocks` module](https://github.com/roots/bud/edit/main/sources/%40roots/wordpress-hmr/src/blocks.ts) it defines what should happen before a hot reload event and what should happen after. This is a curried function that is passed to [the `editor` module](https://github.com/roots/bud/blob/f9f7358dcbdf9d94ce5058aa6887751dd8ab692b/sources/%40roots/wordpress-hmr/src/editor.ts) which executes the two callbacks (`before` and `after`). All of the entities recycle the `editor` module in the way I just described.

The interface looks like this:

> <https://github.com/roots/bud/blob/f9f7358dcbdf9d94ce5058aa6887751dd8ab692b/sources/%40roots/wordpress-hmr/src/editor.ts#LL6C1-L15C2>

What you’re trying to do is replace the `editor.load` function with a `vite` specific implementation.

You should check out the vite docs for the vite HMR API and the vite `handleHotUpdate` method from its plugin API:

[https://vitejs.dev/guide/api-hmr.html#hmr-api](https://vitejs.dev/guide/api-hmr.html#hmr-api)

[https://vitejs.dev/guide/api-plugin.html#handlehotupdate](https://vitejs.dev/guide/api-plugin.html#handlehotupdate)

---

## Post 4 by @dave_m — 2023-05-03T07:55:11Z

Thanks a lot mate!!!

That helps a lot and gives me a good starting point for trying to figure this out. I’ll be back with either some questions, or with a finished solution to share with others.

cheers

---

## Post 5 by @dave_m — 2023-05-03T10:01:52Z

I was able to make it work.

This is the code in the main file that is enqueued in the block editor

```
import { blocks } from '@roots/wordpress-hmr';
import createRequireContext from "./createRequireContext";

const modules = import.meta.glob('./**/*.block.*', { eager: true });
blocks.register(
  () => createRequireContext(modules, import.meta.url),
  (id, context) => {
    if (import.meta.hot) {
      return import.meta.hot.accept(id.toString(), context);
    }
  },
);

if (import.meta.hot) {
  import.meta.hot.accept();
}
```

`createRequireContext()` transforms our modules into the format expected by `blocks.register()`. The latter is expecting `__WebpackModuleApi.RequireContext` so we needed to add `@types/webpack-env` to our `devDependencies` so `ts` knows what’s up with that.

```
import RequireContext = __WebpackModuleApi.RequireContext;

const createRequireContext = <T = any>(modules: Record<string, T>, moduleId: string): RequireContext => Object.assign(
    (id: string) => modules[id],
    {
      keys: () => Object.keys(modules),
      resolve: (id: string) => id,
      id: moduleId
    }
  );

export default createRequireContext;
```

The only thing not working is the initial snackbar notice informing us that hot reload is enabled. It’s testing for `import.meta.webpackHot` which is always false because in vite this would have to be changed to `import.meta.hot`. Small inconvenience.

Thanks again for your input Kelly.
