bit Bswup

Preparing the app for offline use, please wait...

0%

bit platform logo Bswup
NuGet GitHub

The Built-in Progress UI

Instead of writing a handler yourself, use the built-in splash/progress UI: the BswupProgress Razor component (the markup) plus bit-bswup.progress.js (the behavior). It registered the splash you saw when this site first installed.

Reference both in your host document:

html
<link rel="stylesheet" href="_content/Bit.Bswup/bit-bswup.progress.css" />
...
<script src="_content/Bit.Bswup/bit-bswup.js" ...></script>
<script src="_content/Bit.Bswup/bit-bswup.progress.js"></script>

Then render the component:

razor
<BswupProgress AutoReload="false" ShowAssets="true" HideApp="true" AutoHide="true" />

Component parameters

Each parameter maps to a data-bit-bswup-* attribute that the script reads at load time. The component emits no inline <script>, so it works under a strict Content-Security-Policy and when rendered by an interactive Blazor renderer.

ParameterDefaultDescription
AutoReloadfalseReload automatically when an update finishes instead of showing the reload button. Changed in v-10-6-0 - previously defaulted to true.
ShowLogsfalseLog lifecycle messages to the console.
ShowAssetsfalseList each downloaded asset inside the splash.
AppContainer#appSelector of the element to hide while installing (used with HideApp). An invalid selector is tolerated - only the hiding is skipped.
HideAppfalseHide the app container while the first install downloads.
AutoHidefalseHide the splash automatically when the download finishes.
Handler-Name of an additional custom handler invoked after the built-in handling, so you can layer your own behavior without replacing the UI. (Do not point it at bitBswupHandler itself - self-references are detected and ignored.)
ChildContent-Replaces the default splash markup with your own - see below.

Behavior worth knowing

  • The full-screen splash is first-install only. A background update downloads silently behind the running app; when it finishes - or when an update is already staged at page load - the reload button appears on its own, with a screen-reader announcement through a role="status" region.
  • Clicks outside the splash content pass through the overlay, so an app force-started under a failure panel stays usable.
  • A failure panel with retry appears for fatal first-install errors; deterministic failures (an unparseable manifest, an integrity mismatch) hide the retry button since reloading would fail identically.
  • Runtime toggles are available via BitBswupProgress.config({ autoReload, showLogs, showAssets, hideApp, autoHide }).

Custom splash content

Pass ChildContent to replace the default splash markup. The component keeps initializing automatically, and the built-in behavior drives your markup through the documented element ids - include whichever you want driven:

Element idDriven as
bit-bswup-progress-barWidth + aria-valuenow set to the download percentage; the splash root also gets --bit-bswup-percent / --bit-bswup-percent-text CSS variables.
bit-bswup-percentText content set to NN%.
bit-bswup-assetsEach downloaded asset prepended as a list item.
bit-bswup-error (+ -message, -details, -retry)The failure panel for fatal first-install errors.
bit-bswup-reload / bit-bswup-reload-statusThe update-ready button and its screen-reader status region.
Don't render your own reload button
The update-ready button (#bit-bswup-reload) and its status region are always rendered by the component itself, outside the overlay, even with custom content - they are the only way a finished update surfaces under the default AutoReload="false". A custom splash should not render its own copy of those two; restyle them by id instead.

Standalone WebAssembly apps

In a standalone Blazor WebAssembly app the splash must exist before Blazor starts - on a first install, Blazor only boots after the download completes - so the BswupProgress component (which renders as part of the app) cannot paint the first-install splash. Hand-write the same markup in index.html instead; bit-bswup.progress.js self-initializes from the data-bit-bswup-* attributes exactly as it does for the component:

html
<div id="bit-bswup"
     data-bit-bswup-config="true"
     data-bit-bswup-auto-reload="false"
     data-bit-bswup-hide-app="true"
     data-bit-bswup-auto-hide="true"
     data-bit-bswup-handler="myExtraHandler">
    <div class="bit-bswup-container">
        <p class="bit-bswup-title">Installing the app</p>
        <div class="bit-bswup-progress">
            <div id="bit-bswup-progress-bar" role="progressbar" aria-label="Update download progress"
                 aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" style="width: 0%"></div>
        </div>
        <p id="bit-bswup-percent">0%</p>
        <div id="bit-bswup-error" class="bit-bswup-error" style="display: none;" role="alert">
            <p class="bit-bswup-error-title">Update failed to install</p>
            <p id="bit-bswup-error-message" class="bit-bswup-error-message"></p>
            <pre id="bit-bswup-error-details" class="bit-bswup-error-details"></pre>
            <button id="bit-bswup-error-retry" type="button">Retry</button>
        </div>
    </div>
</div>
<!-- OUTSIDE the overlay: -->
<button id="bit-bswup-reload" type="button" style="display: none;">Update ready - reload</button>
<span id="bit-bswup-reload-status" role="status" class="bit-bswup-visually-hidden"></span>
Two placement rules
Keep #bit-bswup-reload and its status region outside the #bit-bswup overlay (a finished background update must surface the button without revealing the splash), and give the button its own z-index if your app has fixed chrome in the top-right corner.

Prerendered Blazor Web Apps (like this site)

A Blazor Web App renders its host document (Components/App.razor) on the server, so the hand-written workaround above is unnecessary: drop <BswupProgress /> straight into App.razor, outside the interactive render-mode boundary. It is statically rendered, which puts its markup - and the data-bit-bswup-* configuration bit-bswup.progress.js reads - in the very first HTML the browser receives, before any script runs. This is what this site does; view source on any page for a complete working example.

html
<body>
    <!-- Statically rendered: present before blazor.web.js (and the app) start. -->
    <BswupProgress AutoReload="false" HideApp="true" AutoHide="true" AppContainer="#app" />

    <div id="app">
        <Routes @rendermode="renderMode" />
    </div>

    <script src="_framework/blazor.web.js" autostart="false"></script>
    <script src="_content/Bit.Bswup/bit-bswup.js" scope="/" sw="service-worker.js"></script>
    <script src="_content/Bit.Bswup/bit-bswup.progress.js"></script>
</body>