loading
Warning:
This is not a place to keep your app's data Shared storage is unpartitioned - the same data is there whichever site embeds you - which would be a cross-site identifier if the page could read it back. So it can't. For your own app's data use LocalStorage, IndexedDb or StorageManager.
Note:
The worklet is the only reader A worklet runs in an isolated scope with no network access, and its single permitted output is a choice among URLs (SelectUrl) rendered inside a fenced frame. Run gets no result at all - not even a boolean about what it computed.
Warning:
Early - Chromium, behind a permissions policy Every method answers false rather than throwing where the runtime disagrees, and the shape of this API has changed more than once.

Support check

IsSupported

True when the runtime exposes window.sharedStorage. During prerender/SSR the check returns false rather than throwing.

C#
@inject Bit.Butil.SharedStorage sharedStorage

var supported = await sharedStorage.IsSupported();
Live sample
support check output
Results will appear here when you interact with the samples.

Write (there is no read)

Set / Append / Delete / Clear

Set writes a value, optionally leaving an existing one alone. Append adds to one. Delete and Clear remove. Keys and values are both capped at a few hundred characters, and a value over the limit fails rather than truncating.

C#
await sharedStorage.Set("campaign-seen", "1", ignoreIfPresent: true);
await sharedStorage.Append("impressions", ",42");
await sharedStorage.Delete("campaign-seen");
Live sample
write output
Results will appear here when you interact with the samples.

Load the worklet

AddModule

The worklet module is the only code that ever sees a stored value. It must be same-origin, and a page may add one only once. Inside it, a register('name', …) call declares the operations Run and SelectUrl can call.

@inject Bit.Butil.SharedStorage sharedStorage

@code {
    // A page may add one module only, ever - a second call is refused for the life of the document.
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender is false) return;

        var added = await sharedStorage.AddModule("/shared-storage-worklet.js");
        // false when there is no API here, the module 404'd, or one was already added
    }
}
Live sample
worklet output
Results will appear here when you interact with the samples.

Run an operation

Run / SelectUrl

Run starts a registered operation and tells you only whether it started. SelectUrl runs an operation that picks one of the given URLs by index; which one won is not reported to the page - the result is only usable by handing it to a fenced frame, whose whole point is that the embedding page cannot inspect it.

C#
await sharedStorage.Run("frequency-cap", new { campaignId = 42 });

await sharedStorage.SelectUrl("pick-creative",
    ["/creative-a", "/creative-b"],
    new { slot = "hero" });
Live sample
run output
Results will appear here when you interact with the samples.

API reference

Member
Signature
Description
IsSupported
ValueTask<bool> IsSupported()
True when the runtime exposes window.sharedStorage.
Set
ValueTask<bool> Set(string key, string value, bool ignoreIfPresent = false)
Writes a value. There is no matching read.
Append
ValueTask<bool> Append(string key, string value)
Appends to an existing value, or sets it when there is none.
Delete
ValueTask<bool> Delete(string key)
Removes one key.
Clear
ValueTask<bool> Clear()
Removes everything this origin has written.
AddModule
ValueTask<bool> AddModule(string url)
Loads the worklet module - the only code that can read what was written. A page may add one only once.
Run
ValueTask<bool> Run(string operation, object? data = null, bool keepAlive = false)
Runs a registered worklet operation. Reports whether it started, never what it computed.
SelectUrl
ValueTask<bool> SelectUrl(string operation, string[] urls, object? data = null, bool resolveToConfig = false)
Runs a worklet operation that picks one of the given URLs. Which one won is not reported to the page.
An unhandled error has occurred. Reload 🗙