4 ms·
Build Your Own Router with URLPattern()
- teddyh 11mo agoSPA router, not IP router.
- embedding-shape 11mo agoKind of obvious when a DOM/Web API is mentioned, isn't it? Besides, does it really matter? Same ideas you use for building a frontend router can be used to build a backend router, and vice-versa.
- simon04 11mo agoMaybe not so much for an Internet Protocol router?
- deleted 11mo ago[deleted]
- teddyh 11mo agoThe actual title, and the original HN story title, was “Build Your Own Router”, which, in a general tech context like HN, I would assume mean an IP router.
- embedding-shape 11mo agoSure, but once you open up the article and see browsers with green checkmarks next to them, and "this feature works across the latest devices and browser versions", then most people have to be getting what the coming body text is about, right?
- pscanf 11mo agoI've done something similar in a React project I'm working on to avoid dealing with the insanity that is react-router. Call me naïve, but routing in a single page application is just not that hard of a problem. At the core it's about having a piece of state¹ (your active route) which determines which part of the app you want to render–something you can do with a switch statement². On top of that, you want to synchronize that state to the page URL³. Doing it yourself requires more boilerplate code, no question about it. But it's not that much code tbh (not very complex either), and you get back control over that important piece of state, which otherwise remains opaque and difficult to work with–i.e., its "shape" is pre-determined by the routing library you use. For example, react-router doesn't support parallel routes. ¹ https://github.com/superegodev/superego/blob/main/packages/apps/browser-app/src/business-logic/navigation/Route.ts https://github.com/superegodev/superego/blob/main/packages/a... ² https://github.com/superegodev/superego/blob/main/packages/apps/browser-app/src/components/routes/Root/MainPanel.tsx https://github.com/superegodev/superego/blob/main/packages/a... ³ https://github.com/superegodev/superego/blob/main/packages/apps/browser-app/src/business-logic/navigation/RouteUtils.ts https://github.com/superegodev/superego/blob/main/packages/a...
- sampullman 11mo agoI don't think it's naive, I often do the same in Vue. A pretty useful subset of vue-router can be implemented in less than a tenth of the bundle size.
- embedding-shape 11mo agoI also basically re-invent a tiny 50 line router for every web project. Hardly ever go beyond "Map URL -> Page" and "Map URL + Parameters -> Page with properties", and when you do, knowing 100% how it works helps a lot. I also agree it isn't a hard problem, but personally I'd say you got the flow the wrong way around. You don't want to "synchronize state to the page URL" but rather treat the page URL as something you create state from, so it works both when you navigate there by pressing anchor tags, or the user manually enters the URL, and it gets a bit easier to manage. Basically, URL is the top-level state, and from there you derive what page, then render that page, rather than the other way around.
- pscanf 11mo agoYeah, implementing it with data flowing one-way only from the URL to the state is cleaner. Conceptually, however, I prefer to think of my state being at the center of things. I mean, that's where I define (via types) what the state is. The URL is just one serialization of that state that is convenient to use in a web browser (making it work with links, back/forth buttons, etc). Maybe in another environment another serialization would be needed. Or maybe no serialization could be needed at all (making it a memory router).
- simon04 11mo agoA very tiny router is provided by nanostores: https://github.com/nanostores/router https://github.com/nanostores/router
- johnfn 11mo agoIf you are just working on a small website and you don't care about SEO or supporting more than, I dunno, a thousand users, then sure. But if you ever expect to do more than that, I might call you naive, yeah. One big thing: what if you want to support SSR, which I think is a pretty basic requirement these days? I'd submit that supporting SSR will take you a bit more than 50 lines.
- jazzypants 11mo agoIs this really that much easier than matching paths and query strings yourself? I'm glad that there is an official API now, but this article didn't really show me anything to get excited about as someone who has built several client-side routers from scratch.
- bob1029 11mo agoWriting a fast router can be surprisingly difficult if you are trying to cover the edges. The state of the art is not trivial: https://github.com/dotnet/aspnetcore/blob/main/src/Http/Routing/src/Matching/DfaMatcher.cs https://github.com/dotnet/aspnetcore/blob/main/src/Http/Rout...
- embedding-shape 11mo agoThe thing is, performance in that particular context hardly matters, unless you're forcing users to switch pages faster than 1 page per second. Even if each resolving takes 0.1 seconds (which be bad, don't get me wrong), 99% of users wouldn't notice a thing, and if you're a small agency/shop/company/team, focusing on more general things tends to be time spent better.
- recursive 11mo agoI have a hard time imagining how one would implement a router that took a full millisecond to resolve a path in a typical case.
- embedding-shape 11mo agoImagine doing a call to a remote authentication service to check who has access to what :) Regardless, performance is usually not the biggest problem in those types of routers.
- recursive 11mo agoAuthorization seems different from route resolution to me. But I guess I wouldn't be surprised if someone was doing it that way.
- tinco 11mo agoThis seems really irrelevant to the browser. I wonder why this was standardized, JavaScript is easily powerful enough to express this. Surely it hasn't been a performance bottleneck for it needing a native api? I agree with the other two comments, surely almost every frontend webdev has implemented a router in their career unless they never strayed from the major frameworks. It's really not a complicated thing to have to build. I'm not one to look a gift horse in the mouth but I don't see why we're being given this one.
- embedding-shape 11mo agoAnytime I end up wondering "Why do we have feature X on the web?" I tend to up end reading through proposals and I always end up finding a suitable answer that makes me wonder no more. For this specific feature, there is lots of prior discussions about why this is needed in the first place here: https://github.com/whatwg/urlpattern https://github.com/whatwg/urlpattern
- kemayo 11mo agoBased on https://github.com/whatwg/urlpattern/blob/main/explainer.md https://github.com/whatwg/urlpattern/blob/main/explainer.md it looks like they specifically wanted it as a way to scope service workers so it's easy to make them only run on certain parts of a site, and viewed giving people something easy to use for other URL matching as a nice bonus.
- jauntywundrkind 11mo agoI'm really glad we have URLPattern, as it's a fairly mundane task that shouldn't need us to bring in special tools. I can't imagining argue that the plarform shouldn't come well equipped for basic cases like this. Ideally a native implementation will be able to use SIMD and be faster too, which is a nice to have. Unfortunately cases like here in the article are an example of why URLPattern had enormous push back during development. It's not the worst thing in the world to run three or four patterns one after another. But generally, doing a linear search for the right pattern doesn't scale well at all! If there's a dozen routes, running pattern after pattern is probably not ideal! We can look at Hono routers, for example. Which has a bunch of different examples, most of which will one-shot a bunch of patterns at once. RegExpRouter, TrieRouter. There's good write-ups for the tradeoffs across them. But they all take a bunch of routes up front, and combine them into a single matcher, attempting to re-use work across patterns. https://hono.dev/docs/concepts/routers https://hono.dev/docs/concepts/routers Really good we have URLPattern, but this is the anti-use-case, that almost convinced folks not to make URLPattern at all.
- jslakro 11mo agoPage.js is a good alternative for a client-side router https://visionmedia.github.io/page.js/ https://visionmedia.github.io/page.js/
- spankalee 11mo agoAs a maintainer of Lit, this statement seems a little off to me: > Another thing- should we be building a router with web components? Eh... maybe not? Lit seems to think (it would be helpful and useful)[1]. But there are a lot of considerations you have to handle with your own implementation that framework routers have already solved. Web components also add another level of security you need to be aware of. The Lit Labs router isn't a web component. It's a Lit reactive controller that lets you define a router separately from a component, but attach it to a component so that the component updates when routes change. So we're saying don't make your router a web component (ie `<my-route path="...">` Also there isn't another level of security web components. They're implemented in script just like a router. Script running in a page can do all kinds of things. [1]: https://www.npmjs.com/package/@lit-labs/router https://www.npmjs.com/package/@lit-labs/router
- hilti 11mo agoOh wow … I did this in the late 90s with PHP - roughly 30 years ago - and my websites worked without Javascript
- az09mugen 11mo agoI'm wondering if the people saying "php is bad" nowadays are not the same that keep reinventing php concepts in node.