← Public packages
@kentcdodds/package-app-kit
Design tokens, PWA install/update, About/version, cache helpers, and optional realtime notes sync for Kody package apps.
import { createMemoryHistory, RouterProvider } from '@tanstack/react-router'
import { renderToReadableStream } from 'react-dom/server.edge'
import { packageContext } from 'kody:runtime'
import { formatAboutPageData } from 'kody:@kentcdodds/package-app-kit/about'
import { readRecordedVersion } from '../src/record-version.ts'
import { listNotes } from './data/notes.ts'
import { createAppRouter, type RouterContext } from './routeTree.tsx'
import { ErrorBanner } from './ui/error-banner.tsx'
import { Document } from './ui/document.tsx'
import { toErrorMessage } from './ui/to-error-message.ts'
async function buildContext(runningSha?: string): Promise<RouterContext> {
const version = await readRecordedVersion()
return {
appBasePath: packageContext?.appBasePath ?? '',
assetBasePath: packageContext?.assetBasePath ?? '',
clientModuleUrl: packageContext?.clientModuleUrl ?? null,
runningSha: runningSha ?? version.sha,
listNotes,
async loadAbout() {
const recorded = await readRecordedVersion()
const about = formatAboutPageData({
version: recorded,
runningSha: recorded.sha,
codeUrl: null,
})
return {
sha: about.sha,
shortSha: about.shortSha,
message: about.message,
publishedAt: about.publishedAt,
committedAt: about.committedAt,
codeUrl: about.codeUrl,
runningSha: about.runningSha || about.sha,
}
},
}
}
/**
* SSR the matched TanStack route into a full HTML document Response.
* Uses react-dom/server.edge renderToReadableStream (Workers-safe) — not TanStack Start / Vite.
*/
export async function renderApp(request: Request): Promise<Response> {
const url = new URL(request.url)
const context = await buildContext()
const basepath = context.appBasePath.replace(/\/+$/, '') || undefined
const history = createMemoryHistory({
initialEntries: [url.pathname + url.search],
})
const router = createAppRouter({ history, context, basepath })
try {
await router.load()
const stream = await renderToReadableStream(
<RouterProvider router={router} />,
{
onError(error) {
console.error('SSR render error:', error)
},
},
)
return new Response(stream, {
headers: {
'content-type': 'text/html; charset=utf-8',
'cache-control': 'no-store',
},
})
} catch (error) {
const message = toErrorMessage(error)
console.error('SSR render failed:', error)
const stream = await renderToReadableStream(
<Document
title={`Error · __APP_TITLE__`}
appBasePath={context.appBasePath}
assetBasePath={context.assetBasePath}
clientModuleUrl={context.clientModuleUrl}
runningSha={context.runningSha}
>
<div className="pak-wrap pak-stack">
<ErrorBanner title="Something went wrong" message={message} detail={message} />
</div>
</Document>,
)
return new Response(stream, {
status: 500,
headers: {
'content-type': 'text/html; charset=utf-8',
'cache-control': 'no-store',
},
})
}
}