question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Get rid of filesystem-based routing and use js files for defining routes

See original GitHub issue

Is your feature request related to a problem? Please describe. WARNING: I don’t have enough experience with Svelte and the proposal is purely my thoughts without knowing about implementation details or without trying building something big

I just stared learning svelte-kit and I saw that it uses a filesystem-based router. Even though when you start with it seems like a straightforward way of building apps I am just imagining that when the app grows that approach will become confusing and have limitations.

My thoughts on why:

  1. It forces you to name your folder/files with the name of the page. That might sound silly or very opinionated on why it’s a bad thing, but it’s true that it’s a limitation because you can’t name the folders or files in the way you want or use the naming conventions (camelCase etc) that it’s decided in your project for naming folder or files.

  2. Hard to read and understand the folder structure When someone, even if he is experienced with filesystem-based routing, sees this folder structure in his editor, it will take a moment to realize what’s the actual paths used there and understand for what the different file naming format is used for. And I think this picture is a simple example, but I am sure that in bigger apps, reading folder structure with slugs, endpoints, rest parameters, private modules, components, service files will be even more verbose and difficult to read and understand. Also it will be a bit hard for beginners to memorize all these different naming conventions.

image

  1. Limiting the dev to build his own architecture (folder structure). I strongly believe that folder structure is very important for an application. Let’s take a simple example: Developers decide to group some pages in order to easily read and find specific pages. They have a lot of pages and they think to separate them by 3 categories:
  • pro-pages

  • free-pages

  • settings-related

    Reading docs I see that this is not possible because every page should live under routes and naming a folder to group pages will result in having the folder name in the URL which is not, let’s say, what we want. That was just an example I thought really quickly but I am imagining that there is many real examples. So in general, I think a framework should give developers the ability to use whatever folder structure they want and not limiting them.

  1. Deeply nested folders. I guess it’s not hard to understand that with the approach of nesting folders and files in order to match a specific URL, it will of course get verbose and really hard to maintain all the mess. I like to think about it as “the SASS nesting too deep bad practice”, where eventually it will become more difficult to maintain styles. You might argue that this has nothing to do with nesting folders and files, but I strongly believe (and have experience) that the nested your folders/files are, the harder it is to maintain and deal with them. To be honest, I think it’s possible to separate nested routes. For example you have 2 routes. /blog/posts/[id]/comments and /blog/posts/[id]/info. Is it possible instead of this: image To use this: image

I am not gonna write more why-s but instead describe my proposal on how to have routing.

Describe the solution you’d like I think it would be much better if we could just have a route.config.js file (you can change the name) where we specify all the related route configurations. As a rule, we will only need a folder name to know where all the pages will live. For example as a default folder name we can use src/routes. Then inside that the user can use whatever folder structure wants and the only thing to do is for every page to define a route.config.js. Let’s see an example:

src
 └── routes
│   │   └── projects
│   │   │   ├── ProjectsList.svelte
│   │   │   ├── router.config.js
│   │   │   ├── components
│   │   │   │   └── ProjectStatus.svelte
│   │   │   ├── services
│   │   │   │   └── service-one.js
│   │   │   ├── translations
│   │   │   │   ├── de.js
│   │   │   │   ├── en.js
│   │   │   ├── tests
│   │   │   │   ├── unit-test.js
│   │   │   │   ├── cypress-test.js

Before we focus on the route.config.js internals I want to mention that the above project structure is what I think the best way to build apps with routing. Personally instead of calling the pages folder routes I would go with modules because in almost all of my projects I use pages as modules meaning that each page has anything related to it inside that folder. And that folder should be plug-and-play since it compacts the code together into logical pieces like translations, tests, local components, routing etc.

Think for example that you have a page and it’s translations, stores, tests, route configurations, services are all in different folders throughout the app folder structure. This results in difficulty finding all the related files, hard to follow the flow, and hard to maintain because you never are sure if a file it’s really used somewhere or not by looking at it because it might be imported in a dynamic way.

By using modules though, even if you delete the entire module, you won’t have to search for anything related outside of that folder and you can just delete it and the app still works fine. You can also move an entire module to a different place and still everything works.

Back to the route.config.js internals. I think it might look like this:

path: '/user/:id',
name: 'singleUser',
component: () => import('./SingleUser.svelte'),
chunkName: 'singleUser',
props: true, // if the `id` should be passed as a prop to the component. Defaults to `false`
prerender: true,
beforeLoad: ({ page, fetch, session, context }) => {...}, // Similar to https://kit.svelte.dev/docs#loading
meta: {...} // provide meta fields for example `{ requiresAuth: true }`

I took the idea for the options above from Vue Router

Besides the route.config.js we must have a global configuration for all routes. It can be named globa-route-config.js (maybe something smarter) where we can have a global beforeLoad which runs on every route change (eg Authorization). Similar to Vue Router’s beforeEach.

In short, the basic idea is to have something really similar to Vue Router but instead of defining the routes inside a file, we use a route.config.js file which is located inside every module (page) to define all routes. Therefore, I also suggest to get rid of $layout and instead use a component inside Svelte page component for having layouts similar to Vue router’s <router-view></router-view>

How important is this feature to you? I think that would be really amazing. I also think that getting rid of filesystem-based routing and $layouts might results in less code if my proposal being used.

Additional context I know that my idea might be stupid since I don’t know if it’s realistic or not and I apologize if that’s the case, for the time you spent reading this.

Big THANK YOU to Rich Harris and Svelte team for revolutionizing the way we build apps even if that means that sometimes you have to reinvent the wheel and do the hard work when you know there is a high risk that your idea and your work might not even work. But I think that’s the best way to move forward and be successful and that does not apply only in programming but I think in general.

I took the time to create this proposal because I think it’s time to revolutionize the way how we do routing too. (Even though my idea could be trash and stupid 🤷‍♂️ )

Again thank you for your awesome work and keep it up doing incredible stuff. Really proud to sponsor Svelte 💪 🔥

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:3
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

10reactions
dummdidummcommented, Mar 28, 2021

I don’t think you will ever convince Rich to get rid of file-based routing 😄 but I agree that it would be nice to have some programmatic way to declare the routes yourself. It would roughly mean that SvelteKit would skip generating the route manifest and instead use the one provided. Not sure how the other maintainers feel about this.

5reactions
benmccanncommented, Mar 29, 2021

It’s highly unlikely we’d ever get rid of filesystem-based routing. Lots of our users already depend on it, so it’d be very disruptive. Not to mention many people prefer it.

It’s possible that it could be made pluggable so that you could use a different router and/or be made more configurable via code. I’d proposed some related ideas in an RFC.

Given that this isn’t something we’d do as proposed I’m going to close it for now in an effort to keep the issue tracker clean so that we can track what needs to be done. Feel free to discuss still or propose something more actionable.

Read more comments on GitHub >

github_iconTop Results From Across the Web

File-based routing with React Router - Omar Elhawary
It's a universal routing convention whether using Next.js or just React; Routes are automatically updated by adding/removing/renaming files at ...
Read more >
How to manually configure routing instead of File based ...
For example in the following code I want to render Service Component if my path URL is localhost:3000/about, I don't want to make...
Read more >
Routing: Introduction - Next.js
The files inside the pages directory can be used to define most common patterns. Index routes. The router will automatically route files named...
Read more >
File System Route API | Gatsby
Use the File System Route API when you want to create dynamic pages e.g. to ... As you add and remove markdown files,...
Read more >
File System Routing - Nuxt
Nuxt lets you create nested routes by using the children routes of vue-router. To define the parent component of a nested route, you...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found