diff --git a/app/root.tsx b/app/root.tsx index 16abf0e..a4d8ca2 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -1,5 +1,5 @@ import { ClerkProvider, Show, UserButton, SignInButton } from '@clerk/react-router'; -import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router' +import { isRouteErrorResponse, Link, Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router' import { clerkMiddleware, rootAuthLoader } from '@clerk/react-router/server' import type { Route } from './+types/root' @@ -53,6 +53,7 @@ export default function App({ loaderData }: Route.ComponentProps) { {/* Show the user button when the user is signed in */} + Protected diff --git a/app/routes.ts b/app/routes.ts index 102b402..b38f10d 100644 --- a/app/routes.ts +++ b/app/routes.ts @@ -1,3 +1,6 @@ -import { type RouteConfig, index } from "@react-router/dev/routes"; +import { type RouteConfig, index, route } from "@react-router/dev/routes"; -export default [index("routes/home.tsx")] satisfies RouteConfig; +export default [ + index("routes/home.tsx"), + route("protected", "routes/protected.tsx"), +] satisfies RouteConfig; diff --git a/app/routes/protected.tsx b/app/routes/protected.tsx new file mode 100644 index 0000000..9d94970 --- /dev/null +++ b/app/routes/protected.tsx @@ -0,0 +1,26 @@ +import { redirect } from 'react-router' +import { getAuth } from '@clerk/react-router/server' +import type { Route } from './+types/protected' + +export async function loader(args: Route.LoaderArgs) { + // Use `getAuth()` to read the session on the server and protect this route. + // Unlike the `` component, which only controls what renders, this is + // the real access check: a signed-out user who navigates here is redirected. + const { isAuthenticated, userId } = await getAuth(args) + + if (!isAuthenticated) { + return redirect('/') + } + + return { userId } +} + +export default function Protected({ loaderData }: Route.ComponentProps) { + return ( +
+

+ Welcome! Your user ID is {loaderData.userId}. +

+
+ ) +}