@@ -30,18 +30,20 @@ available in any downstream handler or component via `ctx.state.user`.
3030Handle URL migrations with middleware:
3131
3232``` ts routes/_middleware.ts
33+ import { define } from " @/utils.ts" ;
34+
3335const REDIRECTS: Record <string , string > = {
3436 " /old-page" : " /new-page" ,
3537 " /blog/old-slug" : " /blog/new-slug" ,
3638};
3739
38- export default function handler( ctx ) {
40+ export default define . middleware (( ctx ) => {
3941 const redirect = REDIRECTS [ctx .url .pathname ];
4042 if (redirect ) {
4143 return ctx .redirect (redirect , 301 );
4244 }
4345 return ctx .next ();
44- }
46+ });
4547```
4648
4749> [ info] : ` ctx.redirect() ` includes protection against open redirect attacks.
@@ -55,7 +57,7 @@ Return different formats based on the `Accept` header:
5557import { HttpError } from " fresh" ;
5658import { define } from " @/utils.ts" ;
5759
58- export const handlers = define .handlers ({
60+ export const handler = define .handlers ({
5961 async GET(ctx ) {
6062 const user = await db .users .find (ctx .params .id );
6163 if (! user ) {
@@ -77,8 +79,9 @@ Use the `@std/http` cookie utilities:
7779
7880``` ts routes/_middleware.ts
7981import { getCookies , setCookie } from " @std/http" ;
82+ import { define } from " @/utils.ts" ;
8083
81- export default async function handler (ctx ) {
84+ export default define . middleware ( async (ctx ) => {
8285 const cookies = getCookies (ctx .req .headers );
8386 ctx .state .theme = cookies [" theme" ] ?? " light" ;
8487
@@ -95,7 +98,7 @@ export default async function handler(ctx) {
9598 });
9699
97100 return response ;
98- }
101+ });
99102```
100103
101104See [ Session management] ( /docs/examples/session-management ) for a complete
@@ -109,7 +112,7 @@ Access URL search params from the context:
109112import { page } from " fresh" ;
110113import { define } from " @/utils.ts" ;
111114
112- export const handlers = define .handlers ({
115+ export const handler = define .handlers ({
113116 GET(ctx ) {
114117 const query = ctx .url .searchParams .get (" q" ) ?? " " ;
115118 const pageNum = Number (ctx .url .searchParams .get (" page" ) ?? " 1" );
@@ -121,15 +124,17 @@ export const handlers = define.handlers({
121124
122125## Adding response headers
123126
124- Set custom headers in middleware or handlers :
127+ Set custom headers in middleware:
125128
126129``` ts routes/_middleware.ts
127- export default async function handler(ctx ) {
130+ import { define } from " @/utils.ts" ;
131+
132+ export default define .middleware (async (ctx ) => {
128133 const response = await ctx .next ();
129134 response .headers .set (" X-Frame-Options" , " DENY" );
130135 response .headers .set (" X-Content-Type-Options" , " nosniff" );
131136 return response ;
132- }
137+ });
133138```
134139
135140Or set headers on a specific route using ` page() ` :
@@ -149,7 +154,7 @@ Return a streaming response from a handler:
149154``` ts routes/api/stream.ts
150155import { define } from " @/utils.ts" ;
151156
152- export const handlers = define .handlers ({
157+ export const handler = define .handlers ({
153158 GET() {
154159 const body = new ReadableStream ({
155160 start(controller ) {
@@ -172,7 +177,9 @@ export const handlers = define.handlers({
172177Fresh runs on Deno, so you can upgrade HTTP connections to WebSockets directly:
173178
174179``` ts routes/api/ws.ts
175- export const handlers = define .handlers ({
180+ import { define } from " @/utils.ts" ;
181+
182+ export const handler = define .handlers ({
176183 GET(ctx ) {
177184 const { socket, response } = Deno .upgradeWebSocket (ctx .req );
178185
@@ -196,9 +203,11 @@ export const handlers = define.handlers({
196203Use middleware with ` URLPattern ` to route based on subdomains:
197204
198205``` ts routes/_middleware.ts
206+ import { define } from " @/utils.ts" ;
207+
199208const SUBDOMAIN_PATTERN = new URLPattern ({ hostname: " :sub.example.com" });
200209
201- export default async function handler (ctx ) {
210+ export default define . middleware ( async (ctx ) => {
202211 const match = SUBDOMAIN_PATTERN .exec (ctx .req .url );
203212 if (match ) {
204213 const sub = match .hostname .groups [" sub" ];
@@ -214,7 +223,7 @@ export default async function handler(ctx) {
214223 }
215224 }
216225 return ctx .next ();
217- }
226+ });
218227```
219228
220229## Proxying requests
@@ -226,7 +235,7 @@ import { define } from "@/utils.ts";
226235
227236const UPSTREAM = " https://api.example.com" ;
228237
229- export const handlers = define .handlers ({
238+ export const handler = define .handlers ({
230239 async GET(ctx ) {
231240 const url = new URL (ctx .params .path , UPSTREAM );
232241 url .search = ctx .url .search ;
@@ -273,11 +282,13 @@ when `HeavyFeature` renders in the browser.
273282Measure how long request processing takes:
274283
275284``` ts routes/_middleware.ts
276- export default async function handler(ctx ) {
285+ import { define } from " @/utils.ts" ;
286+
287+ export default define .middleware (async (ctx ) => {
277288 const start = performance .now ();
278289 const response = await ctx .next ();
279290 const duration = performance .now () - start ;
280291 response .headers .set (" Server-Timing" , ` total;dur=${duration .toFixed (1 )} ` );
281292 return response ;
282- }
293+ });
283294```
0 commit comments