Vite on Easel
Deploy Vite applications to Easel as globally cached static sites and single-page applications.
Easel deploys client-side applications built with Vite, including React, Vue, Preact, Solid, and Svelte, as static files on the CDN. Page requests don't invoke a function. Frameworks that use Vite for server rendering, such as SvelteKit, Nuxt, React Router, and TanStack Start, have their own framework guides.
At a glance
| Support level | Production-ready |
| Rendering | Static and client-side rendered |
| Server runtime | None |
| Adapter required | No |
| Automatic detection | Yes |
| Default output directory | dist |
| Most recently tested with | Vite 7.x |
Deploy a Vite application
Easel detects Vite projects automatically. Create a project from your Git repository or deploy with the CLI:
Easel installs dependencies, runs your build script or vite build, and
uploads dist to the CDN. Install command, build command, root directory,
output directory, and Node.js version live in
build configuration.
What Easel deploys
| Vite output | Easel resource |
|---|---|
| HTML entry points | CDN assets |
| JavaScript and CSS bundles | Immutable CDN assets |
| Imported images and fonts | Immutable CDN assets |
Files from public | CDN assets |
| Client-side routes | CDN rewrite to index.html |
Vite's content-hashed bundles can be cached long-term. Files in public keep
their names, so rename one when it must change immediately. See
Static files for how the CDN caches each kind.
Supported features
| Capability | Support | Notes |
|---|---|---|
| Static sites | Supported | Served from the Easel CDN |
| Single-page applications | Supported with configuration | Needs a fallback rewrite to index.html |
| Multipage sites | Supported | Each HTML entry is served at its path |
| React, Vue, Preact, Solid, Svelte | Supported | Standard Vite templates |
| TypeScript and CSS modules | Supported | Compiled during the build |
| Custom base paths | Supported | Vite's base option |
| Custom output directory | Supported | Match build.outDir in Easel settings |
| Client environment variables | Supported | Must use the VITE_ prefix |
| Redirects, rewrites, headers | Supported | Defined in vercel.json |
| Monorepos | Supported | Set the root directory |
| Server rendering, API routes | Not provided by plain Vite | Use a full-stack framework |
Single-page applications
A client-side router renders routes like /account/settings from one
index.html. When a visitor opens that URL directly, there's no file at that
path, so add a fallback rewrite in vercel.json at the project root:
The browser URL doesn't change, so the router renders the requested route. Easel checks for a matching static file before applying the rewrite, so JavaScript, CSS, and image requests still resolve to their files.
This works with React Router in declarative or data mode, Vue Router, TanStack Router, Solid Router, and other client routers. React Router framework mode has a server build. Use the React Router guide for it.
Hash-based routing doesn't need a rewrite, because the fragment never reaches the server.
Multipage sites
Vite can build several HTML entry points:
Easel serves dist/about/index.html at /about/. Don't add an SPA fallback
when each route has its own HTML file.
Environment variables
Vite exposes only variables prefixed with VITE_ to your code, through
import.meta.env:
Vite inlines these values into the browser bundle at build time. That means:
- Anyone can read them in the downloaded JavaScript. Never put secrets in a
VITE_variable. - A changed value needs a new deployment.
- Preview and production can call different backends when you give
VITE_API_ORIGINa separate value in each environment.
Set values per environment in Environment variables.
Base paths
Vite assumes the app is served from /. For an app at
https://example.com/dashboard/, set base:
Vite prefixes JavaScript, CSS, and asset URLs with that path. If base
doesn't match where the app is served, the HTML loads but its scripts and
styles return 404.
Output directory
Vite writes to dist by default. If you change build.outDir, set the same
directory as the output directory in Easel. If they differ, the build succeeds
but Easel finds nothing to deploy.
Source maps
Vite doesn't emit production source maps unless you set build.sourcemap: true. When it does, Easel serves them publicly like any other file. Upload
them to your error-monitoring provider instead if you don't want to expose
your source.
Redirects, rewrites, and headers
Vite doesn't define production routing. Add redirects, rewrites, and custom
response headers in vercel.json. See
Redirects and rewrites and
Headers.
Server-side code
A plain Vite app has no server. Code that imports Node.js modules such as
node:fs, or that needs a secret to call a protected API, belongs in a
full-stack framework or a separate backend. Don't ship private credentials in
the browser bundle.
Monorepos
Set the root directory to the folder that holds the app's package.json and
vite.config.ts, such as apps/dashboard. Easel keeps access to workspace
dependencies. See Monorepos.
Local development
Keep using npm run dev. Use a preview deployment to
check the SPA fallback, base path, headers, and caching. Don't run
vite preview as a production server. It only previews the build locally.
Known limitations
- No server runtime. Node.js APIs and server-only modules can't run.
- Public variables only. The
VITE_prefix controls browser exposure. It isn't secret storage. - History routing needs a rewrite. Without one, direct visits to client
routes return
404.
Troubleshooting
The build succeeds, but Easel can't find the output
Make the Easel output directory match Vite's build.outDir. Both default to
dist.
A client-side route returns 404
Add the SPA fallback rewrite. Skip it on multipage sites.
The page loads without JavaScript or styles
Check the network panel for asset requests returning 404. The usual cause is
a base that doesn't match the deployment path.
An environment variable is undefined or stale
Confirm the name starts with VITE_, that it's set for the current
environment, and that you redeployed after adding or changing it.
An import works locally but fails during deployment
The build environment is case-sensitive. Make import casing match the
filename exactly, and declare the dependency in the app's package.json.
Compatibility policy
Easel's Vite baseline is the version under At a glance. Build plugins that only transform output work without platform support. Plugins that expect a persistent server or specific hosting runtime need a full-stack framework. See the compatibility policy.