# Bundle and Minify CSS/JS using ClientDependency in Umbraco 6 MVC/Razor
**by:** Saurabh Nandu     **in:**  [Programming](https://www.systenics.com/blogs/category/programming)     **tags:**  [*ASP.NET MVC*](https://www.systenics.com/blogs/tag/aspnet-mvc) ,  [*Razor*](https://www.systenics.com/blogs/tag/razor) ,  [*Umbraco*](https://www.systenics.com/blogs/tag/umbraco)

This is going to be a short post on how to configure style sheets and
JavaScript's bundling and minification in Umbraco 6 using **ClientDependency** framework in MVC. The benefits of bundling and minification are obvious as they
reduce the number of HTTP requests as well as decrease the download size of resources
to the browser resulting in a faster browsing experience. While Microsoft has
prebuilt its own libraries to enable these features, Umbraco uses the **ClientDependency** framework to achieve the same. You can read more about the client dependency
framework from its [codeplex website](http://clientdependency.codeplex.com/), its got quite a few configurations options and you and read more about
them on its website. In this post I am just going to focus on getting an
initial configuration up and running since there seems to be lack of clear
documentation on the topic and it took me a while too to figure how to set
it up correctly.

This article assumes that you already have a installation of Umbraco 6 and
have configured its rendering engine to use ASP.NET MVC for the pages.

## Getting Started

The first essential step for **ClientDependency** to work is to ensure
that **debug** mode is turned off in the**
web.config** file. It's a neat idea, when you are in debug mode, bundling and minification
is not applied so you can easily debug your files and continue fixing your css/js.
Only when you are ready with the final output and ready for deployment which is
indicated by setting **debug** mode as false, it acts as a trigger
to turn on **ClientDependency** framework to come into play. So if
you are not able to see the effects of bundling and minification the first checkpoint
would be to ensure that you have set the **debug** mode to false
in the **web.config** file.

```
<system.web>
<compilation defaultLanguage="c#" debug="false"
batch="false" targetFramework="4.0">
.....
...
</system.web>
```

Listing 1: Debug mode set as false

The listing above shows a part of the **web.config** file explicitly
setting the **debug** mode as false. The next step is to configure
the **ClientDependency** framework configuration. Umbraco has a special
config file in the **config** folder called **ClientDependency.config** which contains the configuration for the ClientDependency framework. In my test,
the standard config file shipped with Umbraco 6.0 did not work correctly for MVC.
Using it always lead to errors and at times the assembly ClientDependency.Core.MVC
was reported missing by the ASP.NET runtime.

The solution that I found, was to replace contents of the **ClientDependency.config** file with the sample configuration provided in the [sample documentation](http://clientdependency.codeplex.com/wikipage?title=Configuration&referringTitle=Documentation) on codeplex. Listing 2 shows the replaced contents of the config file.

```
<?xml version="1.0" encoding="utf-8"?>
<!--
Customize the configuration section as required, it is optional,
when it is not specified the defaults will be loaded. YOU DONT NEED
TO SPECIFY ALL OF THIS CONFIG, THE MINIMUM IS JUST THIS:
<clientDependency version="1" />

Each section is optional, so if you're not using Mvc, you don't need
that section and if you're not using Web Forms, you don't need the
fileRegistration section.
Composite files are used for both types of projects.

** IMPORTANT: If you're web.config setting: compilation debug="true" is set to 'true', then composite files will NOT be enabled no matter what
-->
<clientDependency version="76" fileDependencyExtensions=".js,.css">
<!--
This section is used for Web Forms only, the enableCompositeFiles="true" is optional and by default is set to true.
The PlaceHolderProvider is set to default, the javascriptPlaceHolderId, cssPlaceHolderId attributes are optional and default to what is listed below. If using
this provider, then you must specify both PlaceHolder controls on your page in order to render the JS/CSS.
-->
<fileRegistration defaultProvider="PlaceHolderProvider">
<providers>
<add name="PageHeaderProvider" type="ClientDependency.Core.FileRegistration.Providers.PageHeaderProvider, ClientDependency.Core" enableCompositeFiles="true"/>
<add name="LazyLoadProvider" type="ClientDependency.Core.FileRegistration.Providers.LazyLoadProvider, ClientDependency.Core" enableCompositeFiles="true"/>
<add name="LoaderControlProvider" type="ClientDependency.Core.FileRegistration.Providers.LoaderControlProvider, ClientDependency.Core" enableCompositeFiles="true"/>
<add name="PlaceHolderProvider" type="ClientDependency.Core.FileRegistration.Providers.PlaceHolderProvider, ClientDependency.Core" enableCompositeFiles="true" javascriptPlaceHolderId="JavaScriptPlaceHolder" cssPlaceHolderId="CssPlaceHolder"/>
</providers>
</fileRegistration>
<!-- This section is used for MVC only -->
<mvc defaultRenderer="StandardRenderer">
<renderers>
<add name="StandardRenderer" type="ClientDependency.Core.FileRegistration.Providers.StandardRenderer, ClientDependency.Core" enableCompositeFiles="true" />
<add name="LazyLoadRenderer" type="ClientDependency.Core.FileRegistration.Providers.LazyLoadRenderer, ClientDependency.Core" enableCompositeFiles="true"/>
</renderers>
</mvc>
<!--
The composite file section configures the compression/combination/minification of files.
You can enable/disable minification of either JS/CSS files and you can enable/disable the
persistence of composite files. By default, minification and persistence is enabled. Persisting files
means that the system is going to save the output of the compressed/combined/minified files
to disk so that on any subsequent request (when output cache expires) that these files don't have
to be recreated again and will be based on the persisted file on disk. This saves on processing time.
-->
<compositeFiles defaultFileProcessingProvider="CompositeFileProcessor" compositeFileHandlerPath="~/DependencyHandler.axd">
<!--
File processing providers perform the file combination, compression and storage.
Generally there would be no reason to replace.
NOTE: The pathUrlFormat is much nicer as dependencyId.version.type which is the default,
however, it is specified below with '/' as the delimiter to demonstrate using it with Cassini
since Cassini does not support '.' chars in the path.
-->
<fileProcessingProviders>
<add name="CompositeFileProcessor"
type="ClientDependency.Core.CompositeFiles.Providers.CompositeFileProcessingProvider, ClientDependency.Core"
enableCssMinify="true"
enableJsMinify="true"
persistFiles="true"
compositeFilePath="~/App_Data/ClientDependency"
bundleDomains="localhost:46329"
urlType="MappedId"
pathUrlFormat="dependencyId/version/type"/>
</fileProcessingProviders>
<!--
A file map provider stores references to dependency files by an id to be used in the handler URL when using the MappedId Url type
-->
<fileMapProviders>
<add name="XmlFileMap"
type="ClientDependency.Core.CompositeFiles.Providers.XmlFileMapper, ClientDependency.Core"
mapPath="~/App_Data/ClientDependency"/>
</fileMapProviders>
<!--
Defines the mime types to compress when requested by the client.
Path is a regex selector, or a * can be used as in place of 'any'.
Generally mime types are only set by client browsers in the request for things
such as JSON or XML ajax requests.
-->
<mimeTypeCompression>
<add type="application/json" path="^.*?/Services/.*"/>
</mimeTypeCompression>
<!--
Defines the paths to match on to enable rogue file compression.
Path is a regex selector, or a * can be used as in place of 'any'.
jsExt and cssExt are comma seperated list of extensions to match to have the dependencies
replaced with the composite file handler. You can even include ASP.Net web service JS proxies.
-->
<rogueFileCompression>
<add path="*" compressJs="true" compressCss="true" jsExt=".js,asmx/js" cssExt=".css">
<!--<exclusions>
<add path="^.*test.aspx.*"/>
</exclusions>-->
</add>
</rogueFileCompression>
</compositeFiles>
</clientDependency>
```

Listing 2: Updated ClientDependency.config file

The config file above has configurations for both WebForms and MVC pages,
you can read the documentation on codeplex to fine tune the configuration to
meet the requirements of your project. One very powerful feature configured
by the above config is **persistence**. Enabling persistence
makes the framework save the bundled and mninified css/js to a temporary
file on first run. All later requests are directly served from the static
file, this ensures that CPU cycles on the server are saved at the same time
response to the client becomes faster. This step can make a big impact on
sites with a very high number of visitors. Another point to note is that if
you look at line 14 the **clientDependency** tag has a **version** property, it is important to change the version number every time you update
the css/js file. The persistence module does not detect changes to CSS/JS on the
fly, so if you continue making changes in the css/js files they will not reflect!
Ensure that after every change you manually update the version on the config file.
The best way to tackle this issue is to ensure that you enable **ClientDependency** only after your JavaScript's and style sheets have stabilized or not use persistence
till there is stabilization.

With the configurations setup we are ready to use this framework in our View
Templates. Another hiccup is trying to make sense of how to use its HTML
helpers in MVC. The [documentation provided at codeplex](http://clientdependency.codeplex.com/wikipage?title=MVCFileRegistration&referringTitle=Documentation) for MVC is inadequate and keeps giving errors when used with Umbraco. Searching
through several forum posts there is a solution provided in one of them, but I
am not sure why that clarity has not made it back into the original documentation.

The **ClientDependency** framework for MVC works in two parts, in
first part you need to use HTML helper methods like **Html.RequireCss** and **Html.RequireJs** to define all the CSS/JS files that are
needed on your page. The documentation linked above has various overloads for
these helper methods. The second part is to use the **Html.RenderCssHere** and **Html.RenderJsHere** methods within your HTML markup to generate
the appropriate link and script tags. Listing 3 shows a sample Umbraco MVC template

```
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@using ClientDependency.Core.Mvc;
@{
Layout = "SystenicsBaseBase.cshtml";
@Html.RequiresCss("~/css/Site.css");
@Html.RequiresJs("~/scripts/jquery-1.9.1.min.js",1);
@Html.RequiresJs("~/scripts/commonscript.js",2);
}
<!DOCTYPE html>
<html>
<head>
<title>@Umbraco.Field("sEOTitle")</title>
<meta name="description" content='@Umbraco.Field("sEODescription")'/>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,
initial-scale=1, maximum-scale=1" />

@Html.Raw(@Html.RenderCssHere())
@Html.Raw(@Html.RenderJsHere())
</head>
<body>
.....
</body>
</html>
```

Listing 3 – Sample Umbraco Template using Html Helpers

Its important to note from code listing 3 that you need to first import the **ClientDependency.Core.Mvc** assembly to use its helpers. The second critical step is to ensure you use the
**Html.RequireCss** and **Html.RequireJs** helpers within
the initial razor block. I tried defining them elsewhere on the page and it always
returns invalid markup. This is a common mistake not documented on the framework
site, but it leads to everyone wasting time trying to figure it out. As you can
see from the listing above I have included one style sheet and two JavaScript
files to be bundled and minified. Lastly, within the HTML head tag the style sheet
and JavaScript is rendered. You could alternatively load the JavaScript anywhere
within your Body tag for lazy loading of JavaScript.

That's it! Save the template and fire up the Umbraco site in your browser,
you will notice that it takes very long to render the first page, but later
those pages are served very fast. You can also use the Chrome in-built tools
to verify that the css/js files are indeed being bundled and compressed.

I hope this short post will help you setup ClientDependency in your Umbraco
setup, making your client websites super fast!

## Related pages on Systenics

-  [AuctionWorx products](https://www.systenics.com/products/)

## Need help implementing this for your business?

Our team helps plan, build, and scale marketplace and auction workflows.
Explore
[industry solutions](https://www.systenics.com/solutions/),
[platform products](https://www.systenics.com/products/), and
[custom development services](https://www.systenics.com/auctionworx/development-and-customization/)
tailored to your goals.

[Book a quick consultation](https://outlook.office365.com/owa/calendar/sales1@systenics.net/bookings/).