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