Verified on Shopware 6.7
Vite in Shopware 6
Shopware has been transitioning from Webpack to Vite for storefront builds. Vite is faster, simpler, and provides a much better developer experience - but overriding its configuration in Shopware requires understanding where the extension points are.
Here are 5 real-world override examples from production projects.
1. Custom Entry Points
By default, Shopware bundles all storefront JS into a single entry. If you need separate entry points (e.g., for a heavy feature that only loads on certain pages):
// <plugin-root>/Resources/app/storefront/build/vite.config.js
export default (config) => {
// Add a custom entry point
if (!config.build) config.build = {};
if (!config.build.rollupOptions) config.build.rollupOptions = {};
config.build.rollupOptions.input = {
...config.build.rollupOptions.input,
'product-configurator': './src/product-configurator/main.js',
};
return config;
};
Then load it conditionally in your Twig template:
{% if page.product.configuratorSettings|length > 0 %}
<script type="module" src="{{ asset('bundles/yourplugin/storefront/product-configurator.js') }}"></script>
{% endif %}
2. Path Aliases
When your plugin has deep directory structures, imports become unreadable. Add aliases:
// vite.config.js
import path from 'path';
export default (config) => {
if (!config.resolve) config.resolve = {};
if (!config.resolve.alias) config.resolve.alias = {};
config.resolve.alias['@my-plugin'] = path.resolve(__dirname, '../src');
config.resolve.alias['@my-components'] = path.resolve(__dirname, '../src/components');
return config;
};
Now you can import cleanly:
// Before
import ProductHelper from '../../../../service/product-helper';
// After
import ProductHelper from '@my-plugin/service/product-helper';
3. PostCSS Configuration
Need custom PostCSS plugins for autoprefixer config, CSS nesting, or custom media queries?
// vite.config.js
import postcssNesting from 'postcss-nesting';
import autoprefixer from 'autoprefixer';
export default (config) => {
config.css = {
...config.css,
postcss: {
plugins: [
postcssNesting(),
autoprefixer({
overrideBrowserslist: ['last 2 versions', '> 1%'],
}),
],
},
};
return config;
};
Don't forget to add the PostCSS plugins to your plugin's package.json:
{
"devDependencies": {
"postcss-nesting": "^12.0.0",
"autoprefixer": "^10.4.0"
}
}
4. Chunk Splitting for Performance
If your storefront bundle is getting large, split vendor libraries into separate chunks:
// vite.config.js
export default (config) => {
if (!config.build) config.build = {};
config.build.rollupOptions = {
...config.build.rollupOptions,
output: {
...config.build.rollupOptions?.output,
manualChunks: (id) => {
// Split large libraries into separate chunks
if (id.includes('node_modules/swiper')) {
return 'vendor-swiper';
}
if (id.includes('node_modules/flatpickr')) {
return 'vendor-flatpickr';
}
},
},
};
return config;
};
This produces separate files that can be cached independently - users who already have vendor-swiper cached don't re-download it when your main JS changes.
5. Dev Server Proxy
When developing against a remote API or microservice alongside Shopware:
// vite.config.js
export default (config) => {
config.server = {
...config.server,
proxy: {
'/api/custom-erp': {
target: 'https://erp-staging.your-company.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/custom-erp/, '/api/v2'),
secure: false,
},
'/api/product-feed': {
target: 'http://localhost:3001',
changeOrigin: true,
},
},
};
return config;
};
This lets your storefront JS call /api/custom-erp/products during development and it gets proxied to your actual ERP API - no CORS issues.
Debugging Vite Builds
When something goes wrong:
# See the full resolved Vite config
npx vite -debug
# Analyze bundle size
npx vite build -mode analyze
# Check which modules are included
npx vite build -debug=resolve
Common Gotchas
- Config merge order - Shopware applies plugin configs in plugin load order. If two plugins modify the same config key, the last one wins
- Hot reload - Vite HMR works out of the box, but custom entry points may need manual HMR setup
- Production builds - always test
bin/build-storefront.shafter config changes, dev mode can mask issues - Import paths - Vite is strict about ESM imports.
require()won't work - useimportinstead
Having trouble with your Shopware storefront build? We can help optimize it.