#Redirecting unauthenticated users? Convex Auth + TanStack Router

1 messages · Page 1 of 1 (latest)

coral ingot
#

Hi! Hopefully this is an easy one, but I'm new to both Convex, TanStack, and this is my first time ever setting up authentication! So trying to follow best pratices and reading but getting a little lost.

I have a /settings route and I want to redirect unauthenticated users away to /signin. I found the docs in TanStack Router for how to set up a redirect on beforeLoad but I don't know how to check for isAuthenticated() using Convex Auth. Help?

https://tanstack.com/router/latest/docs/framework/react/guide/authenticated-routes#redirecting

Authentication is an extremely common requirement for web applications. In this guide, we'll walk through how to use TanStack Router to build protected routes, and how to redirect users to login if they try to access them.

The route.beforeLoad Option

coral ingot
#

Would love to see a best-practice example of managing authentication and loading state for a page

coral ingot
#

Ah, I was able to get this set up.

In main.tsx:

import { ConvexAuthProvider } from "@convex-dev/auth/react";
import { RouterProvider, createRouter } from "@tanstack/react-router";
import { ConvexReactClient, useConvexAuth } from "convex/react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { routeTree } from "./routeTree.gen";

const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL);

const router = createRouter({
  routeTree,
  context: {
    auth: undefined!,
  },
});

declare module "@tanstack/react-router" {
  interface Register {
    router: typeof router;
  }
}

const InnerApp = () => {
  const auth = useConvexAuth();
  return <RouterProvider router={router} context={{ auth }} />;
};

const rootElement = document.getElementById("root")!;
if (!rootElement.innerHTML) {
  const root = createRoot(rootElement);
  root.render(
    <StrictMode>
      <ConvexAuthProvider client={convex}>
        <InnerApp />
      </ConvexAuthProvider>
    </StrictMode>,
  );
}

In routes/__root.tsx:

import {
  Outlet,
  createRootRouteWithContext,
} from "@tanstack/react-router";
import { TanStackRouterDevtools } from "@tanstack/router-devtools";
// ConvexAuthState keeps everything typesafe
import type { ConvexAuthState } from "convex/react";
import { RouterProvider } from "react-aria-components";

// Pass down type definitions
interface RouterContext {
  auth: ConvexAuthState;
}

export const Route = createRootRouteWithContext<RouterContext>()({
  component: Root,
});

function Root() {
  return (
    <>
      <Outlet />
      <TanStackRouterDevtools />
    </>
  );
}

On routes/settings.tsx:

import { createFileRoute, redirect } from "@tanstack/react-router";

export const Route = createFileRoute("/settings")({
  beforeLoad: ({ context }) => {
    // context.auth includes type safety and Intellisense
    if (!context.auth.isAuthenticated) {
      throw redirect({
        to: "/signin",
      });
    }
  },
  component: SettingsRoute,
});

function SettingsRoute() {
  // ...
}
cinder tree
#

Thanks for sharing this @coral ingot! This is helpful for providing instructions about this, which hopefully get up this week.