Skip to Main content

Integrating Frontend Output

This guide shows the backend side of the handover after a frontend package is released: which generated files matter, where to place them, and how to reference hashed CSS, JavaScript, and icons without fighting the cache.

Overview

When the Frontend team ships a new package, the Backend team usually receives a small bundle of generated files. Some of them are only useful for comparison, while others are required at runtime. Knowing which is which saves a fair amount of avoidable confusion.

The handover normally includes the following items:

  • /PreciseAlloy.Patterns - folder
    This folder contains HTML snapshots of rendered frontend pages at the time the package was created. It helps the Backend team compare markup changes and spot what needs reintegration.
    You do not need to deploy these files to run the website.

  • /PreciseAlloy.Web/wwwroot/assets - folder
    This folder contains the compiled frontend assets, including CSS, JavaScript, icons, fonts, and images required by the site.

  • /PreciseAlloy.Web/wwwroot/assets/hashes.json - file
    This file maps each generated asset to its content hash. It must be deployed with the site so the backend can generate cache-busted asset URLs correctly. If it is missing, the cache buster stops being useful and the CDN will happily serve stale files with great confidence.

The Frontend team usually prepares these files as part of the release pipeline, so the Backend team does not need to build them manually. If you do need to generate them yourself, see Frontend integration.

Integration

Copy the markup file

Start by copying the markup provided by the Frontend team into the matching backend view file.

For example, if you need to integrate the Hero block and the Frontend team points you to the static site's Home page, open the matching Patterns Home page. Find the Hero block markup there, like the simplified example below:

<section class="zzz-o-hero">
  <h1>WELCOME</h1>
  <img src="/samples/image-1.svg" alt="hero">
  <a href="https://www.office.com/">
    <span>Explore</span>
    <svg viewBox="0 0 19 19" width="19" height="19">
      <use xlink:href="/icons.svg#zzz-view"></use>
    </svg>
  </a>  
  <!-- <link rel="stylesheet" href="/assets/css/b-hero.css"> -->
  <!-- <script type="module" src="/assets/js/b-hero.js"></script> -->
</section>

Copy that markup into the backend .cshtml view for the Hero block, then replace the hard-coded values with model data.

Handling hashes.json

Assume you have a hashes.json file at /PreciseAlloy.Web/wwwroot/assets/hashes.json with content like this:

{
  "/assets/css/style-base.css": "Y3_rQ26JDf",
  "/assets/css/b-hero.css": "t8cxlFd_dF",
  "/assets/js/react-loader.0x4d7d0ab2.js": "",
  "/assets/js/main.js": "iX_2YqQ2z7",
  "/assets/js/hero.js": "A_CKPf-kTa",
  "/icons.svg": "SeT74kfn_L"
}

To make this manageable, the backend exposes HTML extension methods that generate the correct CSS and JavaScript tags and append the matching hash automatically. For the full list of available helpers, see /PreciseAlloy.Utils/Extensions/HtmlExtensions.cs.

Including CSS files

If you want to include b-hero.css into the <head> element of your page, use the following helper:

@{
  Html.RequireStyle("/assets/css/b-hero.css").AtHeader();
}

The output will be:

<link href="/assets/css/b-hero.css?v=t8cxlFd_dF" rel="stylesheet">

The ?v=t8cxlFd_dF part represents the hash of the file's content, generated at the frontend's compile time. This approach ensures proper caching. If the file remains unchanged, the hash value remains the same, allowing browsers and/or CDN to cache it for extended periods. When the file content changes, the hash value changes as well, prompting browsers to retrieve the updated file to avoid any caching issues.

You can call the above method multiple times, but the rendered HTML will contain exactly one instance of the link to that CSS file.

Including JavaScript files

To include hero.js at the footer of your page, use the following method:

@{
  // !!! Caution: see the note below
  Html.RequireScript("/assets/js/hero.js").AtFooter();
}

The output will be:

<script src="/assets/js/hero.js?v=A_CKPf-kTa" type="module"></script>

Like the CSS helper, the JavaScript helper appends the hash to the asset URL so cache busting stays consistent.

Obtaining the path directly

If you only need the asset URL and not a full HTML tag, call @Html.GetCacheBusterPath() directly. For example:

<img src="@Html.GetCacheBusterPath("/icons.svg")">

The output will be:

<img src="/icons.svg?v=SeT74kfn_L">

Sample integration

Here is a simple example of the Hero markup integrated into a backend view.

@model HeroViewModel;

@{
  // Styles
  Html.RequireStyle("/assets/css/b-hero.css").AtHeader();

  // Scripts
  Html.RequireScript("/assets/js/hero.js").AtHeader();

  // Icons
  var iconPath = Html.GetCacheBusterPath("/icons.svg");
}

<section class="zzz-o-hero">
  <h1>@Model.Heading</h1>
  <img src="@Model.ImageSrc" alt="@Model.AlternativeText">
  <a href="@Model.CtaUrl">
    <span>@Model.CtaText</span>
    <svg viewBox="0 0 19 19" width="19" height="19">
      <use xlink:href="@iconPath#zzz-view"></use>
    </svg>
  </a>
</section>

Special Case for React Components

There is one special case: react-loader.0x....js acts as the entry point for React components that use client-side rendering. You only need to include it once in the layout. In the <head>, use:

<script type="module" src="@Html.GetWidgetAssetPath("react-loader")"></script>

This helper searches for a file whose name contains /react-loader.0x and returns the matched path.

The output will be:

<script type="module" src="/assets/js/react-loader.0x4d7d0ab2.js"></script>

Conclusion

Once the generated files are in place, backend integration is mostly about discipline: copy the right markup, reference assets through the helper methods, and leave generated output alone. That keeps cache busting reliable and makes the next frontend release much less dramatic.