Framework guide: SvelteKit
Public vs private environment variables
SvelteKit explicitly distinguishes between public (accessible on the client) and private (server only) variables via$env/static/public / $env/dynamic/public vs $env/static/private / $env/dynamic/private.
.env
createConvertStore/MarkpdfClient in a .svelte component (client code), you can only pass it a PUBLIC_* variable — and that key is exposed in the bundle, just like in any SPA.
Pattern A: public key on the client (prototypes, internal tools)
Pattern B (recommended): proxy with +server.ts
Keep the key on the server and expose your own endpoint:
src/routes/api/convert/+server.ts
createConvertStore does not apply on the client side (there is no point in calling it against your own endpoint unless you also implement the same progress contract). If you need actual upload progress to your own endpoint, implement the same XMLHttpRequest pattern that createConvertStore uses internally, pointing to /api/convert instead of markpdf’s API.
Form Actions as an alternative to +server.ts
If the upload form lives on the same page, a Form Action (+page.server.ts) is an alternative without needing a separate endpoint:
src/routes/convert/+page.server.ts
