fsRoutes mounted more than once runs every _middleware once per mount
Fresh 2.3.3, also present on main at 86d6cde.
When the file-system routes are mounted more than once, for example a preview
prefix plus the plain tree, every _middleware.ts runs once per mount on a
single request. Routes are prefixed correctly; only the middleware, layout and
error placement lose the prefix.
Reproduction
deno.json imports: fresh jsr:@fresh/[email protected], @fresh/plugin-vite 1.1.2,
vite 7.3.6, preact 10.29.7.
main.ts
import { App } from "fresh";
export const app = new App()
.fsRoutes("/a/:id")
.fsRoutes("/b/:id")
.fsRoutes();routes/_middleware.ts
import type { Middleware } from "fresh";
export const handler: Middleware<unknown> = (ctx) => {
console.log("middleware ran for " + new URL(ctx.req.url).pathname);
return ctx.next();
};routes/index.tsx renders a heading.
deno task dev
curl -s -o /dev/null http://localhost:8000/Output:
middleware ran for /
middleware ran for /
middleware ran for /Expected: one line.
Where
packages/fresh/src/commands.ts, applyCommandsInner. The Route case builds
its path with mergePath(basePath, pattern), and the FsRoute case recurses
with mergePath(basePath, cmd.pattern, true) as the new base. The Middleware,
Layout and Error cases call getOrCreateSegment(root, cmd.pattern, ...) with
the un-prefixed pattern, so every mount lands its middleware in the same
segment and segmentToMiddlewares collects all of them for each route.
Passing the merged base into getOrCreateSegment for those three cases is what
I would expect, but I have not tested that change against the suite.
Source: freshframework/fresh