# Browser APIs

Rask reaches the browser's Web APIs two ways. Most are MDN's own surface, generated into C# by
[`Rask.Web`](https://rask.sh/docs/guides/web-apis/): `await Navigator.Clipboard.WriteText("hi")`, `await LocalStorage.GetItem("theme")`. The
rest are **typed C# wrappers** — inject one through a component constructor and call it, instead of hand-writing
`IJSRuntime` identifiers and getting the JSON shape right yourself. Each is a thin, awaitable layer over the same unified
[`IJSRuntime`](https://rask.sh/docs/guides/js-interop-runtime/#calling-js-from-c-ijsruntime), so it works the same way whether your
app runs on the **Server** (WebSocket) or **WASM** (`JSImport`/`JSExport`) transport.

This page is the **map of the whole surface**. For an at-a-glance view of *where each API works*
(Web / PWA), see the
[**capability matrix**](https://rask.sh/docs/guides/browser-capabilities/) — it links to a dedicated reference page per API
under [`docs/apis/`](https://github.com/pal-tamas/rask/blob/main/docs/apis/). For the deeper "why" — user activation, the transport seam, element
refs — see [JS interop → Typed browser APIs](https://rask.sh/docs/guides/js-interop-runtime/#typed-browser-apis); for the mobile/PWA
angle see the [Mobile & PWA guide](https://rask.sh/docs/guides/pwa/). Every wrapper has a runnable demo in the
[showcase](https://rask.sh/docs/), under **Browser APIs** — except the WASM-only tier, which gets its own page under
**PWA** because it needs something the Server transport can't give it. (The activation-gated ones appear in both: as gesture components
under Browser APIs, and as injectable services or Rask.Web calls under PWA.)

## Two homes, one rule

- **`Rask.Core.Browser`** — APIs that work on **every host** (Server + WASM). Registered by both.
- **`Rask.Wasm.Browser`** — APIs only the WASM host can run: they need the installed-PWA instance, a live
  document, a device chooser, or *transient* user activation — preserved only when the interop call runs
  inside the click's own call stack, which the Server's WebSocket round-trip loses.

> **The rule:** shared-everywhere APIs live in `Rask.Core.Browser`, WASM-only ones in
> `Rask.Wasm.Browser`. A host simply doesn't register a service it can't provide.

Sharing shows the split cleanly. The **declarative, headless** `Shareable` (Rask.Core) hands *your* markup
a `data-rask-share` attribute and the shared client fires `navigator.share` *inside the click gesture* — no
round-trip, so activation survives — so it works on **every** host, Server included. The **imperative**
`await Navigator.Share(…)` from [`Rask.Web`](https://rask.sh/docs/guides/web-apis/#what-only-webassembly-runs) shares from code (a lifecycle
hook, after an `await`), which only the WASM host can do, so it compiles only in a WASM app.

Call from an **event handler or lifecycle hook**, never from `Render()`. A typed wrapper is injected
through the **constructor** (not a settable property — that would become a required chain parameter):

```csharp
public sealed partial class ThemeToggle : Component
{
    protected override async Task OnFirstRender()
    {
        var saved = await LocalStorage.GetItem("theme");     // or: await Document.Cookie
        var dark = saved is null
            ? await Window.MatchMedia("(prefers-color-scheme: dark)").Matches
            : saved == "dark";
        // …apply theme…
    }
}
```

Browser-gated APIs (clipboard, geolocation, notifications, fullscreen, crypto's secure context, …)
can fail — a denial/timeout/unsupported surfaces as a `JSException` from the awaited task, so gate on
the API's `IsSupported`/permission check and wrap calls in `try/catch`.

See the [capability matrix](https://rask.sh/docs/guides/browser-capabilities/) for which APIs work on which host.

## On this page

- [Web APIs from MDN](https://rask.sh/docs/guides/web-apis/) — every web API the browser ships, generated from MDN into C# by `Rask.Web`.
- [The sharing model](https://rask.sh/docs/guides/browser-apis-sharing/) — shared vs WASM-only wrappers, declarative vs imperative, the subscription push pattern.
- [Reference & live demos](https://rask.sh/docs/guides/browser-apis-reference/) — every wrapper with a runnable demo.

## Notes

- **Secure context.** Clipboard, geolocation, notifications, push, `crypto.subtle`, and others require
  HTTPS or `localhost`.
- **Permission/support gating.** Many APIs expose `IsSupported()`; ask
  `Navigator.Permissions.Query(…)` from [`Rask.Web`](https://rask.sh/docs/guides/web-apis/) before triggering a prompt, and `try/catch` the call.
- **Trimming (WASM).** Types these APIs deserialize are registered in source-gen JSON contexts, and the
  push APIs' `[JSInvokable]` methods are `[DynamicDependency]`-rooted, so everything stays correct in a
  `PublishTrimmed` app.

See also: [JS interop](https://rask.sh/docs/guides/js-interop/) · [Mobile & PWA](https://rask.sh/docs/guides/pwa/).
