7

First project using Helix coming up. In our previous project we've used HTTP/2 on the CDN, so we have adopted a lot of new best practices.

One of the most important new best practices in HTTP/2 is that number of requests is no longer an issue. Instead of bundling all components styles and scripts into one big styles.css and scripts.js we only include the styles and scripts that are needed to support the components that are present on the current page. This results in lighter page weight (which is good) and more requests (which is no longer an issue).

In the last project we have used what Kern Herskind called "inside out rendering" (http://herskind.co.uk/blog/sitecore/2014/11/off-piste-with-sitecore-mvc/) to place the components scripts and styles inside <head> or before </body>.

With that approach, a sample component looks something like this:

<!-- language: html -->
@model Sitecore.Mvc.Presentation.RenderingModel

@{
    Section.AddHead("<link rel='stylesheet' href='" + @GulpAsset.GetSrc("components/headerComponent.css") + "' />");
    Section.AddBeforeBodyEnds("<script src='" + @GulpAsset.GetSrc("components/headerComponent.js") + "' ></script>");
}

<header class="headerComponent">
   [a lot of HTML]
</header>

A page where several components are included would render like this. The thing to note here is that stylesheets renders inside the <head>-element and scripts are rendered just before </body>. Just like it should.

<!-- language: html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>About us</title>
    <link rel="stylesheet" href="//cdn.customer.com/ui/css/headerComponent-[hash].css" />
    <link rel="stylesheet" href="//cdn.customer.com/ui/css/mainNavigationComponent-[hash].css" />
    <link rel="stylesheet" href="//cdn.customer.com/ui/css/editorialComponent-[hash].css" />
    <link rel="stylesheet" href="//cdn.customer.com/ui/css/footerComponent-[hash].css" />
</head>
<body>

    <header class="headerCoponent">
        This is the header component
    </header>

    <nav class="mainNavigationComponent">
        <ul>
            <li><a href="/home">Home</a></li>
            <li><a href="/about">About</a></li>
        </ul>
    </nav>

    <div class="editorialComponent">
        <h1>This is an amazing page</h1>
        <p>Bacon ipsum dolor amet beef ribs tenderloin chuck short ribs sirloin, picanha porchetta ham.</p>
    </div>

    <footer class="footerComponent">
        Some footer content
    </footer>

    <script src="//cdn.customer.com/ui/js/headerComponent-[hash].js"></script>
    <script src="//cdn.customer.com/ui/js/mainNavigationComponent-[hash].js"></script>
    <script src="//cdn.customer.com/ui/js/editorialComponent-[hash].js"></script>
    <script src="//cdn.customer.com/ui/js/footerComponent-[hash].js"></script>
</body>
</html>

The benefits from doing like this is that a cshtml view, its styles and scripts are very closely tied together, both via file names/namespace and sitecore wise.

If you include the component on a page you can be confident that the styles and scripts will follow. One huge disadvantage is that this approach does not work with Sitecore HTML cache. The second time a user requests this page with Sitecore HTML cache enabled the scripts and styles won't render. So that "kinda sucks".

This boils down to: Is there a better way to solve this using Helix principles? How do I link in the components JS and CSS inside the .cshtml and at the same time being able to use the Sitecore HTML cache?

1

I found some time ago a solution for this (In my case it was webforms). Instead of adding the references to css and js in the "view" the trick was to put this on a pipeline which is always executed.

The solution involves creating new "decoration attributes" where you can set the css and js required. Add those attribute in your "views" and then hook into the pipeline and add the references at this point. This link seems to do this with MVC

  • That's an interesting approach! I will look into it. There was also some discussions on Slack about an "Asset requirement service" included in Habitat. So, before picking this as the accepted answer I'd love to hear from someone who knows how it works. – chilly Dec 2 '16 at 11:55
  • Will that work for view renderings as well? – Peter R Dec 2 '16 at 12:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.