diff --git a/src/content/changelog/workers/2025-07-01-vite-plugin-enhanced-assets-support.mdx b/src/content/changelog/workers/2025-07-01-vite-plugin-enhanced-assets-support.mdx
new file mode 100644
index 00000000000000..35e6e62c2ccfb3
--- /dev/null
+++ b/src/content/changelog/workers/2025-07-01-vite-plugin-enhanced-assets-support.mdx
@@ -0,0 +1,36 @@
+---
+title: Enhanced support for static assets with the Cloudflare Vite plugin
+description: The Cloudflare Vite plugin now supports using all of Vite's static assets features in your Worker
+products:
+ - workers
+date: 2025-07-01T01:00:00Z
+---
+
+You can now use any of Vite's [static asset handling](https://vite.dev/guide/assets) features in your Worker as well as in your frontend.
+These include importing assets as URLs, importing as strings and importing from the `public` directory as well as inlining assets.
+
+Additionally, assets imported as URLs in your Worker are now automatically moved to the client build output.
+
+Here is an example that fetches an imported asset using the [assets binding](/workers/static-assets/binding/#binding) and modifies the response.
+
+```ts
+// Import the asset URL
+// This returns the resolved path in development and production
+import myImage from "./my-image.png";
+
+export default {
+ async fetch(request, env) {
+ // Fetch the asset using the binding
+ const response = await env.ASSETS.fetch(new URL(myImage, request.url));
+ // Create a new `Response` object that can be modified
+ const modifiedResponse = new Response(response.body, response);
+ // Add an additional header
+ modifiedResponse.headers.append("my-header", "imported-asset");
+
+ // Return the modfied response
+ return modifiedResponse;
+ },
+};
+```
+
+Refer to [Static Assets](/workers/vite-plugin/reference/static-assets/) in the Cloudflare Vite plugin docs for more info.
diff --git a/src/content/docs/workers/vite-plugin/reference/static-assets.mdx b/src/content/docs/workers/vite-plugin/reference/static-assets.mdx
index 14359554017dbe..0c52b8e9771c13 100644
--- a/src/content/docs/workers/vite-plugin/reference/static-assets.mdx
+++ b/src/content/docs/workers/vite-plugin/reference/static-assets.mdx
@@ -8,14 +8,17 @@ 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.
+This guide focuses on the areas of working with static assets that are unique to the Vite plugin.
+For more general documentation, see [Static Assets](/workers/static-assets/).
-:::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).
-:::
+## Configuration
+
+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 any of the following conditions are met:
+
+- There is an `index.html` file in the root of your project
+- `build.rollupOptions.input` or `environments.client.build.rollupOptions.input` is specified in your Vite config
+- You have a non-empty [`public` directory](https://vite.dev/guide/assets#the-public-directory)
+- Your Worker [imports assets as URLs](https://vite.dev/guide/assets#importing-asset-as-url)
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.
@@ -32,10 +35,34 @@ assets = { not_found_handling = "single-page-application" }
+## Features
+
+The Vite plugin ensures that all of Vite's [static asset handling](https://vite.dev/guide/assets) features are supported in your Worker as well as in your frontend.
+These include importing assets as URLs, importing as strings and importing from the `public` directory as well as inlining assets.
+
+Assets [imported as URLs](https://vite.dev/guide/assets#importing-asset-as-url) can be fetched via the [assets binding](/workers/static-assets/binding/#binding).
+As the binding's `fetch` method requires a full URL, we recommend using the request URL as the `base`.
+This is demonstrated in the following example:
+
+```ts
+import myImage from "./my-image.png";
+
+export default {
+ fetch(request, env) {
+ return env.ASSETS.fetch(new URL(myImage, request.url));
+ },
+};
+```
+
+Assets imported as URLs in your Worker will automatically be moved to the client build output.
+When running `vite build` the paths of any moved assets will be displayed in the console.
+
+:::note
+If you are developing a multi-Worker application, assets can only be accessed on the client and in your entry Worker.
+:::
+
## Headers and redirects
Custom [headers](/workers/static-assets/headers/) and [redirects](/workers/static-assets/redirects/) are supported at build, preview and deploy time by adding `_headers` and `_redirects` files to your [`public` directory](https://vite.dev/guide/assets#the-public-directory).
The paths in these files should reflect the structure of your client build output.
For example, generated assets are typically located in an [assets subdirectory](https://vite.dev/config/build-options#build-assetsdir).
-
-
diff --git a/src/content/docs/workers/vite-plugin/tutorial.mdx b/src/content/docs/workers/vite-plugin/tutorial.mdx
index f8aa24a0f6fc61..c31bc0fc357838 100644
--- a/src/content/docs/workers/vite-plugin/tutorial.mdx
+++ b/src/content/docs/workers/vite-plugin/tutorial.mdx
@@ -147,12 +147,8 @@ 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) {
+ fetch(request) {
const url = new URL(request.url);
if (url.pathname.startsWith("/api/")) {
@@ -163,7 +159,7 @@ export default {
return new Response(null, { status: 404 });
},
-} satisfies ExportedHandler;
+} satisfies ExportedHandler;
```
The Worker above will be invoked for any non-navigation request that does not match a static asset.
@@ -172,6 +168,21 @@ It returns a JSON response if the `pathname` starts with `/api/` and otherwise r
:::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.
+This implicit routing is the default behavior.
+
+If you would instead like to define the routes that invoke your Worker explicitly, you can provide an array of route patterns to [`run_worker_first`](/workers/static-assets/binding/#run_worker_first).
+This opts out of interpreting the `Sec-Fetch-Mode` header.
+
+
+
+```toml
+name = "cloudflare-vite-tutorial"
+compatibility_date = "2025-04-03"
+assets = { not_found_handling = "single-page-application", run_worker_first = ["/api/*"] }
+main = "./worker/index.ts"
+```
+
+
:::
### Call the API from the client