S
SolidJS3mo ago
kaxa

Can't find replace attribute on <Navigate />

This is basically my code, I am trying to check if the user is authenticated, if not then redirect to login page.
export const ProtectedRoute: ParentComponent = (props) => {
const { authed } = useAuth();

return authed() ? (
props.children
) : (
<Navigate href={"/login"} state={{ from: location }} />
);
};
export const ProtectedRoute: ParentComponent = (props) => {
const { authed } = useAuth();

return authed() ? (
props.children
) : (
<Navigate href={"/login"} state={{ from: location }} />
);
};
However, the problem is, I can't set replace attribute to <Navigate /> component. is there any other way to achieve same thing with or without <Navigate />
13 Replies
peerreynders
peerreynders3mo ago
useNavigate Basically use the returned navigate function even before you start rendering and set replace: true in the options argument.
kaxa
kaxa3mo ago
export const ProtectedRoute: ParentComponent = (props) => {
const { authed } = useAuth();
const navigate = useNavigate();
const location = useLocation();

if (!authed())
navigate("/login", {
replace: true,
state: { from: location.pathname },
});

return props.children;
};
export const ProtectedRoute: ParentComponent = (props) => {
const { authed } = useAuth();
const navigate = useNavigate();
const location = useLocation();

if (!authed())
navigate("/login", {
replace: true,
state: { from: location.pathname },
});

return props.children;
};
yep this works
Brendonovich
Brendonovich3mo ago
i'd suggest returning <>{props.children}</> as accessing children outside of jsx can cause issues
kaxa
kaxa3mo ago
I've refactored code to this:
export const RequireAuth: ParentComponent<{ allowedRoles: string[] }> = (
props
) => {
const { accessToken } = useAuth();
const navigate = useNavigate();
const location = useLocation();
const decoded = accessToken()
? (jwtDecode(accessToken()) as DecodedToken)
: undefined;
const role = decoded?.role || "";

// Check if the user's role is included in the allowedRoles array
const includesRole = props.allowedRoles.includes(role);

// Redirect to login page if user is not authenticated
if (!accessToken())
navigate("/login", {
replace: true,
state: { from: location.pathname },
});
// Redirect to unauthorized page if user does not have required role
else if (!includesRole)
navigate("/unauthorized", {
replace: true,
state: { from: location.pathname },
});
else return props.children;
};
export const RequireAuth: ParentComponent<{ allowedRoles: string[] }> = (
props
) => {
const { accessToken } = useAuth();
const navigate = useNavigate();
const location = useLocation();
const decoded = accessToken()
? (jwtDecode(accessToken()) as DecodedToken)
: undefined;
const role = decoded?.role || "";

// Check if the user's role is included in the allowedRoles array
const includesRole = props.allowedRoles.includes(role);

// Redirect to login page if user is not authenticated
if (!accessToken())
navigate("/login", {
replace: true,
state: { from: location.pathname },
});
// Redirect to unauthorized page if user does not have required role
else if (!includesRole)
navigate("/unauthorized", {
replace: true,
state: { from: location.pathname },
});
else return props.children;
};
should i still wrap props.children to empty jsx tags?
Brendonovich
Brendonovich3mo ago
Yeah Just to be safe
kaxa
kaxa3mo ago
Ok, it works but I had no issues without it Thanks for tip
Brendonovich
Brendonovich3mo ago
Yea it's entirely possible that it's fine without it, but if by chance children changed then that wouldn't be reflected
kaxa
kaxa3mo ago
I have one more question, you may know
const PersistLogin: ParentComponent = (props) => {
const [isLoading, setIsLoading] = createSignal(true);

const refresh = useRefreshToken();

const { accessToken } = useAuth();

// Resolve children when loading is completed
const resolved = children(() => !isLoading() && props.children);

... // code that sets loading state

// Show component when loading is completed
return <Show when={!isLoading()}>{resolved()}</Show>;
};
const PersistLogin: ParentComponent = (props) => {
const [isLoading, setIsLoading] = createSignal(true);

const refresh = useRefreshToken();

const { accessToken } = useAuth();

// Resolve children when loading is completed
const resolved = children(() => !isLoading() && props.children);

... // code that sets loading state

// Show component when loading is completed
return <Show when={!isLoading()}>{resolved()}</Show>;
};
Is this the correct way to resolve children, so it should proceed only when loading state has been set to false I'm not sure if this will cause issues as well
Brendonovich
Brendonovich3mo ago
Doing the isLoading check inside children() is just doing double work, I'm not sure if it's actually bad but it's defs not necessary
kaxa
kaxa3mo ago
I've tried without it, and it didn't show children
Brendonovich
Brendonovich3mo ago
That's good right? this should be fine
return <Show when={!isLoading()}>{props.children}</Show>;
return <Show when={!isLoading()}>{props.children}</Show>;
kaxa
kaxa3mo ago
Oh yeah, that totally works haha Thank you very much I've noticed that
return <Show when={!isLoading()}>{props.children}</Show>;
return <Show when={!isLoading()}>{props.children}</Show>;
and
const resolved = children(() => !isLoading() && props.children);

return <>{resolved()}</>;
const resolved = children(() => !isLoading() && props.children);

return <>{resolved()}</>;
do the same thing
Brendonovich
Brendonovich3mo ago
checks out
Want results from more Discord servers?
Add your server
More Posts
Solid-CLI won't create any projectWhen creating using `node` (either via `npx` or `bunx`) the CLI fails simply stating 'something wentcreateEffect is reactive, JSX isn't``` export const SavedLineView = (props: { loading: Accessor<boolean> }) => { createEffect(() => {Restricte route by user role, possibly a middleware?Hello, I would appreciate some assistance from more experienced web developers, if possible. My issNavigating with A from and to dynamic route doesn't re-render.I have a dynamic route `routes/post/[postid].tsx`. Within this route I have (simplified) ```tsx consIs it possible to get createAsync to revaluate/ refetch data like createResource?I see the example [here](https://github.com/solidjs/solid-router?tab=readme-ov-file#createasync) but[solved] Can't use `@solidjs/router` in external package for SolidStartI'm trying to write a library for my SolidStart project & need to use the `A` component exported froSeems like I found a JSX bugAs long I know, you can add up variables and raw text inside a tag, something like: `<p>{myVar} peopHow can I protect nothing ever breaks, while the setTimeout is waiting```tsx createEffect(() => { if (puzzle_lala().is_revealed && is_jump_to_next_puzzle_immeCanonical way to handle exceptions in async functions to perform redirect?Hi folks, I'm very new to solid and frontend development hence my question. I have a class that talk[solved]Issue with Solid Start MDX Project: 404 Error for New PageHello, I have created a Solid Start project using the “with MDX” mode. By default, the navigation in