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 (
+
+