WP Manifestindependent plugin directory
manifest / developer / vite-hmr-for-wordpress

Vite HMR Integration

A Wordpress plugin that allows for easy setup of Vite hot module reloading

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/jack-sandeman/vite-hmr-for-wordpress/archive/refs/heads/master.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

A must-use plugin that enables Vite Hot Module Replacement (HMR) for WordPress plugins and themes. Once installed, other plugins can easily integrate Vite with zero configuration.

Features

  • ✨ Zero Config HMR: Automatically detects dev vs production mode
  • 🔥 Hot Module Replacement: Instant updates without page refresh
  • ⚛️ React Fast Refresh: Built-in support for React projects
  • 📦 Smart Asset Loading: Loads from dev server or production manifest
  • 🎯 Simple API: Single function call to enqueue Vite assets
  • 🔧 Flexible Configuration: Customize dev server URL, port, and more

Installation

This is a must-use plugin, which means it's automatically activated when placed in the mu-plugins directory.

For Bedrock-based WordPress installations:

# Already installed at: web/app/mu-plugins/vite-hmr/

For standard WordPress installations:

# Copy the vite-hmr folder to wp-content/mu-plugins/

Usage

Quick Start

  1. In your plugin/theme directory, copy the example Vite config:
cp web/app/mu-plugins/vite-hmr/vite.config.example.js vite.config.js
  1. Install Vite (and React plugin if using React):
npm install --save-dev vite
# If using React:
npm install --save-dev @vitejs/plugin-react
  1. Create your entry point (e.g., src/main.tsx or src/main.js):
// src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import './style.css'

function App() {
  return <h1>Hello from Vite + React + WordPress!</h1>
}

ReactDOM.createRoot(document.getElementById('root')!).render(<App />)
  1. Enqueue the asset in your plugin:
<?php
// your-plugin.php

add_action('wp_enqueue_scripts', function() {
    // Simple usage - auto-detects plugin directory
    \ViteHMR\vite_enqueue_asset('my-app', 'src/main.tsx');
});
  1. Start the dev server:
npm run dev
  1. Build for production:
npm run build

API Reference

vite_enqueue_asset()

Enqueue a Vite asset in development or production mode.

\ViteHMR\vite_enqueue_asset(string $handle, string $entry, array $options = [])

Parameters

  • $handle (string, required): Unique identifier for this asset
  • $entry (string, required): Entry point file relative to plugin root (e.g., src/main.tsx)
  • $options (array, optional): Configuration options

Options

[
    'plugin_dir' => null,                      // Auto-detected if not provided
    'plugin_url' => null,                      // Auto-detected if not provided
    'dev_server' => 'http://localhost:5173',   // Dev server URL
    'dev_port' => 5173,                        // Dev server port
    'dependencies' => [],                      // Script dependencies
    'in_footer' => true,                       // Load script in footer
]

Examples

Basic Usage

// Enqueue with default options
add_action('wp_enqueue_scripts', function() {
    \ViteHMR\vite_enqueue_asset('my-app', 'src/main.tsx');
});

Admin Scripts

// Enqueue in admin area
add_action('admin_enqueue_scripts', function() {
    \ViteHMR\vite_enqueue_asset('my-admin-app', 'src/admin.tsx');
});

With Dependencies

// Enqueue with jQuery dependency
add_action('wp_enqueue_scripts', function() {
    \ViteHMR\vite_enqueue_asset('my-app', 'src/main.js', [
        'dependencies' => ['jquery'],
    ]);
});

Custom Dev Server

// Use custom dev server port
add_action('wp_enqueue_scripts', function() {
    \ViteHMR\vite_enqueue_asset('my-app', 'src/main.tsx', [
        'dev_server' => 'http://localhost:3000',
        'dev_port' => 3000,
    ]);
});

Multiple Entry Points

add_action('wp_enqueue_scripts', function() {
    // Frontend app
    \ViteHMR\vite_enqueue_asset('frontend-app', 'src/frontend/main.tsx');

    // Widget app
    \ViteHMR\vite_enqueue_asset('widget-app', 'src/widget/main.tsx');
});

add_action('admin_enqueue_scripts', function() {
    // Admin app
    \ViteHMR\vite_enqueue_asset('admin-app', 'src/admin/main.tsx');
});

How It Works

Development Mode

When Vite dev server is running (npm run dev):

  1. Plugin detects dev server at http://localhost:5173
  2. Injects Vite client for HMR
  3. Injects React Refresh runtime (for .tsx/.jsx files)
  4. Loads assets directly from dev server
  5. Hot module replacement works automatically

Production Mode

When Vite dev server is NOT running:

  1. Plugin reads .vite/manifest.json (generated by npm run build)
  2. Loads hashed production assets from dist/ directory
  3. Automatically enqueues associated CSS files
  4. Uses versioned assets for cache busting

Project Structure

your-plugin/
├── src/
│   ├── main.tsx          # Entry point
│   ├── App.tsx           # React components
│   └── style.css         # Styles
├── dist/                 # Production build (generated)
│   ├── .vite/
│   │   └── manifest.json # Asset manifest
│   └── assets/           # Compiled assets
├── vite.config.js        # Vite configuration
├── package.json          # Dependencies
├── tsconfig.json         # TypeScript config (optional)
└── your-plugin.php       # WordPress plugin file

Vite Configuration

The example config (vite.config.example.js) includes:

  • React plugin support
  • HMR configuration
  • Build optimization
  • Manifest generation
  • Code splitting
  • CSS processing

Key Configuration Options

export default defineConfig({
  server: {
    port: 5173,           // Dev server port
    cors: true,           // Enable CORS for WordPress
    hmr: {
      host: 'localhost',  // HMR host
      protocol: 'ws',     // WebSocket protocol
    },
  },
  build: {
    manifest: true,       // Generate manifest.json
    outDir: 'dist',       // Output directory
    rollupOptions: {
      input: {
        main: './src/main.tsx',  // Entry points
      },
    },
  },
})

TypeScript Support

For TypeScript projects, create a tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src"]
}

Troubleshooting

HMR Not Working

  1. Check dev server is running:

    npm run dev
  2. Verify dev server URL:

    • Default: http://localhost:5173
    • Check console for connection errors
  3. Check firewall/ports:

    • Ensure port 5173 is accessible
    • Try accessing http://localhost:5173 in browser

Assets Not Loading in Production

  1. Build the project:

    npm run build
  2. Verify manifest.json exists:

    ls dist/.vite/manifest.json
  3. Check file permissions:

    chmod -R 755 dist/

React Refresh Not Working

  1. Ensure React plugin is installed:

    npm install --save-dev @vitejs/plugin-react
  2. Enable in vite.config.js:

    import react from '@vitejs/plugin-react'
    
    export default defineConfig({
      plugins: [react()],
    })

CORS Issues

If you see CORS errors in the console:

  1. Check Vite config:

    server: {
      cors: true,
    }
  2. Verify WordPress headers are being sent (handled by plugin)

Advanced Usage

Custom Dev Server Detection

// Override dev server detection
add_filter('vite_hmr_is_dev', function($is_dev) {
    return defined('VITE_DEV_MODE') && VITE_DEV_MODE;
});

Custom Manifest Path

// Use custom manifest location
add_filter('vite_hmr_manifest_path', function($path, $plugin_dir) {
    return $plugin_dir . 'build/.vite/manifest.json';
}, 10, 2);

Multiple Vite Projects

// Different dev servers for different plugins
add_action('wp_enqueue_scripts', function() {
    // Plugin 1 on port 5173
    \ViteHMR\vite_enqueue_asset('plugin1', 'src/main.tsx', [
        'dev_server' => 'http://localhost:5173',
        'dev_port' => 5173,
    ]);

    // Plugin 2 on port 5174
    \ViteHMR\vite_enqueue_asset('plugin2', 'src/main.tsx', [
        'dev_server' => 'http://localhost:5174',
        'dev_port' => 5174,
    ]);
});

License

MIT

Credits

Built for WordPress developers who want modern development tools without the hassle.