Issue with authenticated routes, redirect and context
Hello, still having some trouble on how to structure my app and I'm getting some errors during navigation.
1) First problem is the first login after handling auth0 callback. After I redirect the user to the page they were when logging in with
layout.tsx
`
router.history.push I get an error on the function that use checks the context if the user is logged in, I need to refresh the page than it works. there error is "Invalid state" from the auth0 library and Warning: Error in route match: root
Here is what I have now:
main.tsx
const rootRoute = rootRouteWithContext<{
authClient: Auth0Client;
queryClient: QueryClient;
}>()({
component: lazyRouteComponent(() => import('./pages/Layout'), 'Layout'),
beforeLoad: async ({ context, location, search }) => {
const { code, state } = search
console.log("code:", code)
console.log("state:", state)
const isAuthenticated = await context.authClient.isAuthenticated();
console.log("isAuthenticated:", isAuthenticated)
if (code && state) {
var result = await context.authClient.handleRedirectCallback()
console.log("result:", result)
if (result.appState) {
//When I redirect here I get the error on the path, usualy /
throw router.history.push(result.appState.retturnTo)
}
}
if (!isAuthenticated) {
console.log("location.href:", location.pathname)
throw await context.authClient.loginWithRedirect({ appState: { returnTo: location.pathname } })
}
return {}
},
})
const calendarRoute = new Route({
getParentRoute: () => rootRoute,
path: '/',
component: lazyRouteComponent(() => import('./pages/CalendarPage')),
})
const routeTree = rootRoute.addChildren([calendarRoute])
const queryClient = new QueryClient();
const auth0 = new Auth0Client({
domain: domain,
clientId: clientId,
cacheLocation: 'localstorage',
authorizationParams: {
redirect_uri: callbackUri,
audience: audience,
scope: scope
}
});
const router = new Router({
routeTree,
defaultPendingComponent: () => <div>Loading...</div>,
defaultErrorComponent: ({ error }) => <ErrorComponent error={error} />,
context: {
authClient: auth0,
queryClient
}
})
const rootElement = document.getElementById('app')!
if (!rootElement.innerHTML) {
const root = ReactDOM.createRoot(rootElement)
root.render(
<StrictMode>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
</StrictMode>,
)
}
const rootRoute = rootRouteWithContext<{
authClient: Auth0Client;
queryClient: QueryClient;
}>()({
component: lazyRouteComponent(() => import('./pages/Layout'), 'Layout'),
beforeLoad: async ({ context, location, search }) => {
const { code, state } = search
console.log("code:", code)
console.log("state:", state)
const isAuthenticated = await context.authClient.isAuthenticated();
console.log("isAuthenticated:", isAuthenticated)
if (code && state) {
var result = await context.authClient.handleRedirectCallback()
console.log("result:", result)
if (result.appState) {
//When I redirect here I get the error on the path, usualy /
throw router.history.push(result.appState.retturnTo)
}
}
if (!isAuthenticated) {
console.log("location.href:", location.pathname)
throw await context.authClient.loginWithRedirect({ appState: { returnTo: location.pathname } })
}
return {}
},
})
const calendarRoute = new Route({
getParentRoute: () => rootRoute,
path: '/',
component: lazyRouteComponent(() => import('./pages/CalendarPage')),
})
const routeTree = rootRoute.addChildren([calendarRoute])
const queryClient = new QueryClient();
const auth0 = new Auth0Client({
domain: domain,
clientId: clientId,
cacheLocation: 'localstorage',
authorizationParams: {
redirect_uri: callbackUri,
audience: audience,
scope: scope
}
});
const router = new Router({
routeTree,
defaultPendingComponent: () => <div>Loading...</div>,
defaultErrorComponent: ({ error }) => <ErrorComponent error={error} />,
context: {
authClient: auth0,
queryClient
}
})
const rootElement = document.getElementById('app')!
if (!rootElement.innerHTML) {
const root = ReactDOM.createRoot(rootElement)
root.render(
<StrictMode>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
</StrictMode>,
)
}
import {
Outlet,
RouteApi
} from '@tanstack/react-router';
import React, { useEffect, useState } from 'react';
import { Loading } from "../components/Loading";
import "../index.css";
export const Layout = () => {
//this should let me get the context from root, where the context is for all the routes, right?
const routeApi = new RouteApi({ id: '__root__' })
const { authClient } = routeApi.useRouteContext()
console.log("authClient:", authClient)
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const checkAuth = async () => {
console.log("checkAuth")
const authStatus = await authClient.isAuthenticated();
console.log("authStatus:", authStatus)
if (authStatus) {
setIsLoading(false);
}
};
checkAuth();
}, [isLoading]);
if (isLoading) {
return <Loading />;
}
return (
<main className="flex min-h-full w-full h-full flex-col font-poppins">
<Outlet />
</main>
);
}
import {
Outlet,
RouteApi
} from '@tanstack/react-router';
import React, { useEffect, useState } from 'react';
import { Loading } from "../components/Loading";
import "../index.css";
export const Layout = () => {
//this should let me get the context from root, where the context is for all the routes, right?
const routeApi = new RouteApi({ id: '__root__' })
const { authClient } = routeApi.useRouteContext()
console.log("authClient:", authClient)
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const checkAuth = async () => {
console.log("checkAuth")
const authStatus = await authClient.isAuthenticated();
console.log("authStatus:", authStatus)
if (authStatus) {
setIsLoading(false);
}
};
checkAuth();
}, [isLoading]);
if (isLoading) {
return <Loading />;
}
return (
<main className="flex min-h-full w-full h-full flex-col font-poppins">
<Outlet />
</main>
);
}
0 Replies