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
fix: isolate the shim port from application throws, and close the doc drift
Review found five things.
The shim port the per-tab fallback hands the relay runs application code
synchronously in its postMessage, and the relay deletes a port whose
postMessage throws. That heuristic reads a throw as "the tab is gone",
which is right for a real MessagePort and wrong here: an overlay render
that threw would permanently unsubscribe the tab and silently kill its
live reload. The pre-#1397 fallback attached to the EventSource directly,
where a handler throw detached nothing, so the guard restores the old
behaviour rather than adding a new one.
The ?v= test claimed to cover the early path while building the handler
with dev: false, so it exercised the prod path instead. It cannot be
written the other way, since fileResponse hard-codes no-cache whenever dev
is true, so immutable is unobservable there. Retitled to what it actually
pins, plus a dev-mode assertion that a fingerprinted asset still serves on
the early path.
Correcting the middleware prose left two code-block comments two lines
below still saying "every request", and the same claim was still on the
agent-facing skill reference the scaffold ships, in the root AGENTS.md
layout table, and in the blog example's own middleware.
Inserting the two constants between the module header and the function
orphaned its @PARAM tags onto a constant, and the header no longer
mentioned that reloadClientJs inlines this source too.
Copy file name to clipboardExpand all lines: .agents/skills/webjs/references/muscle-memory-gotchas.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -202,7 +202,7 @@ Export `GET` / `POST` / etc. as named async functions `(request, { params }) =>
202
202
203
203
### `middleware.ts` is per-segment and chainable, not one matcher config
204
204
205
-
The file stays `middleware.ts`, NOT Next 16's renamed `proxy.ts`. WebJs middleware is in-process, chainable, and per-segment (the Remix / Koa model). There is no `export const config = { matcher }` and no single-file restriction. The default export is `async (req, next) => Response`: return a Response to short-circuit, or call `next()` and post-process. Colocate `app/admin/middleware.ts` next to the admin routes and it runs for that subtree only. An optional root `middleware.ts` runs on every request, outermost to innermost.
205
+
The file stays `middleware.ts`, NOT Next 16's renamed `proxy.ts`. WebJs middleware is in-process, chainable, and per-segment (the Remix / Koa model). There is no `export const config = { matcher }` and no single-file restriction. The default export is `async (req, next) => Response`: return a Response to short-circuit, or call `next()` and post-process. Colocate `app/admin/middleware.ts` next to the admin routes and it runs for that subtree only. An optional root `middleware.ts` runs on every app request, outermost to innermost. Two things are served ahead of it: the framework's own `/__webjs/*` assets and probes, in both modes, and in DEV only, `/public/*` plus the `/sw.js` / `/offline.html` root remaps and `/favicon.ico`, so a stylesheet is never queued behind the dev startup analysis. In production those static files go through root middleware normally, so a middleware that guards an asset still guards it where it counts.
206
206
207
207
### No `<Link>`, no `next/navigation`, no `next/*` libraries
Copy file name to clipboardExpand all lines: website/app/docs/middleware/page.ts
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ export default function Middleware() {
11
11
<p>Place a <code>middleware.ts</code> at the root of your project (next to <code>app/</code>, not inside it). This middleware runs on <strong>every app request</strong> before WebJs routes it to a page, API route, or server action. Any of <code>middleware.ts</code>, <code>.js</code>, <code>.mts</code>, or <code>.mjs</code> works, and <code>.ts</code> wins if you somehow have more than one.</p>
12
12
<p>Two things are served ahead of it, so root middleware never sees them. The framework's own <code>/__webjs/*</code> assets and health probes bypass it in both dev and production, because they are framework infrastructure your app needs to boot rather than app routes. In <strong>development only</strong>, static files under <code>/public/*</code> (plus the <code>/sw.js</code> and <code>/offline.html</code> root remaps and <code>/favicon.ico</code>) are served ahead of it as well, so a stylesheet is never queued behind the dev server's startup analysis. In production those static files go through root middleware normally, so a middleware that protects an asset still protects it where it counts.</p>
13
13
<code-block>my-app/
14
-
middleware.ts # root middleware: runs on every request
14
+
middleware.ts # root middleware: runs on every app request
15
15
app/
16
16
page.ts
17
17
api/
@@ -33,7 +33,7 @@ export default async function middleware(
33
33
<h2>Per-Segment Middleware</h2>
34
34
<p>Place a <code>middleware.ts</code> inside any directory under <code>app/</code> to scope it to that subtree. It runs only for requests whose URL matches that segment and its children.</p>
0 commit comments