pentatrion/vite-bundle
Symfony bundle integrating Vite for easy asset loading. Provides Twig functions to render the right script and link tags for Vite dev server and production builds (including React dependency handling). Install via Composer and use vite_entry_* tags in templates.
Install the Bundle
composer require pentatrion/vite-bundle
This auto-configures Symfony via a recipe, including:
/build).vite-plugin-symfony integration.package.json/vite.config.js templates.Run Vite Dev Server
npm install
npm run dev
Integrate Twig Tags
Add these to your base template (e.g., base.html.twig):
{% block stylesheets %}
{{ vite_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ vite_entry_script_tags('app') }}
{% endblock %}
Replace 'app' with your Vite entry point (defined in vite.config.js).
Verify
/public/build/ (configured in vite.config.js).assets/ and package.json:
mv assets assets.bak
composer remove symfony/webpack-encore-bundle
mv assets.bak assets
vite.config.js:
import symfonyPlugin from 'vite-plugin-symfony';
export default {
plugins: [symfonyPlugin()],
build: {
rollupOptions: {
input: {
app: './assets/app.js', // Match Twig entry point
},
},
},
};
Entry Points
Define entries in vite.config.js as an object:
build: {
rollupOptions: {
input: {
app: './assets/app.js',
admin: './assets/admin.js',
},
},
}
Use in Twig:
{{ vite_entry_link_tags('admin') }}
{{ vite_entry_script_tags('app') }}
Environment-Specific Configs
Use mode in vite.config.js:
export default defineConfig(({ mode }) => ({
plugins: [symfonyPlugin({ enabled: mode !== 'production' })],
}));
Dynamic Imports For lazy-loaded assets (e.g., Stimulus controllers):
// vite.config.js
plugins: [
symfonyPlugin({
stimulus: {
controllersDir: './assets/controllers',
},
}),
];
Symfony UX (React/Vue)
@symfony/ux-react or @symfony/ux-vue alongside.vite.config.js includes:
plugins: [
symfonyPlugin(),
react(), // or vue()
],
Legacy Browser Support
vite-plugin-symfony's legacy option:
symfonyPlugin({
legacy: {
build: './assets/legacy.js',
},
});
<script nomodule> fallbacks.Environment Variables Expose Symfony env vars to Vite:
symfonyPlugin({
exposedEnvVars: ['APP_ENV', 'APP_DEBUG'],
});
Access in JS:
import.meta.env.APP_ENV;
Custom Build Output
Override outDir in vite.config.js:
build: {
outDir: '../public/custom-build',
}
Update Symfony’s asset path in config/packages/pentatrion_vite.yaml:
pentatrion_vite:
build_directory: '/custom-build'
Missing manifest.json in Dev Mode
manifest.json for prod builds but removes it in dev.npm run dev is running when accessing dev assets. Use npm run build for prod.CORS Errors in Dev
/build proxy.vite.config.js:
server: {
proxy: {
'/build': {
target: 'https://symfony.local',
changeOrigin: true,
},
},
}
Stimulus HMR Not Working
symfonyPlugin({
stimulus: {
hmr: true,
},
});
TypeScript Errors
@hotwired/stimulus types conflict.vite.config.js:
declare module '@hotwired/stimulus' {
interface Stimulus {
controllers: Record<string, any>;
}
}
Asset Not Found
npm run dev is running.vite.config.js input matches Twig entry points.php bin/console cache:clear
Prod Build Fails
outDir is writable:
chmod -R 775 public/build
manifest.json exists in public/build.Twig Functions Missing
composer require pentatrion/vite-bundle --update-with-dependencies
php bin/console cache:clear --env=prod
Custom Vite Config
Override default config via config/packages/pentatrion_vite.yaml:
pentatrion_vite:
vite_options:
build:
emptyOutDir: true
Preload Assets
Use Symfony’s PreloadAssetsEventListener:
// src/EventListener/PreloadAssetsListener.php
public function onPreloadAssets(PreloadAssetsEvent $event) {
$event->addAsset('app', 'vite:///assets/app.js');
}
Legacy Asset Handling
For non-modern browsers, extend vite-plugin-symfony:
symfonyPlugin({
legacy: {
entry: './assets/legacy.js',
build: './assets/legacy-built.js',
},
});
Vite 7+ Compatibility
Use vite-bundle@^8.2.0 for Vite 7 support:
composer require pentatrion/vite-bundle:^8.2.0
HTTPS in Dev For local HTTPS (e.g., with Symfony CLI):
symfony serve --no-tls
Configure Vite to trust self-signed certs:
server: {
https: {
key: './path/to/key.pem',
cert: './path/to/cert.pem',
},
}
Monorepo Support
Use vite-plugin-symfony’s root option:
symfonyPlugin({
root: '../monorepo-packages',
});
Profiler Integration
Enable Vite’s profiler in vite.config.js:
plugins: [
symfonyPlugin({
profiler: true,
}),
];
View stats at /_profiler/vite.
How can I help you explore Laravel packages today?