diff --git a/src/content/docs/workers/vite-plugin/get-started.mdx b/src/content/docs/workers/vite-plugin/get-started.mdx new file mode 100644 index 000000000000000..503d61958706f4b --- /dev/null +++ b/src/content/docs/workers/vite-plugin/get-started.mdx @@ -0,0 +1,88 @@ +--- +pcx_content_type: get-started +title: Get started +sidebar: + order: 1 +description: Get started with the Vite plugin +--- + +import { PackageManagers, WranglerConfig } from "~/components"; + +:::note +This guide demonstrates creating a standalone Worker from scratch. +{/* Add link to React Router framework guide */}If you would instead like to create a new application from a ready-to-go template, refer to the [React](/workers/frameworks/framework-guides/react/) or [Vue](/workers/frameworks/framework-guides/vue/) framework guides. +::: + +## Start with a basic `package.json` + +```json title="package.json" +{ + "name": "cloudflare-vite-get-started", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "npm run build && vite preview", + "deploy": "npm run build && wrangler deploy" + } +} +``` + +:::note +Ensure that you include `"type": "module"` in order to use ES modules by default. +::: + +## Install the dependencies + + + +## Create your Vite config file and include the Cloudflare plugin + +```ts title="vite.config.ts" +import { defineConfig } from "vite"; +import { cloudflare } from "@cloudflare/vite-plugin"; + +export default defineConfig({ + plugins: [cloudflare()], +}); +``` + +The Cloudflare Vite plugin doesn't require any configuration by default and will look for a `wrangler.jsonc`, `wrangler.json` or `wrangler.toml` in the root of your application. + +Refer to the [API reference](/workers/vite-plugin/reference/api/) for configuration options. + +## Create your Worker config file + + + +```toml +name = "cloudflare-vite-get-started" +compatibility_date = "2025-04-03" +main = "./src/index.ts" +``` + + + +The `name` field specifies the name of your Worker. +By default, this is also used as the name of the Worker's Vite Environment (see [Vite Environments](/workers/vite-plugin/reference/vite-environments/) for more information). +The `main` field specifies the entry file for your Worker code. + +For more information about the Worker configuration, see [Configuration](/workers/wrangler/configuration/). + +## Create your Worker entry file + +```ts title="src/index.ts" +export default { + fetch() { + return new Response(`Running in ${navigator.userAgent}!`); + }, +}; +``` + +A request to this Worker will return 'Running in Cloudflare-Workers!', demonstrating that the code is running inside the Workers runtime. + +## Dev, build, preview and deploy + +You can now start the Vite development server (`npm run dev`), build the application (`npm run build`), preview the built application (`npm run preview`), and deploy to Cloudflare (`npm run deploy`). diff --git a/src/content/docs/workers/vite-plugin/index.mdx b/src/content/docs/workers/vite-plugin/index.mdx new file mode 100644 index 000000000000000..b6ac97e86b25fcc --- /dev/null +++ b/src/content/docs/workers/vite-plugin/index.mdx @@ -0,0 +1,34 @@ +--- +pcx_content_type: overview +title: Vite plugin +sidebar: + order: 16 +description: A full-featured integration between Vite and the Workers runtime +--- + +The Cloudflare Vite plugin enables a full-featured integration between [Vite](https://vite.dev/) and the [Workers runtime](/workers/runtime-apis/). +Your Worker code runs inside [workerd](https://github.com/cloudflare/workerd), matching the production behavior as closely as possible and providing confidence as you develop and deploy your applications. + +### Features + +- Uses the Vite [Environment API](https://vite.dev/guide/api-environment) to integrate Vite with the Workers runtime +- Provides direct access to [Workers runtime APIs](/workers/runtime-apis/) and [bindings](/workers/runtime-apis/bindings/) +- Builds your front-end assets for deployment to Cloudflare, enabling you to build static sites, SPAs, and full-stack applications +- Official support for [React Router v7](https://reactrouter.com/) with server-side rendering +- Leverages Vite's hot module replacement for consistently fast updates +- Supports `vite preview` for previewing your build output in the Workers runtime prior to deployment + +### Use cases + +- React Router v7 (support for more full-stack frameworks is coming soon) +- Static sites, such as single-page applications, with or without an integrated backend API +- Standalone Workers +- Multi-Worker applications + +### Get started + +{/* Add link to React Router framework guide */}To create a new application from a ready-to-go template, refer to the [React](/workers/frameworks/framework-guides/react/) or [Vue](/workers/frameworks/framework-guides/vue/) framework guides. + +To create a standalone Worker from scratch, refer to [Get started](/workers/vite-plugin/get-started/). + +For a more in-depth look at adapting an existing Vite project and an introduction to key concepts, refer to the [Tutorial](/workers/vite-plugin/tutorial/). diff --git a/src/content/docs/workers/vite-plugin/reference/api.mdx b/src/content/docs/workers/vite-plugin/reference/api.mdx new file mode 100644 index 000000000000000..ba36430c6b75457 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/reference/api.mdx @@ -0,0 +1,86 @@ +--- +pcx_content_type: reference +title: API +sidebar: + order: 3 +description: Vite plugin API +--- + +import { Type, MetaInfo } from "~/components"; + +## `cloudflare()` + +The `cloudflare` plugin should be included in the Vite `plugins` array: + +```ts {2, 5} title="vite.config.ts" +import { defineConfig } from "vite"; +import { cloudflare } from "@cloudflare/vite-plugin"; + +export default defineConfig({ + plugins: [cloudflare()], +}); +``` + +It accepts an optional `PluginConfig` parameter. + +## `interface PluginConfig` + +- `configPath` + + An optional path to your Worker config file. + By default, a `wrangler.jsonc`, `wrangler.json`, or `wrangler.toml` file in the root of your application will be used as the Worker config. + + For more information about the Worker configuration, see [Configuration](/workers/wrangler/configuration/). + +- `viteEnvironment` + + Optional Vite environment options. + By default, the environment name is the Worker name with `-` characters replaced with `_`. + Setting the name here will override this. + A typical use case is setting `viteEnvironment: { name: "ssr" }` to apply the Worker to the SSR environment. + + See [Vite Environments](/workers/vite-plugin/reference/vite-environments/) for more information. + +- `persistState` + + An optional override for state persistence. + By default, state is persisted to `.wrangler/state`. + A custom `path` can be provided or, alternatively, persistence can be disabled by setting the value to `false`. + +- `inspectorPort` + + An optional override for debugging your Workers. + By default, the debugging inspector is enabled and listens on port `9229`. + A custom port can be provided or, alternatively, setting this to `false` will disable the debugging inspector. + + See [Debugging](/workers/vite-plugin/reference/debugging/) for more information. + +- `auxiliaryWorkers` + + An optional array of auxiliary Workers. + Auxiliary Workers are additional Workers that are used as part of your application. + You can use [service bindings](/workers/runtime-apis/bindings/service-bindings/) to call auxiliary Workers from your main (entry) Worker. + All requests are routed through your entry Worker. + During the build, each Worker is output to a separate subdirectory of `dist`. + +:::note +When running `wrangler deploy`, only your main (entry) Worker will be deployed. +If using multiple Workers, each auxiliary Worker must be deployed individually. +You can inspect the `dist` directory and then run `wrangler deploy -c dist//wrangler.json` for each. +::: + +## `interface AuxiliaryWorkerConfig` + +- `configPath` + + A required path to your Worker config file. + + For more information about the Worker configuration, see [Configuration](/workers/wrangler/configuration/). + +- `viteEnvironment` + + Optional Vite environment options. + By default, the environment name is the Worker name with `-` characters replaced with `_`. + Setting the name here will override this. + + See [Vite Environments](/workers/vite-plugin/reference/vite-environments/) for more information. diff --git a/src/content/docs/workers/vite-plugin/reference/cloudflare-environments.mdx b/src/content/docs/workers/vite-plugin/reference/cloudflare-environments.mdx new file mode 100644 index 000000000000000..8eadb3b08df7609 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/reference/cloudflare-environments.mdx @@ -0,0 +1,109 @@ +--- +pcx_content_type: reference +title: Cloudflare Environments +sidebar: + order: 9 +description: Using Cloudflare environments with the Vite plugin +--- + +import { PackageManagers, WranglerConfig } from "~/components"; + +A Worker config file may contain configuration for multiple [Cloudflare environments](/workers/wrangler/environments/). +With the Cloudflare Vite plugin, you select a Cloudflare environment at dev or build time by providing the `CLOUDFLARE_ENV` environment variable. +Consider the following example Worker config file: + + + +```toml +name = "my-worker" +compatibility_date = "2025-04-03" +main = "./src/index.ts" + +vars = { MY_VAR = "Top-level var" } + +[env.staging] +vars = { MY_VAR = "Staging var" } + +[env.production] +vars = { MY_VAR = "Production var" } +``` + + + +If you run `CLOUDFLARE_ENV=production vite build` then the output `wrangler.json` file generated by the build will be a flattened configuration for the 'production' Cloudflare environment, as shown in the following example: + +```json title=wrangler.json +{ + "name": "my-worker", + "compatibility_date": "2025-04-03", + "main": "index.js", + "vars": { "MY_VAR": "Production var" } +} +``` + +Notice that the value of `MY_VAR` is `Production var`. +This flattened configuration combines [top-level only](/workers/wrangler/configuration/#top-level-only-keys), [inheritable](/workers/wrangler/configuration/#inheritable-keys), and [non-inheritable](/workers/wrangler/configuration/#non-inheritable-keys) keys. + +:::note +The default Vite environment name for a Worker is always the top-level Worker name. +This enables you to reference the Worker consistently in your Vite config when using multiple Cloudflare environments. +See [Vite Environments](/workers/vite-plugin/reference/vite-environments/) for more information. +::: + +Cloudflare environments can also be used in development. +For example, you could run `CLOUDFLARE_ENV=development vite dev`. +It is common to use the default top-level environment as the development environment and then add additional environments as necessary. + +:::note +Running `vite dev` or `vite build` without providing `CLOUDFLARE_ENV` will use the default top-level Cloudflare environment. +As Cloudflare environments are applied at dev and build time, specifying `CLOUDFLARE_ENV` when running `vite preview` or `wrangler deploy` will have no effect. +::: + +## Combining Cloudflare environments and Vite modes + +You may wish to combine the concepts of [Cloudflare environments](/workers/wrangler/environments/) and [Vite modes](https://vite.dev/guide/env-and-mode.html#modes). +With this approach, the Vite mode can be used to select the Cloudflare environment and a single method can be used to determine environment specific configuration and code. +Consider again the previous example: + + + +```toml +# wrangler.toml + +name = "my-worker" +compatibility_date = "2025-04-03" +main = "./src/index.ts" + +vars = { MY_VAR = "Top-level var" } + +[env.staging] +vars = { MY_VAR = "Staging var" } + +[env.production] +vars = { MY_VAR = "Production var" } +``` + + + +Next, provide `.env.staging` and `.env.production` files: + +```sh +# .env.staging + +CLOUDFLARE_ENV=staging +``` + +```sh +# .env.production + +CLOUDFLARE_ENV=production +``` + +By default, `vite build` uses the 'production' Vite mode. +Vite will therefore load the `.env.production` file to get the environment variables that are used in the build. +Since the `.env.production` file contains `CLOUDFLARE_ENV=production`, the Cloudflare Vite plugin will select the 'production' Cloudflare environment. +The value of `MY_VAR` will therefore be `'Production var'`. +If you run `vite build --mode staging` then the 'staging' Vite mode will be used and the 'staging' Cloudflare environment will be selected. +The value of `MY_VAR` will therefore be `'Staging var'`. + +For more information about using `.env` files with Vite, see the [relevant documentation](https://vite.dev/guide/env-and-mode#env-files). diff --git a/src/content/docs/workers/vite-plugin/reference/debugging.mdx b/src/content/docs/workers/vite-plugin/reference/debugging.mdx new file mode 100644 index 000000000000000..8070aea38a111fd --- /dev/null +++ b/src/content/docs/workers/vite-plugin/reference/debugging.mdx @@ -0,0 +1,59 @@ +--- +pcx_content_type: reference +title: Debugging +sidebar: + order: 5 +description: Debugging with the Vite plugin +--- + +The Cloudflare Vite plugin has debugging enabled by default and listens on port `9229`. +You may choose a custom port or disable debugging by setting the `inspectorPort` option in the [plugin config](/workers/vite-plugin/reference/api#interface-pluginconfig). +There are two recommended methods for debugging your Workers during local development: + +## DevTools + +When running `vite dev` or `vite preview`, a `/__debug` route is added that provides access to [Cloudflare's implementation](https://github.com/cloudflare/workers-sdk/tree/main/packages/chrome-devtools-patches) of [Chrome's DevTools](https://developer.chrome.com/docs/devtools/overview). +Navigating to this route will open a DevTools tab for each of the Workers in your application. + +Once the tab(s) are open, you can make a request to your application and start debugging your Worker code. + +:::note +When debugging multiple Workers, you may need to allow your browser to open pop-ups. +::: + +## VS Code + +To set up [VS Code](https://code.visualstudio.com/) to support breakpoint debugging in your application, you should create a `.vscode/launch.json` file that contains the following configuration: + +```json title=".vscode/launch.json" +{ + "configurations": [ + { + "name": "", + "type": "node", + "request": "attach", + "websocketAddress": "ws://localhost:9229/", + "resolveSourceMapLocations": null, + "attachExistingChildren": false, + "autoAttachChildProcesses": false, + "sourceMaps": true + } + ], + "compounds": [ + { + "name": "Debug Workers", + "configurations": [""], + "stopAll": true + } + ] +} +``` + +Here, `` indicates the name of the Worker as specified in your Worker config file. +If you have used the `inspectorPort` option to set a custom port then this should be the value provided in the `websocketaddress` field. + +:::note +If you have more than one Worker in your application, you should add a configuration in the `configurations` field for each and include the configuration name in the `compounds` `configurations` array. +::: + +With this set up, you can run `vite dev` or `vite preview` and then select **Debug Workers** at the top of the **Run & Debug** panel to start debugging. diff --git a/src/content/docs/workers/vite-plugin/reference/index.mdx b/src/content/docs/workers/vite-plugin/reference/index.mdx new file mode 100644 index 000000000000000..35717a7ba245dd2 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/reference/index.mdx @@ -0,0 +1,12 @@ +--- +pcx_content_type: navigation +title: Reference +sidebar: + order: 5 + group: + hideIndex: true +--- + +import { DirectoryListing } from "~/components"; + + diff --git a/src/content/docs/workers/vite-plugin/reference/migrating-from-wrangler-dev.mdx b/src/content/docs/workers/vite-plugin/reference/migrating-from-wrangler-dev.mdx new file mode 100644 index 000000000000000..851391bc27c2ce9 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/reference/migrating-from-wrangler-dev.mdx @@ -0,0 +1,34 @@ +--- +pcx_content_type: reference +title: Migrating from wrangler dev +sidebar: + order: 6 +description: Migrating from wrangler dev to the Vite plugin +--- + +In most cases, migrating from [`wrangler dev`](/workers/wrangler/commands/#dev) is straightforward and you can follow the instructions in [Get started](/workers/vite-plugin/get-started/). +There are a few key differences to highlight: + +## Input and output Worker config files + +With the Cloudflare Vite plugin, your [Worker config file](/workers/wrangler/configuration/) (for example, `wrangler.jsonc`) is the input configuration and a separate output configuration is created as part of the build. +This output file is a snapshot of your configuration at the time of the build and is modified to reference your build artifacts. +It is the configuration that is used for preview and deployment. +Once you have run `vite build`, running `wrangler deploy` or `vite preview` will automatically locate this output configuration file. + +## Cloudflare Environments + +With the Cloudflare Vite plugin, [Cloudflare Environments](/workers/vite-plugin/reference/cloudflare-environments/) are applied at dev and build time. +Running `wrangler deploy --env some-env` is therefore not applicable and the environment to deploy should instead be set by running `CLOUDFLARE_ENV=some-env vite build`. + +## Redundant fields in the Wrangler config file + +There are various options in the [Worker config file](/workers/wrangler/configuration/) that are ignored when using Vite, as they are either no longer applicable or are replaced by Vite equivalents. +If these options are provided, then warnings will be printed to the console with suggestions for how to proceed. +Examples where the Vite configuration should be used instead include `alias` and `define`. +See [Vite Environments](/workers/vite-plugin/reference/vite-environments/) for more information about configuring your Worker environments in Vite. + +## No remote mode + +The Vite plugin does not support [remote mode](/workers/local-development/#develop-using-remote-resources-and-bindings). +We will be adding support for accessing remote resources in local development in a future update. diff --git a/src/content/docs/workers/vite-plugin/reference/secrets.mdx b/src/content/docs/workers/vite-plugin/reference/secrets.mdx new file mode 100644 index 000000000000000..3a6b79d57701c57 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/reference/secrets.mdx @@ -0,0 +1,21 @@ +--- +pcx_content_type: reference +title: Secrets +sidebar: + order: 7 +description: Using secrets with the Vite plugin +--- + +import { PackageManagers, WranglerConfig } from "~/components"; + +[Secrets](/workers/configuration/secrets/) are typically used for storing sensitive information such as API keys and auth tokens. +For deployed Workers, they are set via the dashboard or Wrangler CLI. + +In local development, secrets can be provided to your Worker by using a [`.dev.vars`](/workers/configuration/secrets/#local-development-with-secrets) file. +If you are using [Cloudflare Environments](/workers/vite-plugin/reference/cloudflare-environments/) then the relevant `.dev.vars` file will be selected. +For example, `CLOUDFLARE_ENV=staging vite dev` will load `.dev.vars.staging` if it exists and fall back to `.dev.vars`. + +:::note +The `vite build` command copies the relevant `.dev.vars` file to the output directory. +This is only used when running `vite preview` and is not deployed with your Worker. +::: diff --git a/src/content/docs/workers/vite-plugin/reference/static-assets.mdx b/src/content/docs/workers/vite-plugin/reference/static-assets.mdx new file mode 100644 index 000000000000000..3bd9c1fcdd708b8 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/reference/static-assets.mdx @@ -0,0 +1,39 @@ +--- +pcx_content_type: reference +title: Static Assets +sidebar: + order: 4 +description: Static assets and the Vite plugin +--- + +import { WranglerConfig } from "~/components"; + +The Vite plugin does not require that you provide the `assets` field in order to enable assets and instead determines whether assets should be included based on whether the `client` environment has been built. +By default, the `client` environment is built if there is an `index.html` file in the root of your project or if `build.rollupOptions.input` is specified in the Vite config. + +:::note +When using the Cloudflare Vite plugin, the `client` environment is deployed as your static assets. +This typically includes files such as static HTML, front-end JavaScript, CSS, images and fonts. +For more information about using static assets in Vite, refer to [Static Asset Handling](https://vite.dev/guide/assets). +::: + +On running `vite build`, an output `wrangler.json` configuration file is generated as part of the build output. +The `assets.directory` field in this file is automatically populated with the path to your `client` build output. +It is therefore not necessary to provide the `assets.directory` field in your input Worker configuration. + +The `assets` configuration should be used, however, if you wish to set [routing configuration](/workers/static-assets/routing/#routing-configuration) or enable the [assets binding](/workers/static-assets/binding/#binding). +The following example configures the `not_found_handling` for a single-page application so that the fallback will always be the root `index.html` file. + + + +```toml +assets = { not_found_handling = "single-page-application" } +``` + + + +{/* Add docs for _headers and _redirects */} + +:::note +The Cloudflare Vite plugin does not support [run_worker_first](/workers/static-assets/binding/#run_worker_first). +::: diff --git a/src/content/docs/workers/vite-plugin/reference/vite-environments.mdx b/src/content/docs/workers/vite-plugin/reference/vite-environments.mdx new file mode 100644 index 000000000000000..5f5a5c0a2140a48 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/reference/vite-environments.mdx @@ -0,0 +1,78 @@ +--- +pcx_content_type: reference +title: Vite Environments +sidebar: + order: 8 +description: Vite environments and the Vite plugin +--- + +import { WranglerConfig } from "~/components"; + +The [Vite Environment API](https://vite.dev/guide/api-environment), released in Vite 6, is the key feature that enables the Cloudflare Vite plugin to integrate Vite directly with the Workers runtime. +It is not necessary to understand all the intricacies of the Environment API as an end user, but it is useful to have a high-level understanding. + +## Default behavior + +Vite creates two environments by default: `client` and `ssr`. +A front-end only application uses the `client` environment, whereas a full-stack application created with a framework typically uses the `client` environment for front-end code and the `ssr` environment for server-side rendering. + +By default, when you add a Worker using the Cloudflare Vite plugin, an additional environment is created. +Its name is derived from the Worker name, with any dashes replaced with underscores. +This name can be used to reference the environment in your Vite config in order to apply environment specific configuration. + +:::note +The default Vite environment name for a Worker is always the top-level Worker name. +This enables you to reference the Worker consistently in your Vite config when using multiple [Cloudflare Environments](/workers/vite-plugin/reference/cloudflare-environments/). +::: + +## Environment configuration + +In the following example we have a Worker named `my-worker` that is associated with a Vite environment named `my_worker`. +We use the Vite config to set global constant replacements for this environment: + + + +```toml +name = "my-worker" +compatibility_date = "2025-04-03" +main = "./src/index.ts" +``` + + + +```ts title="vite.config.ts" +import { defineConfig } from "vite"; +import { cloudflare } from "@cloudflare/vite-plugin"; + +export default defineConfig({ + environments: { + my_worker: { + define: { + __APP_VERSION__: JSON.stringify("v1.0.0"), + }, + }, + }, + plugins: [cloudflare()], +}); +``` + +For more information about Vite's configuration options, see [Configuring Vite](https://vite.dev/config/). + +The default behavior of using the Worker name as the environment name is appropriate when you have a standalone Worker, such as an API that is accessed from your front-end application, or an [auxiliary Worker](/workers/vite-plugin/reference/api/#interface-pluginconfig) that is accessed via service bindings. + +## React Router v7 + +If you are using the Cloudflare Vite plugin with [React Router v7](https://reactrouter.com/), then your Worker is used for server-side rendering and tightly integrated with the framework. +To support this, you should assign it to the `ssr` environment by setting `viteEnvironment.name` in the plugin config. + +```ts title="vite.config.ts" +import { defineConfig } from "vite"; +import { cloudflare } from "@cloudflare/vite-plugin"; +import { reactRouter } from "@react-router/dev/vite"; + +export default defineConfig({ + plugins: [cloudflare({ viteEnvironment: { name: "ssr" } }), reactRouter()], +}); +``` + +This merges the Worker's environment configuration with the framework's SSR configuration and ensures that the Worker is included as part of the framework's build output. diff --git a/src/content/docs/workers/vite-plugin/tutorial.mdx b/src/content/docs/workers/vite-plugin/tutorial.mdx new file mode 100644 index 000000000000000..9c51a4e2493c6b1 --- /dev/null +++ b/src/content/docs/workers/vite-plugin/tutorial.mdx @@ -0,0 +1,289 @@ +--- +pcx_content_type: tutorial +title: Tutorial - React SPA with an API +sidebar: + order: 2 +description: Create a React SPA with an API Worker using the Vite plugin +--- + +import { PackageManagers, WranglerConfig } from "~/components"; + +This tutorial takes you through the steps needed to adapt a Vite project to use the Cloudflare Vite plugin. +Much of the content can also be applied to adapting existing Vite projects and to front-end frameworks other than React. + +:::note +If you want to start a new app with a template already set up with Vite, React and the Cloudflare Vite plugin, refer to the [React framework guide](/workers/frameworks/framework-guides/react/). +To create a standalone Worker, refer to [Get started](/workers/vite-plugin/get-started/). +::: + +## Introduction + +In this tutorial, you will create a React SPA that can be deployed as a Worker with static assets. +You will then add an API Worker that can be accessed from the front-end code. +You will develop, build, and preview the application using Vite before finally deploying to Cloudflare. + +## Set up and configure the React SPA + +### Scaffold a Vite project + +Start by creating a React TypeScript project with Vite. + + + +Next, open the `cloudflare-vite-tutorial` directory in your editor of choice. + +### Add the Cloudflare dependencies + + + +### Add the plugin to your Vite config + +```ts {3, 6} title="vite.config.ts" +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import { cloudflare } from "@cloudflare/vite-plugin"; + +export default defineConfig({ + plugins: [react(), cloudflare()], +}); +``` + +The Cloudflare Vite plugin doesn't require any configuration by default and will look for a `wrangler.jsonc`, `wrangler.json` or `wrangler.toml` in the root of your application. + +Refer to the [API reference](/workers/vite-plugin/reference/api/) for configuration options. + +### Create your Worker config file + + + +```toml +name = "cloudflare-vite-tutorial" +compatibility_date = "2025-04-03" +assets = { not_found_handling = "single-page-application" } +``` + + + +The [`not_found_handling`](/workers/static-assets/routing/#not_found_handling--404-page--single-page-application--none) value has been set to `single-page-application`. +This means that all not found requests will serve the `index.html` file. +With the Cloudflare plugin, the `assets` routing configuration is used in place of Vite's default behavior. +This ensures that your application's [routing configuration](/workers/static-assets/routing/#routing-configuration) works the same way while developing as it does when deployed to production. + +Note that the [`directory`](/workers/static-assets/binding/#directory) field is not used when configuring assets with Vite. +The `directory` in the output configuration will automatically point to the client build output. +See [Static Assets](/workers/vite-plugin/reference/static-assets/) for more information. + +:::note +When using the Cloudflare Vite plugin, the Worker config (for example, `wrangler.jsonc`) that you provide is the input configuration file. +A separate output `wrangler.json` file is created when you run `vite build`. +This output file is a snapshot of your configuration at the time of the build and is modified to reference your build artifacts. +It is the configuration that is used for preview and deployment. +::: + +### Update the .gitignore file + +When developing Workers, additional files are used and/or generated that should not be stored in git. +Add the following lines to your `.gitignore` file: + +```txt title=".gitignore" +.wrangler +.dev.vars* +``` + +### Run the development server + +Run `npm run dev` to start the Vite development server and verify that your application is working as expected. + +For a purely front-end application, you could now build (`npm run build`), preview (`npm run preview`), and deploy (`npm exec wrangler deploy`) your application. +This tutorial, however, will show you how to go a step further and add an API Worker. + +## Add an API Worker + +### Configure TypeScript for your Worker code + + + +```jsonc title="tsconfig.worker.json" +{ + "extends": "./tsconfig.node.json", + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.worker.tsbuildinfo", + "types": ["@cloudflare/workers-types/2023-07-01", "vite/client"], + }, + "include": ["worker"], +} +``` + +```jsonc {6} title="tsconfig.json" +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" }, + { "path": "./tsconfig.worker.json" }, + ], +} +``` + +### Add to your Worker configuration + + + +```toml +name = "cloudflare-vite-tutorial" +compatibility_date = "2025-04-03" +assets = { not_found_handling = "single-page-application" } +main = "./worker/index.ts" +``` + + + +The `main` field specifies the entry file for your Worker code. + +### Add your API Worker + +```ts title="worker/index.ts" +interface Env { + ASSETS: Fetcher; +} + +export default { + fetch(request, env) { + const url = new URL(request.url); + + if (url.pathname.startsWith("/api/")) { + return Response.json({ + name: "Cloudflare", + }); + } + + return new Response(null, { status: 404 }); + }, +} satisfies ExportedHandler; +``` + +The Worker above will be invoked for any non-navigation request that does not match a static asset. +It returns a JSON response if the `pathname` starts with `/api/` and otherwise return a `404` response. + +:::note +For top-level navigation requests, browsers send a `Sec-Fetch-Mode: navigate` header. +If this is present and the URL does not match a static asset, the `not_found_handling` behavior will be invoked rather than the Worker. +::: + +### Call the API from the client + +Edit `src/App.tsx` so that it includes an additional button that calls the API and sets some state: + +```tsx {8, 32-46} collapse={12-27} title="src/App.tsx" +import { useState } from "react"; +import reactLogo from "./assets/react.svg"; +import viteLogo from "/vite.svg"; +import "./App.css"; + +function App() { + const [count, setCount] = useState(0); + const [name, setName] = useState("unknown"); + + return ( + <> + +

Vite + React

+
+ +

+ Edit src/App.tsx and save to test HMR +

+
+
+ +

+ Edit api/index.ts to change the name +

+
+

+ Click on the Vite and React logos to learn more +

+ + ); +} + +export default App; +``` + +Now, if you click the button, it will display 'Name from API is: Cloudflare'. + +Increment the counter to update the application state in the browser. +Next, edit `api/index.ts` by changing the `name` it returns to `'Cloudflare Workers'`. +If you click the button again, it will display the new `name` while preserving the previously set counter value. + +With Vite and the Cloudflare plugin, you can iterate on the client and server parts of your app together, without losing UI state between edits. + +### Build your application + +Run `npm run build` to build your application. + +```sh +npm run build +``` + +If you inspect the `dist` directory, you will see that it contains two subdirectories: + +- `client` - the client code that runs in the browser +- `cloudflare-vite-tutorial` - the Worker code alongside the output `wrangler.json` configuration file + +### Preview your application + +Run `npm run preview` to validate that your application runs as expected. + +```sh +npm run preview +``` + +This command will run your build output locally in the Workers runtime, closely matching its behaviour in production. + +### Deploy to Cloudflare + +Run `npm exec wrangler deploy` to deploy your application to Cloudflare. + +```sh +npm exec wrangler deploy +``` + +This command will automatically use the output `wrangler.json` that was included in the build output. + +## Next steps + +In this tutorial, we created an SPA that could be deployed as a Worker with static assets. +We then added an API Worker that could be accessed from the front-end code. +Finally, we deployed both the client and server-side parts of the application to Cloudflare. + +Possible next steps include: + +- Adding a binding to another Cloudflare service such as a [KV namespace](/kv/) or [D1 database](/d1/) +- Expanding the API to include additional routes +- Using a library, such as [Hono](https://hono.dev/) or [tRPC](https://trpc.io/), in your API Worker