-
-
Notifications
You must be signed in to change notification settings - Fork 348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Single Route File #341
Comments
This comment was marked as outdated.
This comment was marked as outdated.
One option could be to use a tagged template literal string. Which at first glance seems to have typescript support. It would also allow to eliminate the documentation/comments in the aforementioned example, since it would be more direct. function Menu() {
return <>
<Link to={`/`} />
<Link to={`/about`} />
<Link to={`/product/${42}`} />
<Link to={`/products`} />
</>
} |
I see there’s some precedence to the API that I suggested: https://solito.dev/usage/link#wrapper-components In all, Solito does some really nifty things with routing, which is very desirable to replicate on a non-NextJS stack. To enable universal apps cross platform. The downside with Fernando’ stack (NextJS+Expo+Solito+Dripsy) is that it actually disables SSR on web to be able to work (due to issues with responsivity, that Tamagui solves). So there’s a double opportunity there: universal apps on Vite and with SSR on web. I know the very competent and prolific author of Tamagui is looking into that, and has been eyeing vite-plugin-ssr since I gave word to him about it. |
Does Solito has such TypeScript support?
So far, I can't see how TypeScript's template literal strings would help. One aspect of Single Route Files that is interesting is that the user can change the URL without having to modify each link. That's why I'm leaning towards |
It doesn't seem like it. It simply replicates NextJS' API.
On second glance, I think you're right. TypeScript Template Literal Types that I linked to are a different thing. What I had in mind - type checking inside tagged template literal strings - is still an open TypeScript issue (not very likely to get implemented, it seems): microsoft/TypeScript#29432
I see. I think the general web native way of doing it - and what Rails did - is to simply provide a re-route to the new URL. That way, outdated links in ones app would work the same as the outdated links to one's page that had already been shared on the web: they would be re-routed to the new URL. |
Did some more research into this, since you mentioned it is a blocker. In addition to pathpida, check out next-type-safe-routes or nextjs-routes or next-typed-routes for inspiration. The API of next-type-safe-routes seems the nicest (clearest, most straightforward/intuitive, least boilerplate). The automatic route listing (route autocomplete) is quite nice.
So, the only issue with using either of those directly is that they all presume filesystem routing (being for NextJS). Maybe typesafe-routes is what you're looking for?Actually, it turns out you can use TypeScript Template Literal Types to get type checking inside tagged template literal strings, like I had in mind. This library does it, see the GIF animation in that repo. As long as it is possible to wrap the |
Neat. Indeed, We can even make the route types defined by the user in I think we can make it work. Although Route Functions routes cannot be typed, but that's expected.
Yes, that's the idea. So far, I don't see a problem with that. |
Came across this. Could be potential inspiration for typesafe routes.
|
react-router-url-params is another one, for typesafe query parameters. It was made this summer. |
My idea is that TypeScript for query params just works if we treat param serialization as implementation detail defined by the user. // `order` is typesafe
<Link to="product-search" order={"desc"} /> // /routes.js
export default {
routes: [
{
Page: '/pages/product-search.page.js',
toUrl: ({ order }: { order: 'asc' | 'desc' }) => `/product/search?order={order}`,
route: '/product/search'
},
]
} |
I'm a big fan of Tanstack React Location and upcoming Tanstack Router. I think it's API is quite well thought. See this single route file example from Tanstack Router: https://github.com/TanStack/router/blob/572318b1b132307be02857b97ae05b2040363ccf/examples/kitchen-sink/src/index.tsx#L91 I really like how React components can be used instead of file path as proposed in this issue. Also, pending state feature sounds incredible. |
The API of React Location / TanStack Router looks a lot like the API of (Remix and) React Router v6 : TanStack Router has the same issue as React Router mentioned there:
|
The overall design is starting to crystalize (it also includes better support for nested layouts). One open question: https://stackoverflow.com/questions/73957822/get-import-path-of-dynamic-import-as-typescript-string-type, in case someone knows this. I don't think it's possible, but who knows with TypeScript 😅. |
blitz-js has another way to achieve typesafe routing which looks quite neat: https://twitter.com/aleksandrasays/status/1559157742559825920?s=20&t=uaV2ruG_UcOlWxDwGhk9yQ |
👍 Neat idea to make the link target a TS object, so you can definition-jump directly to the route file. Neat. |
@patryk-smc @brillout here's an idea for a simplified API which presents the routes in a flat manner so you can more easily visually pattern-match to the URL in the browser (compared to the nesting in React Router and TanStack Router): |
@redbar0n Yes I'm also not too fond of their verbosity. While I share the sentiment to keep things succinct, I'm thinking multi-dimensional arrays are a bit too extreme, i.e. not explicit enough. Let's see if the solution I come up with is succinct enough (so far I think so). |
Ok, excited to see how it will look. I wonder how much explicitness is needed if we can have some Convention over Configuration. |
Coming from React Router I use their Javascript Route Definitions which allows me to dynamically create and pre-filter routes, and render navigation from the definitions. |
For folks who need/want Single Route File, please PM on discord. |
FFR, here is a thread with people who don't like file based routing: https://twitter.com/t3dotgg/status/1583285667768827904 |
I think SolidStart is taking a great approach with the dynamic |
Yeah, I agree, with one exception. To quote the SolidStart approach:
I think it makes more sense to expose the file routes through some other means than as a UI component. Maybe as a function (e.g. import You then use it to import the default routes derived from the file system, which you are then able to overwrite in the routes file. Or you could choose to not import it and rather manually write out all the routes if you'd like. I think it could be the best of both worlds: convenience of filesystem routing (aka. file based routes) + the power and customizability of a single route file. Avoiding having it as a UI component would also allow vps to remain render library agnostic. |
I'm actually thinking of increasingly focusing on single route files, and I'm increasingly thinking that it's superior than Next/Solid/Remix's approach. That said, so far, I think still supporting basic FS routing makes sense (like what VPS already does today), but I'll likely won't focus much on it. |
TanStack Router vs. React Router DOM vs. Next.js comparison page is out, as per demand. It has a good overview of potentially desirable features for a routing solution. |
Other than typesafe links (which is quite lovely), is there something you'd miss if using VPS's built-in router? |
My approach to the Single Route File would be to use it into my framework, I'd like to have a File Routing System but I like it in my own style, that's why I would probably in a Single Route File declared in the renderer folder, use import.meta.glob or something like Chokidar. I like the idea of // +config.js
export default {
routes: {
"/:id": {
Page: UserPage,
onBeforeRender: onBeforeRenderUser,
"/activities": {
Page: UserActivitiesPage,
onBeforeRender: onBeforeRenderUserActivities
}
// ...etc
}
}
} I'm not that sure about the naming of the property "routes" as I don't know how it would be to separate API Routes and UI Routes. |
Hello, I would be interested to get a single file routes definition to increase maintenability and also getting better git diff when updating routes. It's also more user dev friendly to have a file to defined all routes, dev can quickly read it and understand what is going on at a specific url. I think vps is a plug and play ssr plugin for vite sooo imo it need to be as flexible as he can be. I just want to be able to define my urls and get it strongly typed when I'm using a link. I also think child routes are not that good for readability I prefer to have a full relative url on each route. Hope it can be helpful, sry for bad english. Also hope it's understandable. |
Do you mind elaborating? |
A good example would be, where routes are managed externally from the code, in applications with multi project setup. Having the flexibility to define route pages without being forced to use file based routing, would be a great feature that Vite-Plugin-SSR could implement. |
Definitely and especially now with the V1 design header files.
Curious: what's your motivation for organizing your code like that? The more I know about use cases, the better. |
It could be useful in projects where same codebase is used for multiple projects, and is managed externally via some kind of CMS. Pages, entire features are configurable without requiring a release. |
Do you know of any short term solution which could allow me to configure routes without file based routing? |
Makes sense. What is it you're building? Let's PM. Let's also talk about sponsoring, which can make sense for your company as you'll be using a unique added value of VPS. It's actually already implemented by config.extends. But you can't currently provide pages (i.e. routes). This ticket is precisely about enabling defining pages/routes in For others reading this: if your company is up for sponsoring, definitely PM me. I prioritize features by the needs of sponsors. |
I'm currently not considering implementing Single Route File for the https://github.com/brillout/vite-plugin-ssr/labels/v1%20release%20%3Astar2%3A. AFAICT it's about two things:
Are there other use cases? If so, let me know. The thing is that I've a solution in mind that doesn't require Single Route File for both
|
For me this would be an awesome feature for localization. I could then dynamically change the routing based on the localization of the user. For instance: in english this would be
in german
It would make my life much easier to define this in a single file instead of in multiple files. Of course within my app then I would need a helper, which resolves the routes by routes name. So basically, the creation of a route would mean I define an unchangable name and a dynamic string which is what will be displayed in the url. The API I am picturing would be: // in some route file
import route from 'vite-plugin-ssr';
type add = { (uri: string, name: string, component: ReactNode|FC<any>) => void }
route.add('/home', 'home', component)
// Not sure if the next to would also need consideration
route.add('/contract/{route-param}', 'contract-details', component)
route.add('/contract?query-param', 'contract-search', component) // to refrence a route I would then need to call a resolve function with the name
<Link to={routeResolve('home')} />
// alternative VPS provides a link wrapper which does this under the hood for me
<Link to='home' /> Edit: if there is already a plan to deliver this and just the manpower to do it is missing I would be willing to look into the matter. Is there a way to help or contribute? |
I see. Most of it is actually unrelated to having a Single Route File. I created a new ticket for i18n: #1000. FYI I'll be working on a couple of higher priority https://github.com/brillout/vite-plugin-ssr/labels/v1%20release%20%3Astar2%3A tickets before tackling i18n. I consider it a blocker for the v1 release, so you can expect enhancements around i18n fairly soon. I suggest we first implement i18n then let's see if the need for a Single Route File is still there. |
@brillout my statement holds true though. I really would prefer to define my routes in a single file instead of having filesystem routing. If I can help to implement this let me know where I could get started. |
A Single Route File also has its drawbacks. It isn't a perfect solution. I think I understand the appeal of it and I still have mixed feelings about it. I'm thinking at this point the best is to first try to solve all issues without Single Route File and then later reconsider whether we want to add support for it. That said, feel free to elaborate and why exactly you'd prefer a Single Route File over Filesystem Routing. (Your previous comment was more related to #1000. FYI I've a design in mind about i18n which I'll share if I'm still happy about it in a couple of days.) |
@brillout For me it just seems so much simpler to use a single file for defining routes. But I am comming from a server perspective here. Most frameworks I worked with offered me a router object onto which I can push routes. How I then generate the routes is entirely up to me. So for me the main benefit is that I can control route generation on run time. File System routing is fine simple frontend apps which have a couple of slugs etc. But defining common middlewares, route groups, prefixes etc. seems just more simple for me in a single file. There I can have a typed object (API) and don't need to learn what kind of special file with a special hook I need to export. I could have a single API, which in my opinion is much easier to understand. (But maybe this is just me. I have a hard time to do simple things with the file based routing right now.)
May I ask why to address multiple issues with different solution when you could have one solution for all of them? If we have a single route file we can write our own solution around it. You don't need to solve all our problems 😅 |
That makes a lot of sense.
That's quite appealing indeed. Actually, the V1 design needs a rudimentary implementation of a Single Route File. I'll see if I can get something useable for users. |
@brillout if it helps you can also point me into a direction where and maybe "how" I could get started on, since I am need of the feature I would be willing to help out to maybe build a first implementation of this. I guess you have a lot of work to do with the V1 Design. However, I also know that first contributors can often cost more time than they bring to the table. So if contribution are welcome (and possible) I could have a look in coming up with an implementation if you have ideas for architecture maybe we can discuss them closer per pm (discord)? But I can also see that as maintainer you want to implemt this kind of core feature yourself. |
I definitely appreciate the intention but, yeah, this one is quite a subtle one so I think it's best I implement it. (There are other tickets that are well suited for getting started with contributing: https://github.com/brillout/vite-plugin-ssr/labels/contribution-welcome%20%3Atwo_hearts%3A — in case any of it is appealing to you.) |
This would also be useful for any plugin that wants to build an abstraction above Vike/VPS . The Single Route File could be generated by them yet still be transparently visible/editable by the user. Be it an abstraction that provides the boilerplate for an API layer, internationalized routes, etc. |
@doeixd You're right and that's the plan: https://vite-plugin-ssr.com/extends. (The rudimentary Single Route File implementation I mentioned earlier needed for the V1 design is actually precisely for enabling extensions to define pages.) |
The ideal, imho, would be to have:
Thumbs up or heart if you like or love this ideal. Update: Another thing I thought of is that it would be very nice to have the Vike code for parsing the filesystem routes available in a file (not buried deep within some framework code). So you could easily override it if you wanted to parse the filesystem routes differently (if you wanted a different project folder structure for instance). |
Each As for increased flexibility around Filesystem Routing I agree that'd be nice, but it isn't a priority at the moment. That said, I'm happy to revisit prioritisation upon blockers and/or sponsoring. |
Latest design for defining all routes in a single file: #341 (comment). |
I presume you mean «Code Extraction: The act of separating the code and creating server and client code bundles». But doesn’t Vike already do this to an extent? If the problem with having all routes in a single file is that client side routing and server side routing would need to be extracted from that file, what about 2 files: a single route file for the client, and a single route file for the server? Could make it clearer. E.g. So if you want to SSR a particular page you’d move it to the single route file for the server. |
@redbar0n I'm afraid it isn't that simple. In general, design needs an holistic understanding of a lot of problems at once. I'd be happy to elaborate but that would require 2-3 pages of text. As you can imagine, prioritization is crucial for Vike to grow. That said, it's paramount that users communicate their pain points and what they try to achieve (the goals), and I'm more than happy to hear (critical) feedback here. The resulting design (how to achieve the goals) is a work that only Vike maintainers can do. |
Description
Being able to define the entire routing of the app in a single file.
If you want this, feel free to write a comment down below explaining why. The more we know why users want this, the better we can prioritize accordingly.
The text was updated successfully, but these errors were encountered: