Skip to content

Commit 92f0744

Browse files
bartlomiejuclaude
andcommitted
docs: fix remaining review issues
- Fix app.onError() missing path arg in error-handling.md - Add missing HttpError import in error-handling.md - Add missing define imports in WebSocket, subdomain, timing examples - Standardize on `handler` (singular) for all export names - Convert all untyped middleware to define.middleware() Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 394441f commit 92f0744

3 files changed

Lines changed: 34 additions & 21 deletions

File tree

docs/latest/advanced/error-handling.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ When an `HttpError` is thrown, Fresh catches it and invokes the error handler.
103103
You can check the status code in your error handler:
104104

105105
```ts main.ts
106-
app.onError((ctx) => {
106+
import { HttpError } from "fresh";
107+
108+
app.onError("*", (ctx) => {
107109
if (ctx.error instanceof HttpError) {
108110
const status = ctx.error.status;
109111
return new Response("oops", { status });

docs/latest/concepts/data-fetching.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ interface Data {
2020
project: { name: string; stars: number };
2121
}
2222

23-
export const handlers = define.handlers({
23+
export const handler = define.handlers({
2424
async GET(ctx) {
2525
const project = await db.projects.findOne(ctx.params.id);
2626
if (!project) {
@@ -30,7 +30,7 @@ export const handlers = define.handlers({
3030
},
3131
});
3232

33-
export default define.page<typeof handlers>(({ data }) => {
33+
export default define.page<typeof handler>(({ data }) => {
3434
return (
3535
<div>
3636
<h1>{data.project.name}</h1>
@@ -40,8 +40,8 @@ export default define.page<typeof handlers>(({ data }) => {
4040
});
4141
```
4242

43-
The `define.page<typeof handlers>` generic links the handler's return type to
44-
the component's props, giving you full autocompletion on `data`.
43+
The `define.page<typeof handler>` generic links the handler's return type to the
44+
component's props, giving you full autocompletion on `data`.
4545

4646
## Setting response headers and status
4747

docs/latest/examples/common-patterns.md

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,20 @@ available in any downstream handler or component via `ctx.state.user`.
3030
Handle URL migrations with middleware:
3131

3232
```ts routes/_middleware.ts
33+
import { define } from "@/utils.ts";
34+
3335
const 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:
5557
import { HttpError } from "fresh";
5658
import { 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
7981
import { 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

101104
See [Session management](/docs/examples/session-management) for a complete
@@ -109,7 +112,7 @@ Access URL search params from the context:
109112
import { page } from "fresh";
110113
import { 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

135140
Or 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
150155
import { 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({
172177
Fresh 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({
196203
Use middleware with `URLPattern` to route based on subdomains:
197204

198205
```ts routes/_middleware.ts
206+
import { define } from "@/utils.ts";
207+
199208
const 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

227236
const 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.
273282
Measure 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

Comments
 (0)