Vue
Vue is pure Vite — the entire app builds from
@vitejs/plugin-vue in your vite.config.ts, so
Cloudflare.Website.Vite
deploys it with a single declaration: no main entrypoint, no
build command, no output directory, no Wrangler configuration.
Configure Vite
Section titled “Configure Vite”Your Vite config stays exactly what Vue’s scaffold gives you:
import { defineConfig } from "vite";import vue from "@vitejs/plugin-vue";
export default defineConfig({ plugins: [vue()],});Alchemy runs Vite programmatically on the project root and layers its Cloudflare integration on top of this config — your plugins, aliases, and the rest of your setup are preserved as-is.
Declare the Website
Section titled “Declare the Website”Declare the site as a module-level const (rather than inline in the Stack) — every prop is optional, so the minimal declaration is just a name:
import * as Cloudflare from "alchemy/Cloudflare";
export const Website = Cloudflare.Website.Vite("Vue");Add it to the Stack
Section titled “Add it to the Stack”Yield the class from your Stack and return its URL — see examples/cloudflare-vue for the checked-in example:
import * as Alchemy from "alchemy";import * as Effect from "effect/Effect";
export default Alchemy.Stack( "CloudflareVueExample", { providers: Cloudflare.providers(), state: Cloudflare.state(), }, Effect.gen(function* () { const worker = yield* Website;
return { url: worker.url, }; }),);Alchemy builds the client assets and serves them from a Worker at
the returned url.
Deep links with vue-router
Section titled “Deep links with vue-router”If your app uses vue-router in history mode
(createWebHistory), a deep link like /about arrives at the
server as a request for a file that doesn’t exist. Configure the
asset layer to fall back to index.html:
export const Website = Cloudflare.Website.Vite("Vue", { assets: { htmlHandling: "auto-trailing-slash", notFoundHandling: "single-page-application", },});With notFoundHandling: "single-page-application", unmatched
paths return index.html instead of a 404, and vue-router
resolves the route on the client.
Add environment variables
Section titled “Add environment variables”A pure SPA has no server, so anything it needs from the rest of
your Stack is baked into the bundle at build time — pass a
VITE_-prefixed key in env:
export const Website = Cloudflare.Website.Vite("Vue", { env: { VITE_API_URL: backend.url, },});Type it for your Vue code with Vite’s standard ImportMetaEnv
augmentation:
/// <reference types="vite/client" />
interface ImportMetaEnv { readonly VITE_API_URL: string;}Client code reads it as import.meta.env.VITE_API_URL. See
Environment for the full
inlining semantics.
Because a SPA ships no server code, there are no runtime bindings to
type with Cloudflare.InferEnv — when you add server routes (via an
SSR framework like TanStack Start
or a separate Worker), that’s where
InferEnv comes in.