---
url: >-
  https://lit-ui-router.dev/reference/lit-ui-router-ssr/index/functions/renderToString.md
---
[lit-ui-router-ssr](../../index.md) / [lit-ui-router-ssr](../index.md) / renderToString

# Function: renderToString()

```ts
function renderToString(template, options): RenderedPage;
```

Defined in: [packages/lit-ui-router-ssr/src/render.ts:313](https://github.com/simshanith/lit-ui-router/blob/740888c2b2ba358c4dfa52a122e927df6a604b12/packages/lit-ui-router-ssr/src/render.ts#L313)

Renders the page a router already stands on to a string, for a host that
owns the request: a framework route or a worker settles the router on the
request's path, decides the response, and calls this for the page's markup.
It is the render `prerender()` runs for every page it writes, so the markup
is the same bytes `prerender()` hands `document` for the same template and
router.

The markup opens on the page's hydration signature, the JSON data block
`hydrateRoot()` reads, then the template's render, drawn with
`deferHydration` so every custom element sleeps until the client's walk
reaches it. The status, the redirect and the document around the markup
are the host's: settle with `settle`, read a `redirectTo` with
`redirectedTo`, and wrap the markup in the shell html.

The render is synchronous and collects the whole page into one string. The
router is scoped to it through a module slot, so renders on one thread never
interleave.

## Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `template` | `TemplateResult` | the page, rendered with the router in scope |
| `options` | [`RenderToStringOptions`](../interfaces/RenderToStringOptions.md) | the router, and the renderers and resolve payload to draw with |

## Returns

[`RenderedPage`](../interfaces/RenderedPage.md)

the page's markup, and what its signature carries of the resolve payload

## Throws

an `Error` when both `dehydrate` and `payload` are supplied

## Example

```ts
import type { TemplateResult } from 'lit';
import type { UIRouterLit } from 'lit-ui-router';
import { redirectedTo, renderToString, settle } from 'lit-ui-router-ssr';

declare function page(router: UIRouterLit): TemplateResult;
declare function shell(body: string): string;

// `router` serves the mount at /releases; `subpath` is the request's path within it.
async function serve(router: UIRouterLit, subpath: string): Promise<Response> {
  const redirect = redirectedTo(router, await settle(router, subpath));

  if (redirect)
    return new Response(null, {
      status: redirect.status,
      headers: { Location: `/releases${redirect.url}` },
    });

  const { html } = renderToString(page(router), { router, dehydrate: {} });

  return new Response(shell(html), {
    headers: { 'Content-Type': 'text/html; charset=utf-8' },
  });
}
```
