S
SolidJS•7mo ago
mbork.pl

Where can I find any documentation about `RouteDefinition`?

I can see (in dist/types.d.ts) what properties it has, but I don't know what some of them are for. Or maybe I'm looking in the wrong place? What I need is to attach a "permission name" to each route, and then before rendering the component check if the logged in user has that permission. Is RouteDefinition.info the right place for that?
46 Replies
Brendonovich
Brendonovich•7mo ago
info is the place for that yeah
mbork.pl
mbork.plOP•7mo ago
thx and how would I know that? are there any docs on that?
Brendonovich
Brendonovich•7mo ago
i don't think so i just figured it out from playing with it
mbork.pl
mbork.plOP•7mo ago
ah
Brendonovich
Brendonovich•7mo ago
also fwiw you might be better off splitting the routes into groups and using a layout for each group to do the permission checks, so that you don't have to do it on every route
mbork.pl
mbork.plOP•7mo ago
good point, thx but how do I do that? via the children property? and more importantly, how do I access the info property of the component being rendered?
peerreynders
peerreynders•7mo ago
and more importantly, how do I access the info property
useCurrentMatches
GitHub
GitHub - solidjs/solid-router at a2652b4eab6576db78e6371e5c0aa45eea...
A universal router for Solid inspired by Ember and React Router - GitHub - solidjs/solid-router at a2652b4eab6576db78e6371e5c0aa45eea85d98d
mbork.pl
mbork.plOP•7mo ago
yeah, I've been looking at this for the past 15 minutes or so, but still can't figure out how to use it 😦 for starters, how do I import it?
peerreynders
peerreynders•7mo ago
but how do I do that?
Are using vanilla solid-router or SolidStart file routes?
mbork.pl
mbork.plOP•7mo ago
great question! no idea, I suppose the former (I'm not the original programmer who set up Solid in this project) definitely vanilla I tried import {useCurrentMatches} from '@solidjs/router';, but it says "module @solidjs.router has no exported member useCurrentMatches"
peerreynders
peerreynders•7mo ago
If you look at https://stackblitz.com/edit/stackblitz-starters-p8qprb?file=src%2Fapp.tsx You'll see
<Route path="/contract" component="{ContractLayout}">
<Route path="/" component="{Contract}" />
<Route path="/prepare" component="{Prepare}" />
</Route>
<Route path="/" component="{Home}" />
<Route path="*404" component="{NotFound}" />
<Route path="/contract" component="{ContractLayout}">
<Route path="/" component="{Contract}" />
<Route path="/prepare" component="{Prepare}" />
</Route>
<Route path="/" component="{Home}" />
<Route path="*404" component="{NotFound}" />
Contract and Prepare are nested inside of ContractLayout which is a layout that looks like this:
import type { ParentProps } from 'solid-js';
import { CounterProvider } from '../components/counter-context';

function ContractLayout(props: ParentProps) {
return <CounterProvider>{props.children}</CounterProvider>;
}

export { ContractLayout };
import type { ParentProps } from 'solid-js';
import { CounterProvider } from '../components/counter-context';

function ContractLayout(props: ParentProps) {
return <CounterProvider>{props.children}</CounterProvider>;
}

export { ContractLayout };
In this particular case this was done so that only the two nested routes have access to the particular provider that is shimmed in by the layout. Similarly checks could be done here to force an immediate Navigate to a less sensitive area in case anything was amiss.
peerreynders
StackBlitz
solidjs/router Layout for nested routes - StackBlitz
A Solid TypeScript project based on @solidjs/meta, @solidjs/router, solid-js, typescript, vite and vite-plugin-solid
mbork.pl
mbork.plOP•7mo ago
thanks a lot for your help it's a pity that it doesn't help me much... 1. We use "configuration-based routing" (https://docs.solidjs.com/solid-router/getting-started/defining-routes#configuration-based-routing), not the Route components (this is probably the least of the problems) 2. I can't see anything about accessing info here where should I look?
peerreynders
peerreynders•7mo ago
@solidjs.router has no exported member useCurrentMatches"
It was only introduced 3 weeks ago so you need 0.13.3
We use "configuration-based routing"
Doesn't matter, same idea.
mbork.pl
mbork.plOP•7mo ago
I thought so ok, thanks I upgraded @solidjs.router, and useCurrentMatches seems to work, thanks
Brendonovich
Brendonovich•7mo ago
your routes would look something like this
[
{
component: PermissionOneLayout,
children: [
{ path: "/permission-one-a", component: ... },
{ path: "/permission-one-b", component: ... },
]
},
{
component: PermissionTwoLayout,
children: [
{ path: "/permission-two-a", component: ... },
{ path: "/permission-two-b", component: ... },
]
}
]
[
{
component: PermissionOneLayout,
children: [
{ path: "/permission-one-a", component: ... },
{ path: "/permission-one-b", component: ... },
]
},
{
component: PermissionTwoLayout,
children: [
{ path: "/permission-two-a", component: ... },
{ path: "/permission-two-b", component: ... },
]
}
]
and the layouts would look something like this
function PermissionOneLayout(props) {
return (
<Show when={checkPermission()} fallback={<Navigate to=... />}
{props.children}
</Show>
)
}
function PermissionOneLayout(props) {
return (
<Show when={checkPermission()} fallback={<Navigate to=... />}
{props.children}
</Show>
)
}
this approach won't need info since the layouts do the permission check on behalf of all their children
mbork.pl
mbork.plOP•7mo ago
I see interesting though I might prefer the info route (pun not intended) because I have pretty many of those permissions
Brendonovich
Brendonovich•7mo ago
are you consuming the route info in a parent route and handling it there?
mbork.pl
mbork.plOP•7mo ago
and I assume that checkPermission() should in fact be a different function for each permission, right? not yet, I'm still figuring out how to get it in the component code
Brendonovich
Brendonovich•7mo ago
yeah that's up to you
mbork.pl
mbork.plOP•7mo ago
wait a second how does this tree-like structure work here? if both the parent and the child (in routes above) have the component property?
Brendonovich
Brendonovich•7mo ago
the children have unique paths path-less routes are basically invisible to the matching algorithm which is a whole beast in itself
mbork.pl
mbork.plOP•7mo ago
I have something like that:
[
{
path: '/',
component: Dashboard,
info: {
permission: 'dashboard',
},
},
{
path: '/article',
children: [
{
path: '/',
component: Articles,
},
{
path: '/:article_id',
component: EditArticles,
},
],
info: {
permission: 'articles',
},
},
]
[
{
path: '/',
component: Dashboard,
info: {
permission: 'dashboard',
},
},
{
path: '/article',
children: [
{
path: '/',
component: Articles,
},
{
path: '/:article_id',
component: EditArticles,
},
],
info: {
permission: 'articles',
},
},
]
and when I'm on /article, useCurrentMatches gives me 2 results instead of one am I doing this correctly? (there is nothing about how to do that in the docs, I'm basically doing it via trial and error... 😦 )
peerreynders
peerreynders•7mo ago
if both the parent and the child (in routes above) have the component property?
The components in a parent will be layout components (taking props.children) while only components in leaf routes are terminal.
Brendonovich
Brendonovich•7mo ago
yea the first match is the /article layout and the second is the / leaf route layout is a bit of a misnomer since you haven't supplied a component there but yeah
mbork.pl
mbork.plOP•7mo ago
ok, what is a "layout component"? I didn't find that term in the docs
Brendonovich
Brendonovich•7mo ago
i think the docs refer to them as nested routes
mbork.pl
mbork.plOP•7mo ago
so if I'm deeper in the nested component tree, the leaf and all its parents are the matches?
peerreynders
peerreynders•7mo ago
Correct So you should get access to the info on each level
mbork.pl
mbork.plOP•7mo ago
I see that makes sense although is not ideal in my use-case since it probably means that I'll need to define my permissions on each level and is it a good idea not to have any component on higher-level routes, only on the leaves? the first example in https://docs.solidjs.com/solid-router/concepts/nested-routes suggests so
Brendonovich
Brendonovich•7mo ago
oh if it's a good idea not to then call me a sinner haha, layout components are super useful they're perfectly fine to use dw
peerreynders
peerreynders•7mo ago
This works just fine
<Route path="/users">
<Route path="/" component={Users} />
<Route path="/:id" component={User} />
</Route>
<Route path="/users">
<Route path="/" component={Users} />
<Route path="/:id" component={User} />
</Route>
mbork.pl
mbork.plOP•7mo ago
yeah, I'm looking at that example right now and it doesn't make sense to me
Leaf nodes, or innermost Route components, are the only ones that become their own route.
what does that mean? and if this:
// This won't work the way you'd expect
<Route path="/users" component={Users}>
<Route path="/:id" component={User} />
</Route>
// This won't work the way you'd expect
<Route path="/users" component={Users}>
<Route path="/:id" component={User} />
</Route>
is not the way to go, why does useCurrentMatches return anything but the leaf?
peerreynders
peerreynders•7mo ago
This would have no definition for /users
<Route path="/users">
<Route path="/:id" component={User} />
</Route>
<Route path="/users">
<Route path="/:id" component={User} />
</Route>
Brendonovich
Brendonovich•7mo ago
if you want my 2c, these permissions should probably be defined through your data layer rather than in the router. when someone tries to load /article have the request that fetches/mutates the article check the user's permissions (either on the client just before the request or during the request on the server), and then act accordingly whether that's a redirect or toast or something. that way you're guaranteed to get the right permissions behaviour no matter where you consume that data.
mbork.pl
mbork.plOP•7mo ago
IOW, that example seems to suggest that I shouldn't give any components to the non-leaf routes, no?
peerreynders
peerreynders•7mo ago
It starts by saying "If the parent route needs to be it's own route".
mbork.pl
mbork.plOP•7mo ago
I already handle them on the backend like you say, and return 401 if needed, but I my feeling was that since user without permission X should not be able to do anything with Articles, they should not be even allowed to navigate there – and the router seems the obvious place to handle that, correct? yeah, it says so, and that's exactly what I don't understand – what does it mean "to be its own route"?
Brendonovich
Brendonovich•7mo ago
it probably is the obvious place to yeah but i think doing a fine-grained approach rather than applying route metadata is preferable
mbork.pl
mbork.plOP•7mo ago
maybe in general, yes, but probably not in my use-case we have an app which has about a dozen "modules"; each module has one or more routes/pages; and each user is permitted to access some set of modules so each permission maps precisely to a set of routes/pages
peerreynders
peerreynders•7mo ago
<Route path="/users" component={UsersLayout}>
<Route path="/" component={Users} />
<Route path="/:id" component={User} />
</Route>
<Route path="/users" component={UsersLayout}>
<Route path="/" component={Users} />
<Route path="/:id" component={User} />
</Route>
- Both /users and /users/[id] are nested inside UsersLayout - Users appears inside UsersLayout for /users - User appears inside UsersLayout for /users/[id] So Users and User are on their own routes while UsersLayout isn't on it's own route.
mbork.pl
mbork.plOP•7mo ago
so, does it mean that this:
// This won't work the way you'd expect
<Route path="/users" component={Users}>
<Route path="/:id" component={User} />
</Route>
// This won't work the way you'd expect
<Route path="/users" component={Users}>
<Route path="/:id" component={User} />
</Route>
means that if someone navigates to /users/1, something like this will be rendered?
<Users>
<User>
// ...
</User>
</Users>
<Users>
<User>
// ...
</User>
</Users>
peerreynders
peerreynders•7mo ago
Conceptually yes while at the same time /users isn't defined (no children).
peerreynders
peerreynders•7mo ago
Note on the other hand:
<Route path="/:id?" component={User} />
<Route path="/:id?" component={User} />
Optional Parameters
GitHub
GitHub - solidjs/solid-router: A universal router for Solid inspire...
A universal router for Solid inspired by Ember and React Router - solidjs/solid-router
mbork.pl
mbork.plOP•7mo ago
yeah, that makes sense OTOH, I've just encountered something that doesn't using my previous example
[
{
path: '/',
component: Dashboard,
info: {
permission: 'dashboard',
},
},
{
path: '/article',
children: [
{
path: '/',
component: Articles,
},
{
path: '/:article_id',
component: EditArticles,
},
],
info: {
permission: 'articles',
},
},
]
[
{
path: '/',
component: Dashboard,
info: {
permission: 'dashboard',
},
},
{
path: '/article',
children: [
{
path: '/',
component: Articles,
},
{
path: '/:article_id',
component: EditArticles,
},
],
info: {
permission: 'articles',
},
},
]
when I'm on /article, the /article/:article_id one seems to be also in the array returned by useCurrentMatches aaah now I get it I get two matches for another reason one because of the parent (/article) and one because of the leaf (/) correct?
peerreynders
peerreynders•7mo ago
Articles covers /article so there is nothing amiss here. Correct
Want results from more Discord servers?
Add your server