Vue Gutenberg
π§© Write WordPress Gutenberg blocks with Vue 3
by hermes98761234 Β· github.com/hermes98761234/vue-gutenberg
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/hermes98761234/vue-gutenberg/archive/refs/heads/main.zipWrite WordPress Gutenberg block editor UIs with Vue 3.
How it works
A Vue 3 app is mounted inside the block's React edit component. Block attributes flow from React to Vue via a reactive prop, and changes flow back from Vue to React through an update:attributes emit that calls WordPress's setAttributes.
Using the bridge is straightforward β import registerVueBlockType, a Vue SFC, and block.json, then register:
import { registerVueBlockType } from './lib/register-vue-block';
import Edit from './Edit.vue';
import metadata from './block.json';
registerVueBlockType( metadata, {
edit: Edit, // a Vue 3 component: prop `attributes`, emit `update:attributes`
save: ( { attributes } ) => /* plain Gutenberg save */,
} );
The edit component is a standard Vue 3 component that receives block attributes as a prop and emits update:attributes with a partial attributes object to update them. The save function stays a plain React/JSX function β it determines the block's saved markup and cannot use Vue.
Under the hood, registerVueBlockType wraps your Vue component with the vueEdit bridge, which:
- Creates a reactive state object mirroring the block's attributes.
- Mounts a Vue app inside a div rendered by the React component.
- Syncs React β Vue: whenever the block's attributes change, a
useEffectupdates the reactive state. - Syncs Vue β React: the
update:attributesevent callssetAttributeson the latest block props via a ref (avoiding stale closures).
Install
Download vue-gutenberg.zip from the latest GitHub release and install via Plugins β Add New β Upload Plugin in your WordPress admin. Activate the plugin β the example block will be available in the block inserter.
Alternatively, clone the repo and build from source:
git clone https://github.com/hermes98761234/vue-gutenberg.git
cd vue-gutenberg
npm install
npm run build
Then symlink the directory into wp-content/plugins/ and activate from the WordPress admin.
Development
npm install # install dependencies
npm test # run vitest test suite
npm run build # build with Vite β outputs to build/
npm testruns the vitest suite β tests validate the bridge logic (attribute syncing, Vue app lifecycle) using jsdom and React Testing Library.npm run buildinvokes Vite to produce an IIFE bundle with@wordpress/*packages externalized towp.*globals and Vue 3 bundled in. The result lands inbuild/alongsideblock.json,index.asset.php, andvue-gutenberg.css.
Limitations
- Gutenberg React components (e.g.
RichText,InspectorControls,PanelBody) cannot be used inside the Vue component tree β they expect a React context that Vue's DOM doesn't provide. Any block settings UI that uses these must live outside the Vue tree (e.g. a separate ReactInspectorControlswrapper). saveis plain Gutenberg. The block's saved output is always a plain React/JSX function; Vue is only used in the editor UI.- Bundle size. Vue 3 (~60 KB min+gzip) is bundled into the block script. Each block registered with Vue Gutenberg includes the full runtime.
Project structure
vue-gutenberg/
βββ src/
β βββ lib/
β β βββ register-vue-block.js # vueEdit bridge + registerVueBlockType
β βββ blocks/
β βββ example/
β βββ block.json # block metadata (name, attributes, etc.)
β βββ Edit.vue # Vue 3 SFC β the editor UI
β βββ index.js # block registration entry
βββ vue-gutenberg.php # plugin bootstrap (register_block_type)
βββ build/ # production output (Vite)
β βββ index.js # IIFE bundle with Vue bundled in
β βββ block.json
β βββ index.asset.php
β βββ vue-gutenberg.css
βββ tests/
β βββ vue-edit.test.js # test suite for the bridge
β βββ stubs/ # WordPress module stubs for jsdom
βββ assets/
β βββ index.asset.php # dependency manifest (source)
βββ package.json
βββ vite.config.js
βββ vitest.config.js
License
GPL-2.0-or-later