Previous versions of Umbraco came with the ClientDependencyFramework that let you bundle styles and scripts across your site. In fact the back office used it heavily to minimise all the Javascript.
In v9+ this has been replaced by Smidge - which does same job for the back office , but out of the box, it isn't quite configured to do the same from your front end (website) files.
You can add scripts or stylesheets to the site 'bundles' in your razor files:
for example you can add these to any of your razor templates:
SmidgeHelper.RequiresCss("~/css/site.css");
or
SmidgeHelper.RequiresJs("~/scripts/payments.js");
and then render them in the right place in your HTML with :
@await SmidgeHelper.CssHereAsync();
and
@await SmidgeHelper.JsHereAsync();
this works great but has a few problems :
By default the script files are versioned with a version number that you have to change in the config file or your files will be cached by your site & browser
You can't (with these native methods) add extra attributes to the tags (e.g
<script src="file.js" async></script>
)
Fortunately there are some work around for this:
1. Have generated files versioned with a timestamp in dev and appdomain (so after an app restart) on production
There are a few ways to make the css/js be better for developement a) you can set debug to true in the render tags:
@await SmidgeHelper.CssHereAsync(debug: true)
b) you can change the configuration
now you can do this with a PostConfigure
method that fires whenever the configuration changes :
builder.Services.PostConfigure<SmidgeOptions>(o =>
{
o.DefaultBundleOptions.ProductionOptions
.SetCacheBusterType(typeof(TimestampCacheBuster));
});
or if you want to be a bit more fancy you can do this based on
the environment that is currently running via a configureOptions interface (where you can inject the Environment)
so in a composer you might have:
builder.Services.ConfigureOptions<SmidgeFrontEndSetup>();
And then you have a IConfigureOptions<SmidgeOptions>
interface
to set the value based on if you are running in development.
public class SmidgeFrontEndSetup : IConfigureOptions<SmidgeOptions>
{
private readonly IWebHostEnvironment _webHostEnvironment;
public SmidgeFrontEndSetup(IWebHostEnvironment webHostEnvironment)
{
_webHostEnvironment = webHostEnvironment;
}
public void Configure(SmidgeOptions options)
{
if (_webHostEnvironment.EnvironmentName.Equals("Development", StringComparison.OrdinalIgnoreCase))
{
options.DefaultBundleOptions.ProductionOptions
.SetCacheBusterType(typeof(TimestampCacheBuster));
}
else
{
options.DefaultBundleOptions.ProductionOptions
.SetCacheBusterType(typeof(AppDomainLifetimeCacheBuster));
}
}
}
2. Append extra attributes on script and style tags.
With ClientDependency in v8 you had the ability to append extra attributes to the script or link tags, when you rendered the bundle elements on your page. With the current release of smidge you can't do that with the default helper
but you can do it with a loop (and yes this could be made into a extension to help you. e.g.
replace :
@await SmidgeHelper.JsHereAsync()
with:
@{
var urls = await SmidgeHelper.GenerateJsUrlsAsync();
foreach(var url in urls)
{
<script src="@url" async></script>
}
}
I think the next step is some of this could be bundled up into helper classes to make it easier, but I think it might be good for the default settings elements to go into the Umbraco.Core and the SmidgeHelper
methods to go into Smidge then this could work for everyone 😄
Top comments (1)
Hi Kevin, thanks for this post. I'm upgrading a current Umbraco 8 site to Umbraco 9 and I'm trying to get Smidge working for the backend in the way we used ClientDependency to register our bespoke data editors in Umbraco. For example in the attached image, we registered our .js, .html and .cs files in a folder called 'Chores' in the DataEditor folder in App_Plugins in Umbraco8. Can we do something similar with Smidge for the backend in Umbraco9?