kit icon indicating copy to clipboard operation
kit copied to clipboard

Make the routing even more powerful

Open carlosV2 opened this issue 1 year ago • 0 comments

Describe the problem

The solution proposed here attempts to provide a solution to multi-domain applications.

I find myself building a multi-domain application. Most of those domains render the same pages but the www one is intended to show the home webpage which is, obviously, different than the others.

Despite it has been thought for the purpose of multi-domain application, this solution could also come in hand in other situations. For example, having a different design (and load functions) depending on if the user is logged in or not.

Describe the proposed solution

As you know, SvelteKit has the concept of ParamMatcher. This is a great solution to provide placeholders for a route but, imho, it also serves a good purpose of filtering URLs out if they don't match the matcher.

Currently those matchers are very simple, they take the value they are supposed to replace and return a boolean value. The proposed solution is to augment this functionality by also supplying the Request object to them (and still return a boolean). This way, the matcher can verify additional information contained on the request to determine if the route is suitable for the URL. It is my believe that such addition should not be very hard (apologies if I'm wrong) since, currently, each matcher must be executed within a request context already.

In addition to the matchers update, I think this matcher concept could also be applied to the groups. In the end, a group is a sort of always-optional always-matching matcher so by allowing matchers into the groups, we could discard entire directories from the routes candidates dynamically.

Here is a directory tree example of a project that uses the proposed solution:

routes/
 |- (home=www)/
 |   |- +page.ts
 |   |- +page.svelte
 |   \- [language]/
 |       |- +page.ts
 |       \- +page.svelte
 \- (tenant=app)/
     |- +page.svelte
     \- [order=loggedin]/
         \- +page.svelte

In this example, the matchers would check the following:

  • www: Checks the domain starts with www.
  • app: Checks the domain does not start with www.
  • loggedin: Checks the user is logged in

Having the proposed changes the following URLs are unequivocally run:

  • www.domain.com/en: It runs the routes/(www=home)/[language] path and en is the value for language.
  • tenant.domain.com/abcd: It runs the routes/(app=tenant)/[order=loggedin] (only if the user is logged in) and abcd is the value for order.

In addition, only the selected route's load functions are run and those load functions can be simple and dedicated to the route they exist on.

Alternatives considered

There are a few alternatives to this:

  • Having a monorepo: This is a great alternative but it comes with increased overhead and requires additional knowledge and tooling.
  • Having the routes blended: This is, arguably, an awful solution. It requires each load function to be conscious of the fact that it can represent multiple options so they must run the required checks (the checks that would have been placed in the matchers otherwise) to determine which logic/view follow. This also adds complexity for static analysis tools like TS which can report a variable as not present or optional despite it can be mandatory for that route option.
  • Having completely separate projects: Again, this is a bad solution as it makes code sharing harder plus it can incur in additional costs when deployed into cloud solutions.

Importance

would make my life easier

Additional Information

I am aware that, currently, the groups have a bit more functionality than merely providing directory divisions. Maybe a better solution than using the groups for this would be to have special parameters. Currently there is the optional parameter [[param]] so, maybe, there could also be the "divisor" or "grouping" (yes, nomenclature clash, a better naming should be provided) parameter like, for example, [(param)].

carlosV2 avatar Jun 20 '23 20:06 carlosV2