BJ Patel is an expert user of Umbraco. Always keen to share hints and tips on getting the best out of Umbraco.
Step-by-Step Guide: Bundling & Minification in Umbraco 17 with Vite
In Umbraco 17, the traditional runtime minification tool Smidge is no longer included by default. Developers are encouraged to bundle and optimize static assets using modern tools like Vite.
Why Use Vite?
- Fast build tool
- Automatic bundling
- Minification
- Hot reload during development
- Optimized production build
Project Structure
Client
│
├── src
│ ├── frontend
│ │ ├── js
│ │ │ ├── home.js
│ │ │ ├── about.js
│ │ │ └── common.js
│ │ │
│ │ └── css
│ │ ├── home.css
│ │ └── about.css
│ │
│ └── backoffice
│ └── admin-tools
│ └── main.ts
│
├── vite.frontend.config.ts
├── vite.backoffice.config.ts
└── package.json
UmbracoProject
│
├── wwwroot
│ └── dist
│ ├── js
│ └── css
│
└── App_Plugins
└── admin-tools
└── dist
Frontend Vite Configuration
import { defineConfig } from "vite";
import path from "path";
export default defineConfig({
build:{
outDir: path.resolve(__dirname,"../../wwwroot/dist"),
emptyOutDir:true,
rollupOptions:{
input:{
home:path.resolve(__dirname,"../src/frontend/js/home.js"),
about:path.resolve(__dirname,"../src/frontend/js/about.js")
},
output:{
entryFileNames:"js/[name].min.js",
assetFileNames:"css/[name].min.css"
}
}
}
});
Backoffice Vite Configuration
import { defineConfig } from "vite";
import path from "path";
export default defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, "../src/backoffice/admin-tools/main.ts"),
formats: ["es"],
fileName: () => "index.js",
},
outDir: "../App_Plugins/admin-tools/dist",
emptyOutDir: true,
rollupOptions: {
external: [
/^@umbraco-cms\/backoffice\/.*/
],
output: {
inlineDynamicImports: true,
},
},
},
});
Common JavaScript File
// common.js
export function showMessage(message){
console.log(message);
}
export function initMenu(){
console.log("Menu initialized");
}
Home Page Script
// home.js
import "../css/home.css";
import { showMessage } from "./common";
document.addEventListener("DOMContentLoaded", function(){
showMessage("Home page loaded");
const btn = document.getElementById("homeBtn");
if(btn){
btn.addEventListener("click",()=>{
alert("Welcome to Home Page");
});
}
});
About Page Script
// about.js
import "../css/about.css";
import { showMessage } from "./common";
document.addEventListener("DOMContentLoaded", function(){
showMessage("About page loaded");
});
Home Page CSS
.hero{
background:#2b4c7e;
color:white;
padding:40px;
text-align:center;
}
.hero button{
padding:10px 20px;
border:none;
background:#ff6b00;
color:white;
}
About Page CSS
.about-section{
padding:40px;
background:#f8f8f8;
}
.about-section h2{
color:#2b4c7e;
}
package.json Build Scripts
{
"scripts": {
"build:frontend":
"vite build --config vite/vite.frontend.config.ts",
"build:backoffice":
"vite build --config vite/vite.backoffice.config.ts",
"build":
"npm run build:frontend && npm run build:backoffice"
}
}
Build Commands
The project uses separate builds for frontend assets and backoffice extensions.
- build:frontend → bundles website JS & CSS
- build:backoffice → compiles Umbraco backoffice extension
- build → runs both builds together
npm run build
Use Bundled Files in Razor
<link rel="stylesheet" href="/dist/css/home.min.css"> <script src="/dist/js/home.min.js"></script>
Build Output
wwwroot/dist js/home.min.js js/about.min.js css/home.min.css css/about.min.css App_Plugins/admin-tools/dist index.js
Conclusion
Using Vite with Umbraco 17 provides a modern development workflow for both frontend assets and backoffice extensions. It enables fast builds, automatic bundling, and optimized production assets.
Join Our Community
Your contributions help us continue creating valuable content. Consider supporting us by sharing our content.
Junagadh, Gujarat
Latest Blog Posts