RSC + SSR

One model, streamed twice.

Turtle renders a React Server Component Flight stream, tees it into server HTML and browser hydration transport, and begins the response before suspended work completes.

Streaming lifecycle

  1. The precomputed router matches the Request and resolves metadata.
  2. React produces a Flight stream from the Server Component model.
  3. Turtle tees Flight: one branch feeds streaming SSR, the other is base64-framed into safe bootstrap chunks.
  4. The browser reconstructs Flight, hydrates the SSR markup, and installs client navigation.
import { Suspense } from "react";

async function SlowResult() {
  const value = await loadValue();
  return <p>{value}</p>;
}

export default function Page() {
  return <Suspense fallback={<p>Loading…</p>}><SlowResult /></Suspense>;
}

The document shell and fallback can reach the network before SlowResult resolves. The same RSC protocol powers later navigations without replacing the document.

Server and client modules

Modules are server-by-default. Put "use client" first in a module to include its exports in client manifests. Turtle supports default and named exports and does not depend on filename suffixes. Use server-only and client-only markers to make intended boundaries fail at build time when crossed.

The SSR and browser graphs reject transitive server-only imports and report importer chains. Public environment definitions are the only environment values substituted into browser output.

Metadata

import type { Metadata, Viewport } from "turtle";

export const metadata: Metadata = {
  title: { default: "Docs", template: "%s · Docs" },
  description: "Turtle documentation",
  canonical: "/docs",
  openGraph: { title: "Turtle", image: "/social.png", siteName: "Turtle" },
};

export const viewport: Viewport = {
  width: "device-width", initialScale: 1, themeColor: "#071512",
};

Nested metadata merges from layouts to page. A string title uses the active parent template; a title object establishes a template for descendants. generateMetadata(props, parent) may return metadata asynchronously. Turtle escapes all output, resolves canonical and Open Graph image URLs against the request origin, and sends title and description headers with Flight navigation.

Control flow and failures

import { notFound, redirect } from "turtle/runtime";

if (!record) notFound();
if (record.moved) redirect("/records/" + record.id);

These functions throw private typed signals recognized only at the route render boundary. Redirects accept same-origin absolute paths and return 307. Ordinary exceptions render the nearest error boundary with a safe message while full details remain in server logs.