Introduction
Version scope
This guide targets Umbraco 8 on the classic ASP.NET MVC / .NET Framework stack. The composing APIs and asset pipeline are different in current Umbraco versions.
Website performance affects both user experience and how efficiently pages are delivered. In Umbraco 8, JavaScript and CSS resources can be optimized with the classic Microsoft.AspNet.Web.Optimization library.
This article focuses specifically on integrating that ASP.NET bundling pipeline with the Umbraco 8 application lifecycle.
Start with the ASP.NET fundamentals
If you need the underlying bundling, minification, cache-busting, and BundleTable.EnableOptimizations behavior first, read ASP.NET Bundling and Minification . This article builds on that implementation and adds the Umbraco 8 startup integration.
Setting Up Bundling and Minification in Umbraco 8
The implementation has four main steps:
Install the optimization package: add
Microsoft.AspNet.Web.Optimizationto the project.Define the bundles: create
BundleConfig.csand register the JavaScript and CSS files.Register the bundles during Umbraco startup: use the Umbraco 8 component and composer pattern.
Render the bundles: use
@Scripts.Renderand@Styles.Renderin Razor views.
Install the optimization package with NuGet if your project does not already contain it:
Install-Package Microsoft.AspNet.Web.Optimization
Bundling and minification are controlled by the classic ASP.NET optimization pipeline. If you explicitly set:
BundleTable.EnableOptimizations = true;
ASP.NET forces bundling and minification regardless of the debug setting in Web.config. The linked ASP.NET article explains that behavior in more detail.
Registering Bundles with an Umbraco Component
Umbraco 8 introduced the composing and components pattern for application startup. A component is a good place for initialization code that should run when Umbraco starts.
Create the BundleComponent
Create a component that registers the bundles during Initialize():
using System.Web.Optimization;
using Umbraco.Core.Composing;
public class BundleComponent : IComponent
{
public void Initialize()
{
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
public void Terminate()
{
}
}
Register the component with a composer
In Umbraco 8, use IUserComposer and Composition to append the component:
using Umbraco.Core.Composing;
public class BundleComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Components().Append<BundleComponent>();
}
}
Creating the BundleConfig
The BundleConfig class contains the JavaScript and CSS bundle definitions. You can place it in an App_Start folder or another suitable project folder.
using System.Web.Optimization;
public static class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
var scriptBundle = new ScriptBundle("~/bundles/master/js");
scriptBundle
.Include("~/assets/js/jquery.js")
.Include("~/assets/js/plugins.js")
.Include("~/assets/js/functions.js");
bundles.Add(scriptBundle);
var styleBundle = new StyleBundle("~/bundles/master/css");
styleBundle
.Include("~/assets/css/plugins.css")
.Include("~/assets/css/style.css")
.Include("~/assets/css/custom.css");
bundles.Add(styleBundle);
BundleTable.EnableOptimizations = true;
}
}
This example creates one JavaScript bundle and one stylesheet bundle. Keep the bundles aligned with what the relevant pages actually need rather than putting every asset into one global bundle.
About EnableOptimizations
BundleTable.EnableOptimizations = true explicitly forces optimized output. If you want development and production to follow the debug value from Web.config, omit the explicit override.
Optional Dependency Injection and Startup Logging
Umbraco 8 supports dependency injection, so you can inject its logger into the component if you want to confirm that bundle registration has executed.
using System.Web.Optimization;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
public class BundleComponent : IComponent
{
private readonly ILogger _logger;
public BundleComponent(ILogger logger)
{
_logger = logger;
}
public void Initialize()
{
BundleConfig.RegisterBundles(BundleTable.Bundles);
_logger.Info<BundleComponent>(
"Bundles registered successfully.");
}
public void Terminate()
{
}
}
The logging is optional. It can be useful while introducing the integration or troubleshooting startup, but bundle registration itself does not depend on it.
Using Bundles in Razor Views
To use the ASP.NET optimization helpers in Razor, make sure the namespace is available to the views. In a classic MVC project, you can add it to ~/Views/Web.config:
<add namespace="System.Web.Optimization" />
Then render the registered bundles in your layout:
<head>
@Styles.Render("~/bundles/master/css")
</head>
<body>
@Scripts.Render("~/bundles/master/js")
</body>
When optimization is enabled, ASP.NET generates a combined bundle URL. When optimization is disabled, the helpers render the source files separately. The exact caching behavior and optional LastModifiedBundleTransform technique are covered in the ASP.NET Bundling and Minification guide .
Key Benefits of Bundling and Minification in Umbraco 8
Fewer asset requests: optimized bundles can combine multiple JavaScript or CSS resources into a smaller number of requests.
Smaller transferred files: minification removes unnecessary characters from scripts and styles.
Centralized configuration: bundle definitions remain in one place instead of being repeated across layouts and views.
Clear Umbraco startup integration: the component/composer pattern keeps initialization inside the Umbraco 8 lifecycle.
Conclusion
Adding ASP.NET bundling and minification to Umbraco 8 requires only a small amount of Umbraco-specific integration. Define the bundles in BundleConfig, register them from an IComponent, append that component through an IUserComposer, and render the bundles from Razor.