Routing: Express's Own Wildcard, Hand-Wired
Website Rebuild with Express
Chapter 3 · Routing: Express's Own Wildcard, Hand-Wired
Express registers every route by hand, with no file-based convention at all (Chapter 1's own finding) — including the catch-all this course's own arbitrary-depth routing needs.
Express 5's Current Wildcard Syntax
*, with the matched value at req.params[0]. Express 5 upgraded its underlying path-matching library, and bare wildcards no longer work the same way — a named wildcard, *splat, is required instead. req.params.splat is an array of matched segments (e.g. ['programming', 'java'] for /programming/java), not a single joined string — .join('/') is what reconstructs the full path.
Genuinely Different From Every Sibling's Own Capture
Rails' own *path glob captured the whole matched segment as a single string directly. Express 5's *splat captures an array of the individual segments instead — a real, mechanical difference worth naming precisely rather than assuming every wildcard-capture syntax behaves identically just because the underlying goal is the same.
Route Order — the Same Gotcha, One Final Time
Express matches routes in registration order, exactly like every sibling framework in this series. app.get('/*splat', ...) has to be registered last, after any more specific route (like a future admin API route) — otherwise it swallows every request before the more specific route ever gets a chance to match. The identical trap, repeated honestly a final time, not presented as something new to Express.
404 Handling: Not a Gotcha Here, and Here's Why
src/pages/404.astro, a file that looks like it should work automatically but never gets reached. Express has no equivalent surprise, because it never had an automatic, file-based 404 convention to shadow in the first place — res.status(404).render('404') inside the catch-all handler was always going to be written by hand, the same way every other response in this framework is. Nothing silently breaks here, because nothing was ever implicit to begin with.
Six Frameworks' Wildcard Routing, Compared One Final Time
| Next.js | Django | Laravel | Rails | Astro | Express | |
|---|---|---|---|---|---|---|
| Mechanism | [...path] folder | <path:full_path> | {path?} + regex | *path glob | [...path].astro | /*splat |
| Capture shape | Array | Single string | Single string | Single string | Single string | Array |
Hands-On Exercises
Build the /*splat catch-all route, querying mysql2 directly against the pages table, and confirm a real stored page renders correctly.
📄 View solutionLog req.params.splat directly and confirm it's a real array of segments, not a single string — contrasting this explicitly with Rails' own *path capture.
📄 View solutionRegister the catch-all before a more specific /admin route, observe it swallow every request to /admin, then fix the ordering.
📄 View solutionChapter 3 Quick Reference
/*splat— Express 5's current named wildcard, replacing Express 4's bare*req.params.splat— an array of matched segments, joined manually into a full path- Route order still matters — the same gotcha repeated a final time across the series
- No 404-shadowing gotcha — Express never had an automatic 404 file to shadow in the first place
- Next chapter: Views: EJS Templates