Screenshot and PDF Generation in SvelteKit with SnapAPI
April 2026 — 7 min read
SvelteKit is Svelte's official full-stack application framework, combining server-side rendering, static site generation, and API route handling in a single elegant package. Its server-only modules and form actions make building secure, server-side API endpoints straightforward. In this tutorial, you will add screenshot and PDF generation to a SvelteKit application using SnapAPI, implementing the capture logic in a SvelteKit server route, protecting it with server-side session validation, and returning binary responses efficiently to the client.
SvelteKit Server Routes for Screenshot Generation
SvelteKit server routes are defined as +server.ts files within the src/routes directory. A GET handler in src/routes/api/screenshot/+server.ts maps to the URL /api/screenshot. The handler receives a RequestEvent object providing access to the URL, request headers, cookies, and platform environment. Use the url.searchParams API to extract the target URL parameter. Your SnapAPI key lives in SvelteKit's private environment variables -- defined in your .env file with a SNAPAPI_KEY variable and accessed through the $env/static/private module, which SvelteKit guarantees never to include in the client bundle.
Validating the Target URL
Never pass user-supplied URLs directly to an external API without validation. In your SvelteKit server route, instantiate a URL object inside a try-catch block to validate that the target URL is well-formed. Check that the URL protocol is http or https and reject anything using file, data, or javascript schemes. Consider implementing an allowlist of permitted domains if your application should only screenshot a known set of URLs rather than arbitrary user-provided ones. Return a structured error response with a 400 status code if validation fails, giving the client enough information to correct its request.
Calling SnapAPI and Streaming the Response
After URL validation, call the SnapAPI screenshot endpoint using the native fetch API available in SvelteKit's Node.js server environment. Set the Authorization header to your SnapAPI key retrieved from the private environment module. Await the SnapAPI response and check its status code before proceeding. On success, return a new Response object constructed from the SnapAPI response body, setting the Content-Type header to match the SnapAPI response -- either image/png for screenshots or application/pdf for PDFs. SvelteKit correctly handles Response objects that wrap ReadableStreams, streaming the binary content to the client without buffering the entire payload in server memory.
Form Actions for Screenshot Triggering
SvelteKit form actions handle POST requests from standard HTML forms without client-side JavaScript. This makes them ideal for screenshot generation triggered by user actions in a progressively enhanced SvelteKit application. Define a default action in a page's +page.server.ts file that reads the target URL from the form data, validates it, calls SnapAPI, uploads the result to cloud storage, and redirects to a success page with the stored screenshot URL. The entire workflow functions correctly even with JavaScript disabled in the browser, providing reliable screenshot generation across all client environments.
Caching Screenshots with SvelteKit Hooks
SvelteKit hooks intercept all incoming requests before they reach route handlers, making them an ideal location for request-level caching logic. In src/hooks.server.ts, check if the incoming request is for your screenshot route and whether a cached screenshot exists for the requested URL hash in Redis or another server-side cache. If a cached result exists, return it immediately without executing the route handler. Cache misses fall through to the route handler normally, which calls SnapAPI and writes the result to the cache before returning. This caching layer operates transparently from the perspective of both the route handler and the client.
Deploying SvelteKit with Screenshot Routes
SvelteKit adapts to different deployment targets through its adapter system. The Node.js adapter deploys your screenshot service as a traditional Node.js server. The Vercel adapter deploys API routes as serverless functions. The Cloudflare adapter deploys to Cloudflare Workers. In all cases, your SnapAPI key is stored as a private environment variable in the deployment platform and accessed through the $env/static/private module without any code changes between deployment targets. Choose the adapter that matches your infrastructure, run the SvelteKit build, and deploy -- your screenshot route is live globally within minutes.