- Spec files
npm-tanstack--react-router
Describes: pkg:npm/@tanstack/react-router@1.132.x
- Description
- Modern and scalable routing for React applications with built-in data fetching, caching, and state management capabilities
- Author
- tessl
- Last updated
How to use
npx @tessl/cli registry install tessl/npm-tanstack--react-router@1.132.0
ssr.md docs/
1# Server-Side Rendering23Complete SSR support with server and client components, rendering utilities, hydration, stream handling, and asset management for modern web applications.45## Capabilities67### Server-Side Rendering Functions89Functions for rendering router to string or stream on the server.1011```typescript { .api }12/**13* Render router to string for SSR14* @param options - Server rendering options15* @returns Promise resolving to rendered HTML string16*/17function renderRouterToString<TRouter extends AnyRouter>(18options: RenderRouterToStringOptions<TRouter>19): Promise<string>;2021/**22* Render router to stream for SSR with streaming23* @param options - Stream rendering options24* @returns Promise resolving to readable stream25*/26function renderRouterToStream<TRouter extends AnyRouter>(27options: RenderRouterToStreamOptions<TRouter>28): Promise<ReadableStream<Uint8Array>>;2930interface RenderRouterToStringOptions<TRouter extends AnyRouter> {31/** Router instance */32router: TRouter;33/** Request URL */34url: string;35/** Request headers */36headers?: Record<string, string>;37/** Render handler function */38renderHandler?: RenderHandler;39/** Additional context */40context?: any;41}4243interface RenderRouterToStreamOptions<TRouter extends AnyRouter> {44/** Router instance */45router: TRouter;46/** Request URL */47url: string;48/** Request headers */49headers?: Record<string, string>;50/** Stream handler function */51streamHandler?: StreamHandler;52/** Render handler function */53renderHandler?: RenderHandler;54/** Additional context */55context?: any;56}57```5859**Usage Examples:**6061```typescript62import { renderRouterToString, renderRouterToStream } from "@tanstack/react-router/ssr/server";6364// Express.js server with string rendering65app.get("*", async (req, res) => {66try {67const html = await renderRouterToString({68router,69url: req.url,70headers: req.headers,71context: {72user: req.user,73session: req.session,74},75});7677res.status(200).send(`78<!DOCTYPE html>79<html>80<head>81<meta charset="utf-8">82<title>My App</title>83</head>84<body>85<div id="root">${html}</div>86<script src="/client.js"></script>87</body>88</html>89`);90} catch (error) {91res.status(500).send("Server Error");92}93});9495// Stream rendering for better performance96app.get("*", async (req, res) => {97try {98const stream = await renderRouterToStream({99router,100url: req.url,101headers: req.headers,102});103104res.setHeader("Content-Type", "text/html");105res.write(`106<!DOCTYPE html>107<html>108<head>109<meta charset="utf-8">110<title>My App</title>111</head>112<body>113<div id="root">114`);115116const reader = stream.getReader();117const pump = () => {118return reader.read().then(({ done, value }) => {119if (done) {120res.end(`121</div>122<script src="/client.js"></script>123</body>124</html>125`);126return;127}128res.write(new TextDecoder().decode(value));129return pump();130});131};132133return pump();134} catch (error) {135res.status(500).send("Server Error");136}137});138```139140### Server and Client Components141142Specialized components for server-side and client-side routing.143144```typescript { .api }145/**146* Server-side router component147* @param props - Server router props148* @returns JSX element for server rendering149*/150function RouterServer<TRouter extends AnyRouter>(151props: RouterServerProps<TRouter>152): JSX.Element;153154/**155* Client-side router component for hydration156* @param props - Client router props157* @returns JSX element for client hydration158*/159function RouterClient<TRouter extends AnyRouter>(160props: RouterClientProps<TRouter>161): JSX.Element;162163interface RouterServerProps<TRouter extends AnyRouter> {164/** Router instance */165router: TRouter;166/** Server context */167context?: any;168/** Dehydrated state */169dehydratedState?: any;170}171172interface RouterClientProps<TRouter extends AnyRouter> {173/** Router instance */174router: TRouter;175/** Hydration state from server */176hydrationState?: any;177}178```179180**Usage Examples:**181182```typescript183// Server-side component usage184import { RouterServer } from "@tanstack/react-router/ssr/server";185186function ServerApp({ router, context }: { router: Router; context: any }) {187return (188<RouterServer189router={router}190context={context}191dehydratedState={{192user: context.user,193timestamp: Date.now(),194}}195/>196);197}198199// Client-side hydration200import { RouterClient } from "@tanstack/react-router/ssr/client";201202function ClientApp({ router }: { router: Router }) {203const hydrationState = window.__ROUTER_HYDRATION_STATE__;204205return (206<RouterClient207router={router}208hydrationState={hydrationState}209/>210);211}212```213214### Render and Stream Handlers215216Default handlers for rendering and streaming functionality.217218```typescript { .api }219/**220* Default render handler for SSR221* @param options - Render handler options222* @returns Rendered content223*/224function defaultRenderHandler<TRouter extends AnyRouter>(225options: RenderHandlerOptions<TRouter>226): React.ReactElement;227228/**229* Default stream handler for SSR streaming230* @param options - Stream handler options231* @returns Stream configuration232*/233function defaultStreamHandler<TRouter extends AnyRouter>(234options: StreamHandlerOptions<TRouter>235): StreamHandlerResult;236237interface RenderHandlerOptions<TRouter extends AnyRouter> {238router: TRouter;239context?: any;240dehydratedState?: any;241}242243interface StreamHandlerOptions<TRouter extends AnyRouter> {244router: TRouter;245context?: any;246}247248interface StreamHandlerResult {249/** Bootstrap script */250bootstrapScript?: string;251/** Bootstrap modules */252bootstrapModules?: string[];253/** Progressive enhancement */254progressivelyEnhance?: boolean;255}256257type RenderHandler = <TRouter extends AnyRouter>(258options: RenderHandlerOptions<TRouter>259) => React.ReactElement;260261type StreamHandler = <TRouter extends AnyRouter>(262options: StreamHandlerOptions<TRouter>263) => StreamHandlerResult;264```265266**Usage Examples:**267268```typescript269import { defaultRenderHandler, defaultStreamHandler } from "@tanstack/react-router/ssr/server";270271// Custom render handler272const customRenderHandler: RenderHandler = ({ router, context, dehydratedState }) => {273return (274<html>275<head>276<title>{context.title}</title>277<meta name="description" content={context.description} />278<HeadContent />279</head>280<body>281<RouterServer282router={router}283context={context}284dehydratedState={dehydratedState}285/>286<Scripts />287<script288dangerouslySetInnerHTML={{289__html: `window.__ROUTER_HYDRATION_STATE__ = ${JSON.stringify(dehydratedState)};`,290}}291/>292</body>293</html>294);295};296297// Custom stream handler298const customStreamHandler: StreamHandler = ({ router, context }) => {299return {300bootstrapScript: "/static/js/client.js",301bootstrapModules: ["/static/js/hydration.js"],302progressivelyEnhance: true,303};304};305306// Use custom handlers307const html = await renderRouterToString({308router,309url: req.url,310renderHandler: customRenderHandler,311context: {312title: "My App",313description: "A great application",314user: req.user,315},316});317```318319### Asset Management Components320321Components for managing HTML assets, scripts, and metadata in SSR.322323```typescript { .api }324/**325* Renders route-specific and manifest scripts326* @returns JSX element with script tags327*/328function Scripts(): JSX.Element;329330/**331* Renders various HTML assets (scripts, styles, meta, etc.)332* @param props - Asset configuration333* @returns JSX element with asset tags334*/335function Asset(props: AssetProps): JSX.Element;336337/**338* Renders head content from route matches339* @returns JSX element with head content340*/341function HeadContent(): JSX.Element;342343/**344* Ensures scripts are only rendered once345* @param props - Script attributes346* @returns JSX script element347*/348function ScriptOnce(props: React.ScriptHTMLAttributes<HTMLScriptElement>): JSX.Element;349350interface AssetProps extends RouterManagedTag {351/** Content Security Policy nonce */352nonce?: string;353}354355interface RouterManagedTag {356/** HTML tag type */357tag: "script" | "style" | "link" | "meta" | "title";358/** Tag attributes */359attrs?: Record<string, string>;360/** Tag content */361children?: string;362}363```364365**Usage Examples:**366367```typescript368import { Scripts, Asset, HeadContent, ScriptOnce } from "@tanstack/react-router";369370// Complete HTML document with assets371function DocumentShell() {372return (373<html>374<head>375<HeadContent />376<Asset377tag="meta"378attrs={{ charset: "utf-8" }}379/>380<Asset381tag="link"382attrs={{383rel: "stylesheet",384href: "/static/css/app.css",385}}386/>387<ScriptOnce388src="/static/js/polyfills.js"389defer390/>391</head>392<body>393<div id="root">394<RouterServer router={router} />395</div>396<Scripts />397</body>398</html>399);400}401402// Conditional asset loading403function ConditionalAssets({ isDevelopment }: { isDevelopment: boolean }) {404return (405<>406{isDevelopment && (407<ScriptOnce src="/static/js/devtools.js" />408)}409<Asset410tag="link"411attrs={{412rel: "preconnect",413href: "https://api.example.com",414}}415/>416</>417);418}419```420421### Router Context for SSR422423Utilities for accessing router context in SSR environments.424425```typescript { .api }426/**427* Get router context for SSR usage428* @returns React context for router429*/430function getRouterContext(): React.Context<AnyRouter | undefined>;431```432433**Usage Examples:**434435```typescript436import { getRouterContext } from "@tanstack/react-router";437438// Access router in SSR context439function ServerOnlyComponent() {440const RouterContext = getRouterContext();441442return (443<RouterContext.Consumer>444{(router) => {445if (!router) return null;446447return (448<div>449<p>Current URL: {router.state.location.pathname}</p>450<p>Matches: {router.state.matches.length}</p>451</div>452);453}}454</RouterContext.Consumer>455);456}457458// Use with useContext459function useRouterSSR() {460const RouterContext = getRouterContext();461return useContext(RouterContext);462}463```464465### Location Rewriting for SSR466467Utilities for rewriting URLs and handling base paths in SSR.468469```typescript { .api }470/**471* Create a basepath rewrite function472* @param basepath - Base path to rewrite473* @returns Location rewrite function474*/475function rewriteBasepath(basepath: string): LocationRewrite;476477/**478* Compose multiple location rewrite functions479* @param rewrites - Array of rewrite functions480* @returns Composed rewrite function481*/482function composeRewrites(...rewrites: LocationRewrite[]): LocationRewrite;483484type LocationRewrite = (location: ParsedLocation) => ParsedLocation;485type LocationRewriteFunction = LocationRewrite;486```487488**Usage Examples:**489490```typescript491import { rewriteBasepath, composeRewrites } from "@tanstack/react-router";492493// Basepath rewriting494const basepathRewrite = rewriteBasepath("/app");495496// Custom location rewrite497const customRewrite: LocationRewrite = (location) => ({498...location,499pathname: location.pathname.replace(/^\/old/, "/new"),500});501502// Compose multiple rewrites503const composedRewrite = composeRewrites(504basepathRewrite,505customRewrite,506(location) => ({507...location,508search: { ...location.search, timestamp: Date.now() },509})510);511512// Use in router configuration513const router = createRouter({514routeTree,515basepath: "/app",516// Apply location rewrites517rewrite: composedRewrite,518});519```520521### Serialization for SSR522523Serialization utilities for transferring data between server and client.524525```typescript { .api }526/**527* Create a serialization adapter528* @param adapter - Serialization configuration529* @returns Serialization adapter530*/531function createSerializationAdapter<T>(532adapter: SerializationAdapter<T>533): SerializationAdapter<T>;534535interface SerializationAdapter<T = any> {536/** Serialize value for transport */537serialize: (value: T) => string;538/** Deserialize value from transport */539deserialize: (value: string) => T;540}541542type AnySerializationAdapter = SerializationAdapter<any>;543```544545**Usage Examples:**546547```typescript548import { createSerializationAdapter } from "@tanstack/react-router";549550// Custom date serialization551const dateAdapter = createSerializationAdapter({552serialize: (date: Date) => date.toISOString(),553deserialize: (dateString: string) => new Date(dateString),554});555556// Complex object serialization557const complexAdapter = createSerializationAdapter({558serialize: (obj) => {559return JSON.stringify(obj, (key, value) => {560if (value instanceof Date) return { __type: "Date", value: value.toISOString() };561if (value instanceof Map) return { __type: "Map", value: Array.from(value.entries()) };562return value;563});564},565deserialize: (str) => {566return JSON.parse(str, (key, value) => {567if (value?.__type === "Date") return new Date(value.value);568if (value?.__type === "Map") return new Map(value.value);569return value;570});571},572});573574// Use in router575const router = createRouter({576routeTree,577serializationAdapter: complexAdapter,578});579```580581## Types582583### SSR Configuration Types584585```typescript { .api }586interface SSROptions {587/** Enable server-side rendering */588ssr?: boolean;589/** Hydration strategy */590hydrationStrategy?: "progressive" | "immediate" | "lazy";591/** Stream rendering options */592streaming?: boolean;593/** Asset preloading strategy */594assetPreloading?: "aggressive" | "conservative" | "none";595}596597interface HydrationState {598/** Router state for hydration */599routerState: RouterState;600/** Dehydrated loader data */601loaderData: Record<string, any>;602/** Timestamp of server render */603timestamp: number;604}605```606607### Stream Types608609```typescript { .api }610interface StreamOptions {611/** Bootstrap scripts */612bootstrapScripts?: string[];613/** Bootstrap modules */614bootstrapModules?: string[];615/** Progressive enhancement */616progressivelyEnhance?: boolean;617/** Identifier for the stream */618identifierPrefix?: string;619}620```