You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Cloudflare adapter provides companion handlers that apply Cloudflare-specific setup to your [advanced routing pipeline](/en/guides/routing/#advanced-routing). These handlers configure session KV binding injection, static asset serving via the `ASSETS` binding, `Astro.locals.cfContext`, client address from the `cf-connecting-ip` header, `waitUntil`, and prerendered error page fetching.
436
+
437
+
You can use the [`astro/fetch`](/en/reference/modules/astro-fetch/) and [`astro/hono`](/en/reference/modules/astro-hono/) APIs from `src/fetch.ts` on Cloudflare without these handlers. The adapter's default entrypoint takes care of Cloudflare-specific setup for you. These companion handlers are useful when you already have a [custom worker entrypoint](https://developers.cloudflare.com/workers/wrangler/configuration/#inheritable-keys) (`src/worker.ts`), for example, to export a Durable Object, and want to use the advanced routing APIs directly from that file instead.
438
+
439
+
When using these handlers in your worker entrypoint, they replace the functionality of the adapter's default handler, so you should not use both at the same time. Place the Cloudflare handler before other Astro handlers so that bindings and locals are available to the rest of the pipeline.
For use with [`astro/fetch`](/en/reference/modules/astro-fetch/). The `cf()` function imported from `@astrojs/cloudflare/fetch` receives a [`FetchState`](/en/reference/modules/astro-fetch/#fetchstate), the Cloudflare `env`, and the `ExecutionContext`. It returns a `Response` for static asset hits, or `undefined` when the request should continue to Astro rendering:
For use with [`astro/hono`](/en/reference/modules/astro-hono/). The `cf()` function imported from `@astrojs/cloudflare/hono` returns a Hono middleware that reads `env` and `executionCtx` from the Hono context automatically:
Astro 6 brings significant improvements to the Cloudflare development experience and requires `@astrojs/cloudflare` v13 or later. Now, `astro dev` uses Cloudflare's Vite plugin and `workerd` runtime to closely mirror production behavior.
Copy file name to clipboardExpand all lines: src/content/docs/en/guides/routing.mdx
+146Lines changed: 146 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -575,3 +575,149 @@ In this example, only `src/pages/index.astro` and `src/pages/projects/project1.m
575
575
-_utils.js
576
576
-**project1.md**
577
577
</FileTree>
578
+
579
+
## Advanced routing
580
+
581
+
<p><Sincev="7.0.0" /></p>
582
+
583
+
By default, Astro handles every request with a built-in pipeline that runs the handlers in a fixed order: trailing-slash normalization, redirects, sessions, actions, user middleware, page rendering, i18n, and caching. This pipeline is designed to cover the most common use cases for routing and request handling, but it may not fit every project’s needs.
584
+
585
+
Astro's advanced routing allows you to replace this pipeline with your own. You can choose which built-in features to use and where to use them. You can also add your own custom logic anywhere in the pipeline. This gives you full control over how Astro handles incoming requests.
586
+
587
+
### Creating a custom entrypoint
588
+
589
+
When the default pipeline does not fit your needs, you can override it by creating a `src/fetch.ts` file that default-exports an object with a `fetch()` method. This method receives a standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and must return a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).
590
+
591
+
```ts title="src/fetch.ts"
592
+
importtype { Fetchable } from'astro';
593
+
594
+
exportdefault {
595
+
async fetch(request) {
596
+
// Your custom request handling logic here
597
+
returnnewResponse("Hello from advanced routing!");
598
+
}
599
+
} satisfiesFetchable;
600
+
```
601
+
602
+
Astro supports several file formats for its advanced routing entrypoint: `.ts`, `.js`, `.mjs`, and `.mts`. We recommend using `.js` in most cases or `.ts` if you need TypeScript support.
603
+
604
+
### Changing the entrypoint filename
605
+
606
+
By default, Astro looks for `src/fetch.ts` as the advanced routing entrypoint. You can change this by setting the `fetchFile` option in your Astro config file.
607
+
608
+
The following example tells Astro to look for `src/handler.ts` instead of `src/fetch.ts`:
609
+
610
+
```js title="astro.config.mjs"
611
+
exportdefaultdefineConfig({
612
+
fetchFile:'handler',
613
+
});
614
+
```
615
+
616
+
Set `fetchFile` to `null` to disable the entrypoint entirely. This is useful if you already have a `src/fetch.ts` file used for other purposes:
617
+
618
+
```js title="astro.config.mjs"
619
+
exportdefaultdefineConfig({
620
+
experimental: {
621
+
advancedRouting: {
622
+
fetchFile:null,
623
+
},
624
+
},
625
+
});
626
+
```
627
+
628
+
### Adding custom logic
629
+
630
+
The main benefit of advanced routing is the ability to insert custom logic into the request pipeline. You can run code before Astro touches the request, between pipeline stages, or after the response is produced.
631
+
632
+
You can do this in two ways:
633
+
634
+
- Use the [`astro()` handler](/en/reference/modules/astro-fetch/#astro) to run the full built-in pipeline, and add logic before or after it.
635
+
- Compose individual handlers from [`astro/fetch`](/en/reference/modules/astro-fetch/) or [`astro/hono`](/en/reference/modules/astro-hono/) for more control over execution order.
636
+
637
+
#### Running the full pipeline with `astro()`
638
+
639
+
Use [`astro()`](/en/reference/modules/astro-fetch/#astro) when you want to keep Astro's built-in routing behavior, but need custom logic around it. This approach preserves the default pipeline order and lets you add pre-processing and post-processing in one place. For many use cases, such as adding auth guards, request logging, and custom headers, `astro()` is all you need.
640
+
641
+
The following example checks if a user can access a dashboard before running the Astro pipeline, and adds a custom header to the response once Astro has finished running:
642
+
643
+
```ts title="src/fetch.ts"
644
+
import { FetchState, astro } from'astro/fetch';
645
+
646
+
exportdefault {
647
+
async fetch(request:Request):Promise<Response> {
648
+
const state =newFetchState(request);
649
+
650
+
// Custom pre-processing, runs before any Astro handler
651
+
const url =newURL(request.url);
652
+
if (url.pathname.startsWith('/dashboard')) {
653
+
const cookie =request.headers.get('cookie') ??'';
654
+
if (!cookie.includes('session=')) {
655
+
returnnewResponse(null, {
656
+
status: 302,
657
+
headers: { Location: '/login' },
658
+
});
659
+
}
660
+
}
661
+
662
+
const response =awaitastro(state);
663
+
664
+
// Custom post-processing, runs after Astro renders
665
+
response.headers.set('X-Powered-By', 'Astro');
666
+
returnresponse;
667
+
},
668
+
};
669
+
```
670
+
671
+
#### Composing individual handlers
672
+
673
+
When you need more control over the pipeline execution order, or want to omit certain features, you can compose individual handler functions from [`astro/fetch`](/en/reference/modules/astro-fetch/). Each handler operates on a [`FetchState` object](/en/reference/modules/astro-fetch/#fetchstate) that tracks per-request data, such as the matched route, cookies, and session. You can call handlers in any order and insert custom logic between stages.
674
+
675
+
The following example runs only the handlers used in the project and adds custom logic after actions and before page rendering:
676
+
677
+
```ts title="src/fetch.ts"
678
+
import {
679
+
FetchState,
680
+
actions,
681
+
middleware,
682
+
pages,
683
+
i18n,
684
+
} from'astro/fetch';
685
+
686
+
exportdefault {
687
+
async fetch(request:Request):Promise<Response> {
688
+
const state =newFetchState(request);
689
+
690
+
const actionResponse =awaitactions(state);
691
+
if (actionResponse) returnactionResponse;
692
+
693
+
// Custom logic between actions and page rendering
const response =awaitmiddleware(state, (s) =>pages(s));
697
+
returni18n(state, response);
698
+
},
699
+
};
700
+
```
701
+
702
+
### Using with Hono
703
+
704
+
Astro also provides Hono-compatible wrappers for all handler functions via [`astro/hono`](/en/reference/modules/astro-hono/). If you prefer to use [Hono](https://hono.dev/) as your routing framework, you can export a Hono app from `src/fetch.ts`:
-`rustCompiler`: The Rust-based Astro compiler is now the default and only compiler, replacing the previous Go-based compiler. No action is required for most projects. If you encounter any issues, please report them on [GitHub](https://github.com/withastro/astro/issues).
105
106
107
+
-`advancedRouting`: Advanced routing is now enabled by default. See the [advanced routing guide](/en/guides/routing/#advanced-routing) for more information. Note that `src/fetch.ts` is now a [reserved file name](#reserved-file-name-srcfetchts).
108
+
109
+
### Reserved file name: `src/fetch.ts`
110
+
111
+
Astro v7.0 introduces [advanced routing](/en/guides/routing/#advanced-routing), which uses `src/fetch.ts` (or `src/fetch.js`) as a special file name, similar to `src/middleware.ts`. Astro will automatically import this file to configure routing behavior.
112
+
113
+
If your project already has a `src/fetch.ts` file used for other purposes, Astro will attempt to process it as an advanced routing configuration, which may cause unexpected errors.
114
+
115
+
#### What should I do?
116
+
117
+
If you have an existing `src/fetch.ts` file that is not related to advanced routing, you have two options:
118
+
119
+
***Configure `fetchFile`**: you can specify a different filename or `null` to disable advanced routing. This is useful if you want to keep using `src/fetch.ts` for another purpose, or don't need advanced routing features:
120
+
121
+
```js title="astro.config.mjs" ins={5}
122
+
import { defineConfig } from'astro/config';
123
+
124
+
exportdefaultdefineConfig({
125
+
// specify a different file for advanced routing configuration:
126
+
fetchFile:'./src/router.ts',
127
+
// or disable advanced routing entirely:
128
+
// fetchFile: null,
129
+
});
130
+
```
131
+
132
+
***Rename your file** to something else (e.g. `src/fetcher.ts`, `src/main.ts`), and update any imports that reference it.
133
+
106
134
## Removed
107
135
108
136
The following features have now been entirely removed from the code base and can no longer be used. Some of these features may have continued to work in your project even after deprecation. Others may have silently had no effect.
0 commit comments