# Recipes

Complete, working patterns taken from production integrations. Each one is a few files you can copy, with the reasoning beside the code.

- [Own the download: export, upload to S3, hand back a link](https://kernstra.com/docs/web-sdk/recipes/custom-download-s3): Hide or take over the SDK's own Download, export the edited document through `viewer.createExporter()`, upload it to your bucket through a presigned URL, then give the person a link from your backend.
- [Bring your own chrome](https://kernstra.com/docs/web-sdk/recipes/own-chrome): Render no toolbar and no navigation bar, keep the SDK's pages, panels and per-tool option bars, and drive the tools from buttons of your own through the viewer API.
- [Serve the engine from your own origin](https://kernstra.com/docs/web-sdk/recipes/self-host-engine): Under a license that includes self-hosting, fetch the engine, the shaping and subsetting binaries and the bundled fonts once by their digests, serve them from your own servers, and point `Kernstra.init()` and the viewer at them. The browser then makes no request outside your origin.
- [Next.js, Nuxt, SvelteKit and Astro: mount on the client, tear down cleanly](https://kernstra.com/docs/web-sdk/recipes/ssr-frameworks): The package imports cleanly on the server, but a viewer is browser-only. Render the component on the client alone, keep `init()` in one module, and release both the viewer and the document on unmount.
- [Hand a large file between pages without a server](https://kernstra.com/docs/web-sdk/recipes/handoff-indexeddb): Store the picked file's bytes in IndexedDB on the upload page, navigate, and open them with `PDFDocument.fromBytes()` on the editor page. Nothing is uploaded until the person saves.
- [Unsaved changes done right](https://kernstra.com/docs/web-sdk/recipes/unsaved-changes): Let the viewer track whether the document differs from what it was opened from or last saved, warn before the tab closes only when it matters, and tell the viewer when a save of your own succeeded.
- [Match your brand with tokens](https://kernstra.com/docs/web-sdk/recipes/theming-tokens): Set the accent once through config for the common case, follow the OS or switch themes live from your own toggle, or override the semantic tokens when your design system wants control of every surface.
- [Phones and touch, without fighting the browser](https://kernstra.com/docs/web-sdk/recipes/phones-touch): Meet the two host-side requirements the SDK cannot do for you, pick a phone and tablet composition, open at the right zoom, and keep pinch, the form stepper and the touch sizes the SDK provides.
- [React to the viewer with events, not timers](https://kernstra.com/docs/web-sdk/recipes/events-not-polling): Everything your interface needs to mirror is announced. Subscribe once, keep the unsubscribe or an `AbortSignal`, and drop the polling loop.
