diff --git a/src/content/docs/workers/static-assets/binding.mdx b/src/content/docs/workers/static-assets/binding.mdx index c20228d6ea811fb..0b6487014240e15 100644 --- a/src/content/docs/workers/static-assets/binding.mdx +++ b/src/content/docs/workers/static-assets/binding.mdx @@ -17,6 +17,8 @@ import { Tabs, } from "~/components"; +import { WranglerConfig } from "~/components"; + Configuring a Worker with assets requires specifying a [directory](/workers/static-assets/binding/#directory) and, optionally, an [assets binding](/workers/static-assets/binding/), in your Worker's `wrangler.toml` file. The [assets binding](/workers/static-assets/binding/) allows you to dynamically fetch assets from within your Worker script (e.g. `env.ASSETS.fetch()`), similarly to how you might with a make a `fetch()` call with a [Service binding](/workers/runtime-apis/bindings/service-bindings/http/). Only one collection of static assets can be configured in each Worker. @@ -25,8 +27,6 @@ Only one collection of static assets can be configured in each Worker. The folder of static assets to be served. For many frameworks, this is the `./public/`, `./dist/`, or `./build/` folder. -import { WranglerConfig } from "~/components"; - ```toml title="wrangler.toml" @@ -60,6 +60,23 @@ _headers Now Wrangler will not upload these files as client-side assets when deploying the Worker. +## `experimental_serve_directly` + +Controls whether assets will be served first on a matching request. `experimental_serve_directly = true` ([default](/workers/static-assets/routing/#default-behavior)) will serve any static asset matching a request, while `experimental_serve_directly = false` will unconditionally [invoke your Worker script](/workers/static-assets/routing/#invoking-worker-script-ahead-of-assets). + + + +```toml title="wrangler.toml" +name = "my-worker" +compatibility_date = "2024-09-19" +main = "src/index.ts" + # The following configuration unconditionally invokes the Worker script at + # `src/index.ts`, which can programatically fetch assets via the ASSETS binding +assets = { directory = "./public/", binding = "ASSETS", experimental_serve_directly = false } +``` + + + ## `binding` Configuring the optional [binding](/workers/runtime-apis/bindings) gives you access to the collection of assets from within your Worker script. diff --git a/src/content/docs/workers/static-assets/compatibility-matrix.mdx b/src/content/docs/workers/static-assets/compatibility-matrix.mdx index badfc1c3853835f..64dce6edb8e071c 100644 --- a/src/content/docs/workers/static-assets/compatibility-matrix.mdx +++ b/src/content/docs/workers/static-assets/compatibility-matrix.mdx @@ -40,7 +40,7 @@ We plan to bridge the gaps between Workers and Pages and provide ways to migrate | **Static Assets** | | | | [Early Hints](/pages/configuration/early-hints/) | ❌ | ✅ | | [Custom HTTP headers for static assets](/pages/configuration/headers/) | 🟡 [^1] | ✅ | -| [Middleware](/pages/functions/middleware/) | 🟡 [^2] | ✅ | +| [Middleware](/workers/static-assets/binding/#experimental_serve_directly) | ✅ [^2] | ✅ | | [Redirects](/pages/configuration/redirects/) | 🟡 [^3] | ✅ | | [Smart Placement](/workers/configuration/smart-placement/) | ✅ | ✅ | | **Observability** | | | @@ -83,7 +83,7 @@ We plan to bridge the gaps between Workers and Pages and provide ways to migrate [^1]: Similar to 3, to customize the HTTP headers that are returned by static assets, you can use [Service bindings](/workers/runtime-apis/bindings/service-bindings/) to connect a Worker in front of the Worker with assets. -[^2]: If you need to run a Worker before serving static assets, you can create a separate Worker that acts as middleware, and then use [Service bindings](/workers/runtime-apis/bindings/service-bindings/) to forward the request to the Worker with assets. We plan to explore additional configuration to support more complex routing in the future. +[^2]: Middleware can be configured via the [`experimental_serve_directly`](/workers/static-assets/binding/#experimental_serve_directly) option, but is charged as a normal Worker invocation. We plan to explore additional related options in the future. [^3]: You can handle redirects by adding code to your Worker (a [community package](https://npmjs.com/package/redirects-in-workers) is available for `_redirects` support), or you can use [Bulk Redirects](/rules/url-forwarding/bulk-redirects/). diff --git a/src/content/docs/workers/static-assets/routing.mdx b/src/content/docs/workers/static-assets/routing.mdx index f7dd0f1a59f1627..88b62eec8ab81ff 100644 --- a/src/content/docs/workers/static-assets/routing.mdx +++ b/src/content/docs/workers/static-assets/routing.mdx @@ -17,7 +17,11 @@ import { Tabs, } from "~/components"; -Assets are served by attempting to match up the incoming request's pathname to a static asset. The structure and organization of files in your static asset directory, along with any routing configuration, determine the routing paths for your application. When a request invokes a Worker with assets: +import { WranglerConfig } from "~/components"; + +## Default behavior + +By default, assets are served by attempting to match up the incoming request's pathname to a static asset. The structure and organization of files in your static asset directory, along with any routing configuration, determine the routing paths for your application. When a request invokes a Worker with assets: 1. If a request is found with a matching path to the current route requested then that asset will always be served. @@ -33,6 +37,62 @@ In this example, request to `example.com/api` doesn't match a static asset so th ![A request to `example.com/blog` runs the Worker.](~/assets/images/workers/platform/assets/workers-assets-invoke-worker.png) +## Invoking Worker Script Ahead of Assets + +You may wish to run code before assets are served. This is often the case when implementing authentication, logging, personalization, internationalization, or other similar functions. [`experimental_serve_directly`](/workers/static-assets/binding/#experimental_serve_directly) is a configuration option available in `wrangler.toml` which controls this behavior. When disabled, `experimental_serve_directly = false` will invoke your Worker's code, regardless of any assets that would have otherwise matched. + +Take the following directory structure, wrangler.toml, and user Worker code: + + + +- wrangler.toml +- package.json +- public + - supersecret.txt +- src + - index.ts + + + + + +```toml title="wrangler.toml" +name = "my-worker" +compatibility_date = "2024-09-19" +main = "src/index.ts" +assets = { directory = "./public/", binding = "ASSETS", experimental_serve_directly = false } +``` + + + +```js +export default { + async fetch( + request: Request, + env: Env, + ctx: ExecutionContext + ): Promise { + const url = new URL(request.url); + if (url.pathname === "/supersecret.txt") { + const auth = request.headers.get("Authorization"); + if (!auth) { + return new Response("Forbidden", { + status: 403, + statusText: "Forbidden", + headers: { + "Content-Type": "text/plain", + }, + }); + } + } + + return await env.ASSETS.fetch(request); + }, +}; +``` + +In this example, any request will be routed to our user Worker, due to `experimental_serve_directly` being disabled. As a result, any request being made `/supersecret.txt` without an `Authorization` header will result in a 403. + ## Routing configuration There are two options for asset serving that can be [configured in `wrangler.toml`](/workers/wrangler/configuration/#assets): @@ -61,11 +121,13 @@ If you have custom 404 HTML pages, and configure `not_found_handling` to `"404-p Take the following directory structure: -``` -|---- file.html -|---- folder - |___ index.html -``` + + +- file.html +- folder + - index.html + + Based on the incoming requests, the following assets would be served: @@ -99,8 +161,6 @@ Alternate configuration options are outlined on this page and can be specified i Example `wrangler.toml` configuration: -import { WranglerConfig } from "~/components"; - ```toml title="wrangler.toml" @@ -113,11 +173,13 @@ assets = { directory = "./public", binding = "ASSETS", html_handling = "force-tr Take the following directory structure: -``` -|---- file.html -|---- folder - |___ index.html -``` + + +- file.html +- folder + - index.html + + **`html_handling: "auto-trailing-slash"`** @@ -191,12 +253,14 @@ Based on the incoming requests, the following assets would be served: Take the following directory structure: -``` -|---- 404.html -|---- index.html -|---- folder - |___ 404.html -``` + + +- 404.html +- index.html +- folder + - 404.html + + **`not_found_handling: "none"`** diff --git a/src/content/docs/workers/wrangler/configuration.mdx b/src/content/docs/workers/wrangler/configuration.mdx index 88ad60b87c93460..cd6575d7ba8a8c1 100644 --- a/src/content/docs/workers/wrangler/configuration.mdx +++ b/src/content/docs/workers/wrangler/configuration.mdx @@ -981,6 +981,10 @@ The following options are available under the `assets` key. - The binding name used to refer to the assets. Optional, and only useful when a Worker script is set with `main`. +- `experimental_serve_directly` + + - Controls whether static assets are fetched directly, or a Worker script is invoked. Learn more about fetching assets when using [`experimental_serve_directly`](/workers/static-assets/routing/#invoking-worker-script-ahead-of-assets). + - `html_handling`: - Determines the redirects and rewrites of requests for HTML content. Learn more about the various options in [assets routing](/workers/static-assets/routing/#html_handling).