A simple, elegant Vite integration for WordPress themes and plugins — inspired by Laravel's Vite helper, providing seamless asset management, HMR support, and production-ready manifest handling.
Seamlessly integrate Vite into your WordPress theme or plugin for fast, modern frontend development with hot module replacement (HMR) and efficient production builds.
- Native WordPress support for Vite assets
- Automatic dev server detection with HMR support
- Manifest-based asset URL resolution for production
- Easy static facade:
Vite::asset()to get asset URLs - Injects
type="module"on scripts for ES modules support - Supports extracting and enqueuing CSS linked from JS entrypoints
For the integration to work correctly, your plugin or theme must have the following directories with exact naming at the root level:
root/
├── resources/
├── public/resources/— Place your source assets here, e.g.resources/js/main.js,resources/scss/style.scss, etc.public/— This is the build output directory where Vite will place compiled assets, including thebuild/folder andmanifest.json.
- These directories must exist and follow the naming convention shown above by default.
- If you want to use different directory names or locations, you must update your
vite.config.jsaccordingly to reflect your custom paths. - For example, change the
baseoption and any path aliases in your Vite config to match your folder names.
- Clone or install the package into your WordPress theme or plugin folder via composer or copy just 2 classes located in
src/to your project
composer require stubbornweb/vite-with-wordpress-
Set up your Vite project with your assets inside the theme/plugin directory, e.g.
resources/js/main.js -
Ensure your Vite config outputs assets to
/public/buildinside your theme/plugin directory -
**Include PHP classes and
autoloador simplyrequirethem into your theme/plugin:
// Bootstrap plugin/theme file
use StubbornWeb\ViteWithWordPress\Vite;
if (file_exists(__DIR__ . '/vendor/autoload.php')) {
require_once __DIR__ . '/vendor/autoload.php';
}Bootstrap without composer via native PHP
// Bootstrap plugin/theme file
require_once 'path_to_new_classes/Vite.php'// vite.config.js
import path from 'path';
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
base: '/wp-content/themes/vite-with-wordpress/public/build',
plugins: [
laravel({
input: [
'resources/js/main.js',
'resources/js/plugins/slider.js',
],
refresh: [
{
paths: ['/**/*.php', '*.php']
}
],
}),
],
resolve: {
alias: {
'@styles': path.resolve(__dirname, 'resources/scss'),
'@scripts': path.resolve(__dirname, 'resources/js'),
'@images': path.resolve(__dirname, 'resources/images'),
'@fonts': path.resolve(__dirname, 'resources/fonts'),
},
},
server: {
host: "0.0.0.0",
port: 5173,
strictPort: true,
cors: {
origin: "https://your-local-dev-url.test",
credentials: true,
},
hmr: {
host: "localhost",
protocol: "ws",
},
},
});use StubbornWeb\ViteWithWordPress\Vite;
add_action('wp_enqueue_scripts', function () {
// ✅ Recommended: Include "vite" in handle to enable `type="module"`
wp_enqueue_script(
'vite-main-script-file',
Vite::asset('resources/js/main.js'),
['jquery'],
'1.0.0',
true
);
wp_enqueue_style(
'vite-main-style-file',
Vite::asset('resources/js/main.js', 'css'),
[],
'1.0.0',
);
// 🚫 Not recommended if you want `type="module"` automatically
// This script will not get the type="module" attribute
wp_enqueue_script(
'main-script-file',
Vite::asset('resources/js/main.js'),
['jquery'],
'1.0.0',
true
);
});- Detects Vite dev server by checking hot file presence and uses HMR URLs for assets.
- Loads manifest.json from public/build/ to resolve hashed filenames for cache-busting.
- By default, Vite assets loaded via wp_enqueue_script() will automatically get type="module" injected to support ES modules.
- ✅ This behavior only applies if the script handle contains the keyword vite (e.g. vite-main-script-file).
- 🚫 If you use a generic or unrelated handle like main-script-file, this enhancement will be skipped to avoid affecting non-Vite scripts.
Vite::asset(string $assetPath, string|bool $css = ''): ?string- Returns the full URL of the asset, adapting automatically to dev server or production build.
- The second argument ('css' or true) returns the CSS file linked from a JS entrypoint, if available.
- Returns null if the asset is unavailable.
- Verify
manifest.jsonexists in public/build after running build. - Confirm
hotfile is present during dev server run. - Make sure your WordPress URL and Vite config base & server.cors.origin are correctly set.
- Errors related to missing assets will trigger a detailed WordPress error message including suggestions.
Contributions welcome! Open an issue or pull request to improve the integration.
Created and maintained by Yevhenii Volosiuk for modern WordPress development with Vite.
Inspired by Laravel.
The MIT License (MIT). Please see License File for more information.