---
url: https://lit-ui-router.dev/api/lit-ui-router-ssr/client/functions/bootstrap.md
---
[lit-ui-router-ssr](../../index.md) / [client](../index.md) / bootstrap

# Function: bootstrap()

```ts
function bootstrap(
   router, 
   container, 
   value, 
   options?
): Promise<BootstrapResult>;
```

Defined in: [packages/lit-ui-router-ssr/src/client.ts:988](https://github.com/simshanith/lit-ui-router/blob/3ab90929a8d23dda96e259d7396a274c5b05398e/packages/lit-ui-router-ssr/src/client.ts#L988)

Boots `router` into the page `container` holds, and resolves once that page
is live.

It owns the whole client boot. `options.payload`, when given, seeds the boot
transition first. The container's [signature](readHydrationSignature.md)
is read before anything else touches the document; a container [hydrateRoot](hydrateRoot.md) would not adopt — no signature, another release line, stripped
markers — is emptied and `value` rendered into it at once, and the router
then starts. Otherwise the router starts, the call waits for the boot
transition to land, following redirects to the one that succeeds, and then
hydrates the container with `value`.

The boot decides once what the page does:

* The boot lands where the signature says the document was drawn: every
  served view adopts, and a view that still mismatches warns in development,
  since that is a template the two halves render differently.
* The boot lands elsewhere — a static host serving one document for a
  family of urls, or a redirect: the views that match adopt, and the views
  that differ render cold without a warning of their own. Once the page is
  live, one development warning names both states and how many views
  rendered cold, when any did.
* The boot fails, or the url starts no transition: the container is emptied
  and `value` rendered cold. The root `hydrate()` throwing, as over a
  mutated document, does the same. The call resolves rather than rejects.

Every served view still reports its own [AdoptOutcome](../type-aliases/AdoptOutcome.md), as a [UiViewAdoptEvent](../type-aliases/UiViewAdoptEvent.md) and to `options.onAdopt`. The call waits for each awake
`<ui-view>` to finish updating, nested views included, then releases the
adopter `hydrateRoot()` provided; a view the app detached keeps its pin.

## Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `router` | [`UIRouterLit`](/api/reference/core/UIRouterLit) | the client router, its states registered and not yet started |
| `container` | `HTMLElement` | the element the server's markup was written into, or an empty one |
| `value` | `unknown` | the same template the server rendered, with every `<ui-view>` hole empty |
| `options?` | [`BootstrapOptions`](../interfaces/BootstrapOptions.md) | lit render options, `onAdopt`, and the boot transition's `payload` |

## Returns

`Promise`<[`BootstrapResult`](../interfaces/BootstrapResult.md)>

what the boot came to, once every awake view has updated

## Example

```ts
import { bootstrap } from 'lit-ui-router-ssr/client';

const { outcome } = await bootstrap(router, root, page(router));
```

## Throws

what `router.start()` throws, as on a router already started

## Throws

the `TypeError` `seed` throws on a payload with no `resolves`, before the router starts
