Skip to content
Vincle

Loading…

    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#

    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.

    Usage#

    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.