MVC Bundling in Umbraco 1

MVC allows websites to combine assets such as style-sheets and script files into bundles in order to reduce HTTP requests to your server. Bundles can also be setup to automatically minify your CSS and JavaScript to further optimize your website and make development easier.

If you are building a vanilla MVC application bundling is usually already setup for you using the project templates, but if you are using Umbraco 6 or 7 with MVC then there are a few things you need to do to get this working. This guide assumes you have setup a Visual Studio project for your Umbraco install using nuget and an empty MVC 4 project.

First you will need to include the System.Web.Optimization library. This can be done using the nuget console command.

PM> Install-Package Microsoft.AspNet.Web.Optimization

Next create a BundleConfig class, this is used to determine the files that are included in the bundles and the path the eventual bundle will be available on. Ordinarily this class file lives in the App_Start folder so it makes sense to create it there. The class does not need to extend or implement any interface it just needs to reference the Web.Optimization library and include a static method to register the bundle with MVC.

public class BundleConfig
    public static void RegisterBundles(BundleCollection bundles)
        Bundle scripts = new Bundle("~/bundles/js");
        scripts.Transforms.Add(new JsMinify());

        Bundle styles = new Bundle("~/bundles/css");
        styles.Transforms.Add(new CssMinify());

The above code adds the jquery.js and app.js to a scripts bundle and the style.css and font.css to a styles bundle, it also adds minification transforms to the bundles so that the files will be automatically minified when they are bundled together.

Because the site is running in the context of Umbraco we need to reserve the path we want the bundles available on otherwise you will get a 404 when trying to reference them. This is added in the web.config and should match the path you set in your BundleConfig class.

<add key="umbracoReservedPaths" value="~/umbraco,~/install/,~/bundles" />

The application needs to register the bundle configuration, normally this is achieved using the application start method in the Global.asax.cs. In Umbraco you need to override the application started event handler in a class that inherits from Umbraco.Core.ApplicationEventHandler (Assuming Umbraco 7.x)

Here’s an example of what that looks like, you will need to reference the relevant Umbraco and Web.Optimization libraries.

public class ApplicationEvents : ApplicationEventHandler
    protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)

Finally you need to actually use the bundles in a template. Instead of directly referencing the style-sheet or script files you instead use the helpers to output the bundle links. Be sure to include the web optimization library.

@using System.Web.Optimization

If you start debugging the site now and look at the resulting page source you will see that the files you added to the bundles have been output individually and unminified rather than in bundles.

<link href="/css/font.css" rel="stylesheet"/>
<link href="/css/style.css" rel="stylesheet"/>

<script src="/scripts/jquery.js"></script>
<script src="/scripts/app.js"></script>

This is because the bundling will only be active when the debug flag is set to false in the web.config, in this case the individual files will be referenced as normal. This is actually useful if you need to debug any of the scripts or style-sheets.

You can force bundling by setting it to always active in the BundleConfig class by setting enable optimizations to true.

BundleTable.EnableOptimizations = true;

If you debug the site now and look at the resulting source on the page you will see the minified bundles being output.

<link href="/bundles/css?v=Dn8140cLCV8xEOGELRbm2ZN1S5Zoj8iSfG8yo5Ht7CE1" rel="stylesheet"/>

<script src="/bundles/js?v=yJ64W3mzP3IKe5Q4DbSlPT-SaA2nog_3XGkxlN4kCN41"></script>