How to inline CSS and JavaScript bundles in MVC

Posted written by Paul Seal on March 08, 2017 .NET Framework

Inline styles and scripts

There may be times where you need to render the styles or scripts directly on the page rather than referencing them in separate files.

This post shows you how you can combine bundling and minification with inline styles and scripts in MVC.

Show me the code

using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Text;

namespace CodeShare.Web.Helpers
{
    public static class HtmlBundleExtensions
    {

        /// <summary>
        /// Returns the content of a style bundle in one style block
        /// </summary>
        /// <param name="htmlHelper">Extension for HtmlHelper</param>
        /// <param name="paths">String array of bundle paths</param>
        /// <returns>HtmlString with all css bundle contents in one style block</returns>
        public static IHtmlString InlineStyles(this HtmlHelper htmlHelper, params string[] bundlePaths)
        {
            StringBuilder bundleContent = new StringBuilder();
            foreach (string path in bundlePaths)
            {
                bundleContent.Append(GetBundleContent(htmlHelper.ViewContext.HttpContext, path));
            }
            return new HtmlString(string.Format("<style>{0}</style>", bundleContent.ToString()));
        }

        /// <summary>
        /// Returns the contents of script bundles as individual script blocks
        /// </summary>
        /// <param name="htmlHelper">Extension for HtmlHelper</param>
        /// <param name="paths">String array of bundle paths</param>
        /// <returns>HtmlString with a script block for each script bundle path passed in.</returns>
        public static IHtmlString InlineScripts(this HtmlHelper htmlHelper, params string[] bundlePaths)
        {
            StringBuilder bundleContent = new StringBuilder();
            foreach (string path in bundlePaths)
            {
                bundleContent.Append(string.Format("<script>{0}</script>", GetBundleContent(htmlHelper.ViewContext.HttpContext, path)));
            }
            return new HtmlString(bundleContent.ToString());
        }

        /// <summary>
        /// Gets the content of a bundle
        /// </summary>
        /// <param name="httpContext">The HttpContext</param>
        /// <param name="bundleVirtualPath">Path of the bundle</param>
        /// <returns>String containing the contents of the bundle</returns>
        private static string GetBundleContent(HttpContextBase httpContext, string bundleVirtualPath)
        {
            return BundleTable.Bundles
                .Single(b => b.Path == bundleVirtualPath)
                .GenerateBundleResponse(new BundleContext(httpContext, BundleTable.Bundles, bundleVirtualPath))
                .Content;
        }
    }
}

Using the code

Styles

@Html.InlineStyles("~/bundles/style","~/bundles/font-awesome-css")

Scripts

@Html.InlineScripts("~/bundles/sitescripts","~/bundles/forms","~/bundles/common")

What it looks like in the page

Styles

<style>/*! normalize.css v2.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid #c0c0c0}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{padding:0;box-sizing:border-box}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}</style>

Scripts

<script>blahblahblah1;if(function(n,t){function gt(n){var t=n.length,r=i.type(n);return i.isWindow(n)?!1:1===n.nodeType&amp;&amp;t?!0:"array"===r||"function"!==r&amp;&amp;(0===t||"number"==typeof t&amp;&amp;t>0&amp;&amp;t-1 in n)}function te(n){var t=ni[n]={};return i.each(n.match(s)||[],function(n,i){t[i]=!0}),t}function ur(n,r,u,f){if(i.acceptData(n)){var h,o,c=i.expando,l=n.nodeType,s=l?i.cache:n,e=l?n[c]:n[c]&amp;&amp;c;if(e&amp;&amp;s[e]&amp;&amp;(f||s[e].data)||u!==t||"string"!=typeof r)return e||(e=l?n[c]=b.pop()||i.guid++:c),s[e]||(s[e]=l?{}:{toJSON:i.noop}),("object"==typeof r||"function"==typeof r)&amp;&amp;(f?s[e]=i.extend(s[e],r):s[e].data=i.extend(s[e].data,r)),o=s[e],f||(o.data||(o.data={}),o=o.data),u!==t&amp;&amp;(o[i.camelCase(r)]=u),"string"==typeof r?(h=o[r],null==h&amp;&amp;(h=o[i.camelCase(r)])):h=o,h}}</script>
<script>blahblahblah2if(function(n,t){function gt(n){var t=n.length,r=i.type(n);return i.isWindow(n)?!1:1===n.nodeType&amp;&amp;t?!0:"array"===r||"function"!==r&amp;&amp;(0===t||"number"==typeof t&amp;&amp;t>0&amp;&amp;t-1 in n)}function te(n){var t=ni[n]={};return i.each(n.match(s)||[],function(n,i){t[i]=!0}),t}function ur(n,r,u,f){if(i.acceptData(n)){var h,o,c=i.expando,l=n.nodeType,s=l?i.cache:n,e=l?n[c]:n[c]&amp;&amp;c;if(e&amp;&amp;s[e]&amp;&amp;(f||s[e].data)||u!==t||"string"!=typeof r)return e||(e=l?n[c]=b.pop()||i.guid++:c),s[e]||(s[e]=l?{}:{toJSON:i.noop}),("object"==typeof r||"function"==typeof r)&amp;&amp;(f?s[e]=i.extend(s[e],r):s[e].data=i.extend(s[e].data,r)),o=s[e],f||(o.data||(o.data={}),o=o.data),u!==t&amp;&amp;(o[i.camelCase(r)]=u),"string"==typeof r?(h=o[r],null==h&amp;&amp;(h=o[i.camelCase(r)])):h=o,h}}</script>
<script>blahblahblah3;if(function(n,t){function gt(n){var t=n.length,r=i.type(n);return i.isWindow(n)?!1:1===n.nodeType&amp;&amp;t?!0:"array"===r||"function"!==r&amp;&amp;(0===t||"number"==typeof t&amp;&amp;t>0&amp;&amp;t-1 in n)}function te(n){var t=ni[n]={};return i.each(n.match(s)||[],function(n,i){t[i]=!0}),t}function ur(n,r,u,f){if(i.acceptData(n)){var h,o,c=i.expando,l=n.nodeType,s=l?i.cache:n,e=l?n[c]:n[c]&amp;&amp;c;if(e&amp;&amp;s[e]&amp;&amp;(f||s[e].data)||u!==t||"string"!=typeof r)return e||(e=l?n[c]=b.pop()||i.guid++:c),s[e]||(s[e]=l?{}:{toJSON:i.noop}),("object"==typeof r||"function"==typeof r)&amp;&amp;(f?s[e]=i.extend(s[e],r):s[e].data=i.extend(s[e].data,r)),o=s[e],f||(o.data||(o.data={}),o=o.data),u!==t&amp;&amp;(o[i.camelCase(r)]=u),"string"==typeof r?(h=o[r],null==h&amp;&amp;(h=o[i.camelCase(r)])):h=o,h}}</script>

That's it

If you need help with setting up bundling and minification, see my other post.

Thanks to Marius for inspiration for this code by reading his post here.