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:
<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:
<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.
| Parameter | Default | Description |
|---|---|---|
AutoReload | false | Reload automatically when an update finishes instead of showing the reload button. Changed in v-10-6-0 - previously defaulted to true. |
ShowLogs | false | Log lifecycle messages to the console. |
ShowAssets | false | List each downloaded asset inside the splash. |
AppContainer | #app | Selector of the element to hide while installing (used with HideApp). An invalid selector is tolerated - only the hiding is skipped. |
HideApp | false | Hide the app container while the first install downloads. |
AutoHide | false | Hide 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 id | Driven as |
|---|---|
bit-bswup-progress-bar | Width + aria-valuenow set to the download percentage; the splash root also gets --bit-bswup-percent / --bit-bswup-percent-text CSS variables. |
bit-bswup-percent | Text content set to NN%. |
bit-bswup-assets | Each 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-status | The update-ready button and its screen-reader status region. |
#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:
<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>#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.
<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>