---
title: "@kovojs/browser"
description: Browser execution helpers: app-authored derives, handlers, trusted HTML, and optimistic authoring helpers.
order: 3
---

# @kovojs/browser

Generated from 2 public subpaths — 19 exports, 19 documented. Do not edit by hand.

## `@kovojs/browser`

**Task:** App-authored derives, handlers, trusted HTML, and optimistic authoring helpers.

Source: [`packages/browser/src/index.ts`](https://github.com/kovojs/kovo/blob/main/packages/browser/src/index.ts)

### Values

#### `handler` {#handler}

Type a synchronous client event handler for an island. The handler receives the DOM event
and a `HandlerContext` exposing the island's typed `state` and element params.
The compiler links it to an `on:event` binding and loads its module on first
interaction (SPEC §4.3). Identity function at runtime; it exists for typing.

| Parameter | Type | Description |
| --- | --- | --- |
| `fn` | <code>((event: Event, ctx: <a href="#handlercontext">HandlerContext</a>&lt;State, Params&gt;) =&gt; Result) &amp; ([Result] extends [void] ? unknown : never)</code> | The handler implementation. |
| *(returns)* | <code><a href="#clienthandler">ClientHandler</a>&lt;State, Params&gt;</code> | The same handler, typed. |

**Copyable example**

```ts
import { handler } from '@kovojs/browser';

type CounterState = { count: number };

export const increment = handler<CounterState>((_event, ctx) => {
  ctx.state.count += 1;
});
```

**Signature**

```ts
function handler<
  State = unknown,
  Params = Record<string, ElementParamValue>,
  Result = undefined,
>(
  fn: ((event: Event, ctx: HandlerContext<State, Params>) => Result) &
    ([Result] extends [void] ? unknown : never),
): ClientHandler<State, Params>;
```

#### `safeRichHtml` {#saferichhtml}

Sanitizes legitimate CMS/rich-text HTML through Kovo's conservative allowlist,
then returns the existing explicit trusted-HTML brand. Browser calls also route
the sanitized string through Kovo's sole Trusted Types policy before it reaches a
DOM raw-HTML sink.

This is a runtime-DiD sanitizer floor for rich text, not a by-construction XSS
elimination claim; app-authored raw strings still need the explicit
{@link trustedHtml} escape hatch.

**Signature**

```ts
function safeRichHtml(value: string, options?: SafeRichHtmlOptions): TrustedHtml;
```

#### `trustedHtml` {#trustedhtml}

Marks intentional raw HTML for Kovo sinks that require an explicit escape hatch.

**Signature**

```ts
function trustedHtml(
  value: string | BrowserTrustedHTML,
  metadata: TrustedOutputMetadata,
): TrustedHtml;
```

#### `trustedUrl` {#trustedurl}

Marks an intentional, author-vouched URL for Kovo's URL-bearing sinks,
suppressing the `javascript:`/`data:` scheme neutralization that would
otherwise rewrite it to `#` (SPEC §4.8, KV236). The URL-scheme counterpart of
{@link trustedHtml}: you take responsibility for the URL's safety, and the
brand is visible in source and `kovo explain`.

**Signature**

```ts
function trustedUrl(value: string, metadata: TrustedOutputMetadata): TrustedUrl;
```

#### `derive` {#derive}

App-facing derive constructor (SPEC §4.8).

Raw string input tuples are compiler-generated IR and are intentionally accepted only by
`@kovojs/browser/generated`.

**Signature**

```ts
function derive<const Inputs extends readonly DeriveInput[], Value>(
  inputs: Inputs,
  fn: (
    ...values: {
      readonly [Index in keyof Inputs]: Inputs[Index] extends DeriveInput<string, infer InputValue>
        ? InputValue
        : never;
    }
  ) => Value,
): DeriveDefinition<
  {
    readonly [Index in keyof Inputs]: Inputs[Index] extends DeriveInput<infer Name, unknown>
      ? Name
      : never;
  },
  Value
>;
function derive<const Inputs extends Readonly<Record<string, DeriveInput>>, Value>(
  inputs: Inputs,
  fn: (values: {
    readonly [Name in keyof Inputs]: Inputs[Name] extends DeriveInput<string, infer InputValue>
      ? InputValue
      : never;
  }) => Value,
): DeriveDefinition<readonly string[], Value>;
```

### Supporting types

#### `ElementParamValue` {#elementparamvalue}

Runtime API used by Kovo applications and generated runtime integration.

**Signature**

```ts
type ElementParamValue = string | number | boolean;
```

#### `HandlerContext` {#handlercontext}

Runtime API used by Kovo applications and generated runtime integration.

**Signature**

```ts
interface HandlerContext<State = unknown, Params = Record<string, ElementParamValue>> {
  params: Params;
  signal: AbortSignal;
  state: State;
}
```

#### `ClientHandler` {#clienthandler}

A synchronous client event handler: receives the DOM `event` and a typed island
`HandlerContext`, mutates state during that call frame, and returns `void` (SPEC §4.3).

**Signature**

```ts
type ClientHandler<State = unknown, Params = Record<string, ElementParamValue>> = (
  event: Event,
  ctx: HandlerContext<State, Params>,
) => void;
```

#### `ImportHandlerModule` {#importhandlermodule}

Runtime API used by Kovo applications and generated runtime integration.

**Signature**

```ts
type ImportHandlerModule = (url: string) => Promise<Record<string, unknown>>;
```

#### `BrowserTrustedHTML` {#browsertrustedhtml}

Browser Trusted Types `TrustedHTML` values accepted by Kovo raw HTML sinks.

**Signature**

```ts
interface BrowserTrustedHTML {
  readonly [Symbol.toStringTag]: 'TrustedHTML';
  toString(): string;
}
```

#### `SafeRichHtmlOptions` {#saferichhtmloptions}

Conservative rich-HTML sanitizer options for CMS/user-authored HTML. This is a
runtime defense-in-depth floor, not a by-construction XSS proof (SPEC §6.6).

**Signature**

```ts
interface SafeRichHtmlOptions {
  /**
   * Optional additional element names to admit. Attribute filtering and URL-sink
   * checks still apply.
   */
  readonly allowedTags?: readonly string[];
  /** Optional override for the sanitizer's built-in review reason. */
  readonly reason?: string;
  /** Optional source locator surfaced in trust explain output. */
  readonly source?: string;
}
```

#### `TrustedHtml` {#trustedhtml-1}

Kovo's explicit raw HTML escape-hatch wrapper.

**Signature**

```ts
interface TrustedHtml {
  readonly [trustedHtmlBrand]: true;
  readonly reason: string;
  readonly source?: string;
  readonly value: string | BrowserTrustedHTML;
}
```

#### `TrustedOutputMetadata` {#trustedoutputmetadata}

Required, structured provenance attached to explicit trust escape hatches.

**Signature**

```ts
interface TrustedOutputMetadata {
  readonly reason: string;
  readonly source?: string;
}
```

#### `TrustedUrl` {#trustedurl-1}

Kovo's explicit trusted-URL escape-hatch wrapper — the URL-scheme counterpart
of {@link TrustedHtml} (SPEC §4.8). Brands a URL the author vouches for so
URL-bearing sinks (`href`/`src`/`action`/…) emit it verbatim instead of
neutralizing it against the scheme allowlist.

**Signature**

```ts
interface TrustedUrl {
  readonly [trustedUrlBrand]: true;
  readonly reason: string;
  readonly source?: string;
  readonly value: string;
}
```

#### `DeriveDefinition` {#derivedefinition}

A derived value: the named inputs it depends on and the `run` that computes it.

**Signature**

```ts
interface DeriveDefinition<Inputs extends readonly string[], Value> {
  readonly inputs: Inputs;
  run(...values: readonly unknown[]): Value;
}
```

#### `DeriveInput` {#deriveinput}

An opaque input capability accepted by the app-facing {@link derive} helper.

Query inputs are minted with `derive.query(queryHandle)`; component state and declared clocks
use `derive.state<State>()` and `derive.clock<Clocks>()`. The private brand provides rename-safe
authoring ergonomics, while the runtime WeakMap rejects structural copies and casts.

**Signature**

```ts
interface DeriveInput<Name extends string = string, Value = unknown> {
  readonly [deriveInputBrand]: {
    readonly name: Name;
    readonly value: Value;
  };
}
```

## `@kovojs/browser/client`

**Task:** One experimental, lifecycle-aware Kovo client installer for custom application shells.

Source: [`packages/browser/src/client.ts`](https://github.com/kovojs/kovo/blob/main/packages/browser/src/client.ts)

### Values

#### `installKovoClient` {#installkovoclient}

Install Kovo's browser runtime for a custom shell.

**Signature**

```ts
function installKovoClient(options: InstallKovoClientOptions = {}): KovoClient;
```

### Supporting types

#### `InstallKovoClientOptions` {#installkovoclientoptions}

The one app-authored browser bootstrap for a custom shell.

Kovo owns the query store, morph root, mutation transport, request posture,
module allowlist snapshot, and runtime caches. Generated applications do not
need this API: the compiler emits the equivalent generated-runtime bootstrap.

**Signature**

```ts
interface InstallKovoClientOptions {
  /**
   * Observe or wrap an allowed dynamic import. The URL is still checked against
   * the compiler/document module registry before this callback runs.
   */
  importModule?: (url: string) => Promise<Record<string, unknown>>;
  /**
   * Observe one framework-constructed mutation request. `next()` is zero-argument,
   * single-use, and always dispatches that exact request through the boot-pinned
   * platform fetch. Returning a different response is rejected.
   */
  fetch?: (
    request: Request,
    next: () => Promise<Response>,
    reportUploadProgress: (progress: { loaded: number; total?: number }) => void,
  ) => Promise<Response>;
  onError?: (error: unknown, context: { phase: string }) => void;
  onLifecycle?: (event: {
    mode?: 'abort' | 'drain';
    phase: 'disposed' | 'disposing' | 'ready' | 'session-transition';
    reason?: 'session-transition' | 'user';
  }) => void;
  onUploadProgress?: (progress: { loaded: number; total?: number }, form: unknown) => void;
  /** Delegation and live-fragment root. Defaults to the current `document`. */
  root?: EventTarget & ParentNode;
}
```

#### `KovoClient` {#kovoclient}

Handle returned by {@link installKovoClient}.

`dispose('drain')` (the default) removes listeners immediately, waits for
already-started imports and requests to settle, then clears internal state.
`dispose('abort')` removes listeners, aborts active requests, rejects late
imports, and clears state without waiting for authored wrappers.

**Signature**

```ts
interface KovoClient {
  readonly ready: Promise<void>;
  dispose(mode?: 'abort' | 'drain'): Promise<void>;
}
```

