SvelteKit on Easel
Deploy SvelteKit applications to Easel with SSR, streaming, prerendering, form actions, hooks, and API endpoints.
At a glance
| Support level | Production-ready |
| Rendering | Static, SSR, streaming, and client-side rendering |
| Server runtime | Node.js |
| Required adapter | @sveltejs/adapter-vercel |
| Automatic detection | Yes |
| Most recently tested with | SvelteKit 2.70.x |
Deploy a SvelteKit application
Install the Vercel adapter:
Then configure it in svelte.config.js:
Deploy the project by connecting its Git repository to Easel or using the CLI:
Easel detects SvelteKit, installs the project’s dependencies, runs the production build, and deploys the output generated by the adapter.
The default build command is:
You can override the install command, build command, root directory, Node.js version, and environment variables in the project settings.
Why run SvelteKit on Easel?
Easel provides a production SvelteKit deployment path using the framework’s standard adapter system.
A SvelteKit deployment includes:
- Prerendered pages and static assets served through the Easel CDN
- Regional functions for server-rendered pages and server-side code
- Streaming responses from server load functions and endpoints
- Support for form actions, hooks, and API routes
- Preview deployments for every branch and pull request
- Built-in logs, metrics, traces, WAF, and attack protection
- Vercel-compatible build output without requiring a Vercel deployment
You can inspect function execution, request routing, deployment output, and resource usage from the Easel dashboard.
Why is the Vercel adapter required?
SvelteKit uses adapters to convert a framework build into output that a hosting platform can deploy.
@sveltejs/adapter-vercel produces a Build Output API-compatible deployment containing:
- Client assets
- Prerendered pages
- Server-side application code
- Route and function configuration
- Redirect and routing metadata
Easel consumes this output directly. Using the adapter does not deploy the application to Vercel or require a Vercel account.
Do not use adapter-auto for production Easel deployments. Automatic adapter selection can change based on the detected build environment and does not provide an explicit, reproducible deployment contract.
What Easel deploys
Easel maps the output generated by the SvelteKit adapter to the appropriate platform resources.
| SvelteKit output | Easel resource |
|---|---|
Files in static | CDN assets |
| Client JavaScript and CSS | CDN assets |
| Prerendered pages | CDN assets |
| Server-rendered pages | Easel Functions |
Server load functions | Easel Functions |
| Form actions | Easel Functions |
+server endpoints | Easel Functions |
| Server hooks | SvelteKit server function |
| Redirects and route metadata | Easel request routing |
Prerendered routes are excluded from the dynamic server manifest where possible, reducing the amount of server code required to handle requests.
Routes that require request-time data remain part of the server application and execute in Easel Functions.
Function topology
By default, the adapter can package the server-rendered portion of the SvelteKit application into a shared function.
This allows layouts, pages, endpoints, hooks, and application state to share a server bundle while SvelteKit continues to route requests internally.
The adapter also supports splitting routes into separate functions. Easel support for adapter-level and route-level function splitting depends on the generated Build Output API configuration.
Use route splitting only when it provides a concrete benefit, such as:
- Isolating a resource-intensive endpoint
- Assigning different execution settings to a route
- Reducing the deployment size of frequently invoked routes
- Preventing one route’s dependencies from affecting unrelated routes
Splitting every route can increase build output, deployment complexity, and the number of independently initialized function bundles.
Supported features
| Feature | Support | Notes |
|---|---|---|
| Server-side rendering | Supported | Dynamic routes execute in Easel Functions |
| Prerendering | Supported | Generated files are deployed to the CDN |
| Client-side rendering | Supported | Controlled through SvelteKit page options |
| Streaming server loads | Supported | Promises returned from server load functions can stream as they resolve |
| Streaming endpoints | Supported | Standard ReadableStream responses are forwarded without full-response buffering |
| Universal load functions | Supported | Run according to SvelteKit’s normal server and browser lifecycle |
| Server load functions | Supported | Execute in the SvelteKit server function |
| Form actions | Supported | Includes progressive enhancement with use:enhance |
| API endpoints | Supported | +server handlers execute in Easel Functions |
| Server hooks | Supported | Includes handle, handleFetch, and handleError |
| Universal hooks | Supported | Included in the generated application bundle |
| Cookies and sessions | Supported | Standard SvelteKit cookie APIs are available |
| Redirects and errors | Supported | Standard SvelteKit response behavior is preserved |
| Route parameters | Supported | Includes optional, rest, and matched parameters |
| Route groups | Supported | Groups remain an application-level routing concern |
| Shallow routing | Supported | Client-side framework behavior |
| Service workers | Supported | Generated service-worker assets are deployed statically |
| Private environment variables | Supported | Available only to server-side code |
| Public environment variables | Supported | Exposed according to SvelteKit’s public-prefix rules |
| Dynamic environment variables | Supported | Resolved from the function environment at runtime |
| Static environment variables | Supported | Inlined during the production build |
| Server instrumentation | Supported | Included when emitted by the adapter |
| Base paths | Supported | Configure through kit.paths.base |
| Trailing-slash behavior | Supported | Controlled by SvelteKit route options |
| WebSockets | Not supported | Function routes use HTTP request-response semantics |
| Persistent local filesystem | Not supported | Function filesystems are ephemeral |
| Scheduled tasks | Not provided by SvelteKit | Use Easel scheduled functions or an external scheduler |
Rendering
SvelteKit lets an application combine static, server-rendered, and client-rendered routes.
Rendering behavior can be configured in:
+page.js+page.server.js+layout.js+layout.server.js+server.js
Settings exported from a layout apply to its descendant routes unless overridden.
Server-side rendering
Pages are server-rendered by default.
A server load function can read private environment variables, access a database, inspect cookies, and return data to the page:
The corresponding page receives the data:
The load function and page render execute in an Easel Function. The rendered HTML is returned to the browser and hydrated according to the application’s SvelteKit configuration.
Prerendering
Routes that do not require request-time data can be generated during the build:
Prerendered pages are deployed as static files and served through the Easel CDN without invoking a function.
You can enable prerendering for a group of routes from a layout:
Child routes can override the inherited value:
Use prerender = "auto" when some known route entries should be generated during the build while other parameter values remain available through server rendering:
Routes fully removed from the dynamic manifest can reduce the size of the application’s server bundle.
Client-side rendering
Disable server rendering for a route when it must run entirely in the browser:
This produces a client-rendered application shell for that route. Browser requests for the route still require the appropriate fallback and routing metadata generated by the adapter.
You can also disable hydration for content that should remain static HTML:
Use these options deliberately. Prefer server rendering when you want better initial HTML, progressive enhancement, and resilience if client-side JavaScript fails to load.
Streaming
SvelteKit server load functions can return promises that resolve after the initial page data.
The page can render the required product information immediately and update when the reviews resolve:
Easel forwards the response as SvelteKit produces it rather than waiting for every streamed promise to settle.
Once a response has started streaming, its status and headers can no longer be changed. Do not attempt to redirect or call setHeaders from inside a promise that resolves after streaming begins.
Streaming load data requires browser JavaScript. Without JavaScript, the browser waits for the complete server-rendered response.
Form actions
SvelteKit form actions execute in the application’s server function.
Use a standard HTML form for progressive enhancement:
The form remains functional without browser JavaScript. With use:enhance, SvelteKit submits the request without a full-page reload and updates the action data in place.
API endpoints
Create HTTP endpoints with +server files:
Endpoint handlers can return any standard Response, including JSON, redirects, files, Server-Sent Events, and streaming bodies.
A streaming endpoint can return a ReadableStream:
Long-lived responses remain subject to the route’s function execution limit. Use a persistent service for indefinite connections.
Hooks
Server hooks run inside the SvelteKit server function.
Use handle to authenticate requests, populate event.locals, modify responses, or bypass normal route handling:
The populated value is available to server load functions, form actions, and endpoints:
Use handleFetch when you need to modify server-side requests made through SvelteKit’s enhanced fetch implementation.
Cookies and sessions
SvelteKit’s cookies API is available in server load functions, actions, endpoints, and hooks:
Cookies are sent through Easel’s request pipeline to the application function and returned through standard Set-Cookie response headers.
Store durable session state in a database or shared session store rather than in function memory.
Cache control
Set cache headers from server load functions with setHeaders:
For endpoint responses, set headers directly:
Easel’s CDN interprets supported HTTP cache directives for eligible responses. See Cache responses at the edge and Invalidate and revalidate cached content.
Do not publicly cache responses containing user-specific data, authentication state, private cookies, or personalized content.
Environment variables
SvelteKit distinguishes private from public variables and static from dynamic variables.
Private variables
Private variables are available only to server-side code:
SvelteKit prevents private environment modules from being imported into browser code.
Public variables
Public variables use the configured public prefix, which is PUBLIC_ by default:
Public values can be included in browser bundles and must not contain secrets.
Static variables
Static variables are replaced during the build:
Changing a static variable requires a new deployment.
Dynamic variables
Dynamic variables are read from the function environment when the application handles a request:
Dynamic access is useful when a value should remain outside the generated server bundle or can vary without being statically imported.
Explicit environment variables
Recent SvelteKit 2 releases allow applications to opt into the explicit environment-variable system planned for SvelteKit 3.
When enabled, variables are declared in src/env.ts and imported through $app/env/private or $app/env/public.
Easel supplies the underlying build-time and runtime environment variables. The SvelteKit version and application configuration determine which framework modules expose them.
Adapter configuration
The Vercel adapter accepts options designed for Vercel’s infrastructure. Not every provider-specific option changes an Easel deployment.
The adapter’s primary purpose on Easel is to generate:
- Server function output
- Static and prerendered assets
- Routing configuration
- Build Output API metadata
Easel project settings remain authoritative for platform resources such as:
- Function memory
- CPU allocation
- Maximum execution duration (framework
maxDurationwhen emitted) - Environment variables
- Scaling limits
Do not rely on adapter memory, duration, or region settings unless the corresponding option is explicitly documented as supported by Easel. Functions run in US East.
Image optimization
Static images imported or referenced by the application deploy normally as client assets.
SvelteKit itself does not prescribe a single runtime image-transformation service. Image behavior depends on the component, preprocessor, or image package used by the application.
Build-time image processing works when it produces ordinary static assets during vite build.
For runtime transformation, use Easel’s image service or another documented image provider. Verify framework-specific image plugins in a preview deployment before relying on them in production.
Base paths
Configure an application mounted below the domain root through kit.paths.base:
Use SvelteKit’s path helpers when generating links and asset URLs so the configured base path is preserved.
Trailing slashes
Configure trailing-slash behavior from a layout or page:
Supported values are:
"never""always""ignore"
The setting also affects paths generated during prerendering.
Service workers
SvelteKit service workers are built as static application assets and deployed through the CDN.
Create one at src/service-worker.js or src/service-worker.ts:
A service worker executes in the visitor’s browser, not inside an Easel Function. Ensure caching rules account for immutable deployment assets and application-version changes.
Project configuration
Easel detects conventional SvelteKit project settings automatically:
| Setting | Default |
|---|---|
| Install command | Detected from the package manager |
| Build command | Package script or vite build |
| Output directory | Read from the adapter output |
| Development command | Package script or vite dev |
| Node.js version | Project or platform default |
For monorepos, set the project root to the directory containing the SvelteKit application’s package.json and svelte.config.js.
The project must include the production adapter in its dependencies and configuration.
Local development
Continue using SvelteKit’s normal development server:
The Vite development server provides SvelteKit routing, server rendering, load functions, actions, hooks, and endpoints locally.
Use an Easel preview deployment to validate behavior that depends on the production platform:
- Production adapter output
- Function packaging
- Streaming through the request pipeline
- CDN caching
- Runtime environment variables
- Function duration and resource limits
- WAF and security rules
- Platform resource limits
Every preview deployment uses the production build path and receives its own immutable URL.
Known limitations
WebSockets
SvelteKit routes deployed to Easel Functions cannot accept long-lived WebSocket connections.
Use an external WebSocket provider or a dedicated persistent service for bidirectional communication.
HTTP streaming and Server-Sent Events are separate from WebSockets, but remain subject to function execution limits.
Persistent local filesystem
The function filesystem is ephemeral.
Files written during an invocation are not guaranteed to exist in a later request or on another function instance. Use object storage, a database, or another durable service for persistent data.
Durable background work
Do not start untracked asynchronous work after returning a response.
Function execution may end once the request lifecycle is complete. Use a queue, scheduled function, or durable background-work system for tasks that require retries or must survive function termination.
Adapter-specific infrastructure settings
The Vercel adapter contains options tied specifically to Vercel’s function products.
Easel consumes the portable deployment output, but does not necessarily reproduce every Vercel-specific control. Configure Easel infrastructure from the Easel project settings unless a particular adapter option is documented as supported.
Runtime image plugins
Build-time image output works as static assets. Runtime image packages may depend on provider-specific APIs and should be tested independently.
Troubleshooting
Easel does not detect the server application
Confirm that @sveltejs/adapter-vercel is installed and selected in svelte.config.js.
Do not rely on adapter-auto for the production deployment.
The deployment contains only static files
Check whether prerender = true is exported from the root layout or inherited by the affected routes.
Routes that are fully prerendered do not remain in the dynamic server manifest.
A route fails during prerendering
A prerendered route cannot depend on request-specific cookies, headers, authentication state, or runtime-only data.
Set prerender = false for the route or move the request-dependent work to a dynamically rendered route.
A dynamic route is missing from the prerendered output
SvelteKit must know which parameter values to generate.
Export an entries function or make the route discoverable through links crawled from another prerendered page.
An environment variable is undefined
Confirm that the variable exists in the current Easel environment.
Also verify that the application uses the correct SvelteKit module:
- Static or dynamic
- Private or public
- Legacy
$envmodules or the explicit$app/envsystem
Static variables require a new deployment after their values change.
A public variable is unavailable in browser code
By default, public environment variables must use the PUBLIC_ prefix.
Variables without the public prefix remain server-only.
A streamed value never appears early
Ensure the promise is returned from a server load function rather than awaited before the function returns.
Also confirm that the surrounding application code and any upstream services do not buffer the complete response.
Headers fail inside streamed data
Headers and status codes cannot change after the response starts.
Set headers before returning the initial load result, and do not redirect from inside a streamed promise.
Cookies are not being set
Confirm that the cookie includes an appropriate path, and verify the secure and sameSite settings for the deployment environment.
Code works locally but fails after deployment
Inspect the production build logs and function logs from a preview deployment.
Common causes include:
- Missing runtime environment variables
- Native packages built for the wrong environment
- Case-sensitive import paths
- Provider-specific adapter options
- Access to persistent local files
- Code that uses browser APIs during server rendering
Compatibility policy
Easel tests its SvelteKit integration against representative applications covering:
- Server-side rendering
- Prerendering
- Server and universal load functions
- Streaming promises
- Form actions
- Hooks
- API endpoints
- Cookies and sessions
- Static and dynamic environment variables
- Base paths
- Redirects
- Error handling
Stable SvelteKit releases may work beyond the version listed at the top of this page, but the listed version is the most recently verified baseline.
For a newly released SvelteKit version, an experimental framework feature, or a provider-specific adapter option, create a preview deployment before upgrading the production application.