---
title: renderFragment
---

# renderFragment

Renders a single fragment on demand, outside a full site build: the exact bytes
`emitFragments` would have written for that `id`, at the same URL.

## Signature

```tsx
import { renderFragment } from "@vincle/flow";

function renderFragment(
  id: string,
  content: DeferContent,
  options: RenderFragmentOptions,
): Promise<{ url: string; html: string }>;
```

## Options

| Option         | Type                                                           | Default                              | Description                                           |
| -------------- | -------------------------------------------------------------- | ------------------------------------ | ----------------------------------------------------- |
| `adapter`      | `Adapter`                                                      | Required                             | Wire-format adapter: the same one the full build uses |
| `generatePath` | `(id: string) => string`                                       | ``(id) => `/fragments/${id}.html` `` | Must match the full build's convention                |
| `timeout`      | `number`                                                       | N/A                                  | Forwarded to the underlying `<Defer>`                 |
| `onError`      | `(error: unknown, info: FlowErrorInfo) => JSX.Element \| void` | N/A                                  | Forwarded to the underlying `<Defer>`                 |

Options are validated at the call, before anything renders: see
[Error handling](/api/core/error-handling).

## Usage

```tsx
import { renderFragment } from "@vincle/flow";
import { NativeAdapter } from "@vincle/flow/adapters";

declare function fetchPrice(symbol: string): Promise<{ value: number }>;

// Any standard Request → Response handler (e.g. an edge function).
export default async function handler(req: Request): Promise<Response> {
  const symbol = new URL(req.url).searchParams.get("symbol");
  if (!symbol) return new Response("Missing symbol", { status: 400 });

  const price = await fetchPrice(symbol);
  const { url, html } = await renderFragment(
    `price-${symbol}`,
    <span>{price.value.toFixed(2)}</span>,
    { adapter: NativeAdapter },
  );

  // Write `html` to `url`: the page that includes it needs no rebuild.
  return Response.json({ url, html });
}
```

Call it wherever your data changes (a webhook, a queue consumer, a scheduled
function). Writing `html` to `url` is your platform's job: a blob store, an
on-demand revalidation call, a CDN purge. The page's placeholder for this
id already points at `url`.

`content` accepts anything `<Defer>` does, but resolves once, to the last value
produced: an `AsyncIterable` that never completes never resolves. For content
over time, use [streaming](/integration/streaming).
