AstrolUI AstrolUI
Yellow Orange Red Green Blue Purple Custom color
Light mode
JS utilities

Astrol.JSInterop.Base: browser storage, clipboard, files and browser data from C#.

Astrol.JSInterop.Base comes with Astrol.Component.Basic and gathers the browser calls almost every app needs, so you don't write JavaScript. Its JS module is downloaded the first time it is used. AddAstrolBasic() already registers AstrolJSInterop; storage is a set of extension methods of IJSRuntime.

@* Program.cs: builder.Services.AddAstrolBasic(); (registers AstrolJSInterop) *@
@using Astrol.JSInterop.Base
@inject AstrolJSInterop jsI @* clipboard, files, browser, idle timer *@
@inject IJSRuntime js @* storage: extension methods of IJSRuntime *@

1. localStorage and sessionStorage

Store preferences, filters, a wizard's last step or a draft with its C# type: the value becomes JSON when saved and goes back to its type when read; if it doesn't exist you get default. localStorage survives closing the browser and sessionStorage lasts only as long as the tab.

By default (useEncrypt = true) the value is stored obfuscated: it can't be read at a glance in the browser tools, which adds a layer of discretion. It is not security-grade encryption: don't store passwords, tokens or sensitive data in the browser. With useEncrypt: false readable JSON is stored (e.g. to share it with JavaScript code). Always read with the same useEncrypt value you saved with.

Try it: save with and without useEncrypt and compare the stored value.

read — stored —
public record Preferences(string Theme, int PageSize);
 
// Save any serializable value (stored as JSON; obfuscated by default)
await js.SetInLocalStorage("prefs", new Preferences("dark", 20));
 
// Read it back with its type (default if it does not exist)
var prefs = await js.GetFromLocalStorage<Preferences>("prefs");
 
bool exists = await js.ExistsInLocalStorage("prefs");
await js.RemoveFromLocalStorage("prefs");
await js.ClearLocalStorage();
 
// Same API for sessionStorage (cleared when the tab is closed)
await js.SetInSessionStorage("wizard-step", 3);
int step = await js.GetFromSessionStorage<int>("wizard-step");
 
// Plain, readable JSON (e.g. to share it with JavaScript code)
await js.SetInLocalStorage("theme", "dark", useEncrypt: false);

2. Clipboard and files

CopyToClipboard copies a text (returns false if the browser doesn't allow it). SaveAs downloads a file generated in the app from its bytes (a CSV, a PDF, an Excel...) and DownloadFile one that is already at a URL, with the name you choose.

bool copied = await jsI.CopyToClipboard("dotnet add package Astrol.Component.Basic");
 
// A file generated in the app (CSV, PDF, Excel... as byte[])
await jsI.SaveAs("clients.csv", Encoding.UTF8.GetBytes(csv));
 
// A file that is already at a URL
await jsI.DownloadFile("files/report.pdf", "report-2026.pdf");

3. Browser data and actions

The user's time zone and language (for dates and texts), MatchesMedia for any CSS media query (mobile, dark mode, print...), opening a new tab safely and scrolling to an element or to the top of the page (also inside the AstrolLayoutMenu body).

GetTimeZone() America/Tijuana GetBrowserLanguage() es-ES MatchesMedia("(max-width: 768px)") False MatchesMedia("(prefers-color-scheme: dark)") False
string timeZone = await jsI.GetTimeZone(); // "America/Tijuana"
string language = await jsI.GetBrowserLanguage(); // "es-MX"
bool isMobile = await jsI.MatchesMedia("(max-width: 768px)");
bool prefersDark = await jsI.MatchesMedia("(prefers-color-scheme: dark)");
 
await jsI.OpenInNewTab("https://astrolui.com");
await jsI.ScrollToElement("#results");
await jsI.ScrollToTop();

4. Logout on inactivity

IdleTimer calls your [JSInvokable] Logout() method when the user hasn't moved the mouse, typed, scrolled or touched the screen for a while. The last activity is shared between tabs: working in one keeps the session alive in the others.

// MainLayout.razor.cs: log out after 30 minutes without activity
private DotNetObjectReference<MainLayout>? self;
 
protected override async Task OnAfterRenderAsync(bool firstRender)
{
 if (firstRender)
 {
 self = DotNetObjectReference.Create(this);
 await jsI.IdleTimer(self, storageKey: "myapp", time: 30 * 60 * 1000);
 }
}
 
[JSInvokable]
public async Task Logout()
{
 await AuthService.LogoutAsync();
 Navigation.NavigateTo("/login");
}

Reference

Storage (IJSRuntime extensions, useEncrypt defaults to true)

  • SetInLocalStorage<T>(key, value, useEncrypt) / SetInSessionStorage<T>(...)
  • GetFromLocalStorage<T>(key, useEncrypt) / GetFromSessionStorage<T>(...): the value or default.
  • ExistsInLocalStorage(key) / ExistsInSessionStorage(key)
  • RemoveFromLocalStorage(key) / RemoveFromSessionStorage(key)
  • ClearLocalStorage() / ClearSessionStorage(): remove every key of the site.

AstrolJSInterop

  • CopyToClipboard(text) → bool
  • SaveAs(fileName, bytes) and DownloadFile(url, fileName)
  • GetTimeZone() and GetBrowserLanguage() → string; MatchesMedia(query) → bool
  • OpenInNewTab(url), ScrollToElement(selector, smooth) and ScrollToTop(smooth)
  • IdleTimer(dotNetRef, storageKey, time): calls Logout() after time ms without activity (default 30 minutes).
  • Notification(notification): classic notifications; in new code use IAstrolToast (see Notification).
  • DOM helpers used by the components: FocusElement, GetWidthBySelector, GetHeightBySelector, CountElementExistToHTML, SetInputValue, Prompt.
Markdown for AI © 2026 AstrolUI v10.0.13