Nuxt on Easel
Deploy Nuxt applications to Easel with SSR, streaming, API routes, hybrid rendering, and Nitro route rules.
Easel builds Nuxt with its standard Nitro server engine and deploys the output with no adapter. Public assets and prerendered pages go to the CDN, server rendering and Nitro handlers run in Functions, and route rules choose rendering and caching per path. For how the platform fits together, see How Easel works.
At a glance
| Support level | Production-ready |
| Rendering | Static, client-rendered, SSR, streaming, and hybrid |
| Server runtime | Node.js |
| Server engine | Nitro |
| Adapter required | No |
| Automatic detection | Yes |
| Most recently tested with | Nuxt 3.15.x |
Deploy a Nuxt application
Easel detects Nuxt projects automatically. You can deploy an existing application without changing its Nuxt configuration.
Create a project and connect the Git repository, or deploy with the CLI:
Easel installs dependencies with the detected package manager, runs
nuxt build, and provisions what the Nitro output needs. You can override the
install command, build command, root directory, and Node.js version in
build configuration.
Don't set a Nitro preset
Easel selects the compatible Nitro output when it runs the build. Setting
nitro.preset, NITRO_PRESET, or SERVER_PRESET yourself can produce output
for another platform. Other Nitro options, including route rules, plugins,
prerender settings, storage, and server assets, work as usual.
What Easel deploys
During the production build, Nitro turns the application into a server entry, route metadata, prerendered pages, and public assets.
| Nuxt output | Easel resource |
|---|---|
Files in public/ | CDN assets |
| Nuxt client bundles | CDN assets |
| Prerendered pages | CDN assets |
| Server-rendered pages | Easel Functions |
Routes in server/api/ | Easel Functions |
Routes in server/routes/ | Easel Functions |
| Server middleware | Application function |
| Nitro plugins | Application function |
isr and swr routes | CDN, regenerated by Functions |
| Redirects and headers | Request-routing configuration |
Supported features
| Feature | Support | Notes |
|---|---|---|
| Nuxt pages and layouts | Supported | Includes file-based routing, nested layouts, and error pages |
| Server-side rendering | Supported | Dynamic pages run in Easel Functions |
| Client-side rendering | Supported | Includes applications configured with ssr: false |
| Static generation | Supported | Generated output is deployed to the CDN |
| Hybrid rendering | Supported | Controlled through route rules |
| Streaming responses | Supported | Nitro and h3 response streams are forwarded incrementally |
| Server API routes | Supported | Includes handlers in server/api/ |
| Server routes | Supported | Includes handlers in server/routes/ |
| Server middleware | Supported | Runs inside the application function |
| Nitro plugins | Supported | Run when a Function instance starts |
| Prerendering | Supported | Includes link crawling and explicit prerender routes |
| Route redirects and headers | Supported | Includes rules configured through route rules |
| ISR and SWR route rules | Supported | Cached on the CDN and regenerated after expiration |
| Cached handlers | Partial | Nitro's cache storage is per instance unless you mount an external driver |
| Runtime configuration | Supported | Server and public runtime configuration are available |
| Cookies and sessions | Supported | Standard Nitro and h3 cookie APIs are available |
| Server-Sent Events | Supported | Subject to function limits |
@nuxt/image | Partial | Static assets work. Dynamic provider compatibility depends on the provider |
| Nitro storage | Partial | Memory and external drivers work. Local persistent storage doesn't |
| Scheduled tasks | Not supported | Call an authenticated route from an external scheduler |
| WebSockets | Not supported | Easel Functions don't accept long-lived WebSocket upgrades |
Rendering modes
Nuxt renders pages on the server by default. Routes that need request-time execution run through the Nitro server entry in a Function, and response streams are forwarded as Nitro produces them.
Set ssr: false in nuxt.config.ts for a client-rendered application. Easel
deploys the generated assets to the CDN and falls back to the entry page for
application routes. Server routes in the Nitro build still deploy as Functions.
nuxt generate prerenders the whole application into .output/public and
Easel deploys it straight to the CDN. A generated deployment has no server
rendering or server routes. Use nuxt build when you need them.
Route rules
Route rules choose rendering, caching, redirects, and headers per path:
prerenderrenders the route during the build and deploys it to the CDN.ssr: falserenders the route in the browser.israndswrdeploy the route as incrementally regenerated output. Easel caches it on the CDN, serves the cached copy, and regenerates it in a Function after the interval. See revalidation.redirectandheadersbecome request-routing configuration.
Test combinations of route rules, and experimental Nitro options, in a preview deployment.
Server routes and middleware
Handlers under server/api and server/routes are bundled into the Nitro
application and run in Functions:
Server middleware in server/middleware runs inside the application Function
before the matching route or page render. Logic that should run before a
Function is invoked, such as blocking traffic, belongs in the
Firewall instead.
Nitro plugins
Nitro plugins run each time Easel starts a new Function instance, not once per deployment. Connections and in-memory state a plugin creates belong to that instance and aren't shared.
Runtime configuration
Define private and public keys in nuxt.config.ts, then set their values with
NUXT_-prefixed environment variables:
Private keys are available only to server code through useRuntimeConfig().
Keys under public are exposed to the browser, so don't put secrets there. See
environment variables for scopes and
how changes apply.
Prerendering
Configure Nitro's prerenderer in nuxt.config.ts:
Prerendered routes deploy as CDN assets. The crawler only finds routes linked
from another prerendered page, so list other dynamic routes explicitly or push
them from the nitro:config hook. Data sources used at build time must be
reachable from Easel's build environment.
Caching and storage
defineCachedEventHandler, defineCachedFunction, and cache route rules
without swr use Nitro's cache storage. By default that's memory in one
Function instance, so entries aren't shared and disappear when the instance
stops. The same applies to useStorage() with the memory or filesystem driver.
Mount an external driver for anything that must be shared or durable:
For responses the CDN can cache, prefer isr or swr route rules, or set
Cache-Control as described in CDN caching. Reading files
bundled with serverAssets through useStorage("assets:server") works.
Images
Files in public/ deploy to the CDN. @nuxt/image compatibility depends on the
provider. Providers that return external image URLs work. Providers that need a
local image server or provider-specific runtime behavior need testing in a
preview deployment.
Scheduled tasks
Nitro scheduled tasks aren't registered as Easel schedules. Expose the work as an authenticated server route and call it from an external scheduler:
Make the handler idempotent.
Project configuration
| Setting | Default |
|---|---|
| Install command | Detected from the package manager |
| Build command | Package script or nuxt build |
| Output directory | Detected from Nitro output |
| Development command | Package script or nuxt dev |
| Node.js version | Project or platform default |
In a monorepo, set the root directory to the folder containing the Nuxt
application's package.json and nuxt.config. See
monorepos.
Keep using nuxt dev locally, and use a
preview deployment to check production Nitro output,
route rules, and caching.
Known limitations
- WebSockets. Nitro WebSocket handlers don't work on Functions. See Functions runtime.
- Provider-specific Nitro features. Features built for another Nitro deployment provider may behave differently on Easel.
- Experimental features. Experimental Nuxt and Nitro features can change their deployment output. Validate them in a preview first.
Troubleshooting
Easel can't find the server entry
Check that the build runs nuxt build and that no custom command moves or
replaces .output. Remove NITRO_PRESET, SERVER_PRESET, or nitro.preset.
The project deploys without server rendering
Check that the build command is nuxt build, not nuxt generate, and that
ssr: false isn't set globally or for the route.
A route rule doesn't apply
Check that the pattern matches the deployed URL and that a more specific rule
doesn't override it. Inline route rules need the experimental option your Nuxt
version requires. Otherwise, define the rule in nuxt.config.
A runtime config value is empty
Use the NUXT_-prefixed name that matches the key, such as
NUXT_PUBLIC_API_ORIGIN for runtimeConfig.public.apiOrigin.
A cached handler returns different results per request
Nitro's default cache storage is per instance. Mount a shared driver for
cache, or use an isr or swr route rule.
Compatibility policy
Easel tests this guide against the version in At a glance. Test new Nuxt and Nitro releases, modules, and image providers in a preview deployment first. See the compatibility policy.