@dariomvg/create
clerkautenticacionnextjsoauthintegracion

Módulo de Auth — Clerk (Next.js 16 / App Router)

Módulo de autenticación construido sobre @clerk/nextjs (Core 3 / v7).

Dependencias

  • @clerk/nextjs

Mapa de archivos

proxy.ts                                  # Route protection (Next.js 16 middleware replacement)
app/
├── sign-in/[[...sign-in]]/page.tsx       # Sign-in page (see client.ts for the component)
└── sign-up/[[...sign-up]]/page.tsx       # Sign-up page (see client.ts for the component)

lib/clerk/
├── service.ts   # Server-only logic. Don't touch — everything else calls into this.
├── actions.ts   # Server Actions for Server Components ("use server")
├── types.ts     # AuthUser, AuthSession, AuthResult<T>
└── client.ts    # Client component/hook re-exports + copy-paste usage examples

.env.local       # Clerk keys and URLs
Necesito...Ir a
Obtener el usuario actual en un Server Componentlib/clerk/service.ts → getUser() / requireUser()
Llamar a auth desde un Server Component (botón, formulario)lib/clerk/actions.ts
Agregar un tipo para algo relacionado con authlib/clerk/types.ts
Renderizar <SignIn/>, <SignUp/>, <UserButton/>, <Show/>, o usar un hook de clientelib/clerk/client.ts
Cambiar qué rutas son públicas/protegidasproxy.ts (raíz del proyecto)

Configuración

1. Variables de entorno

Completá .env.local con las keys de tu instancia de Clerk (Dashboard → API Keys):

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=

2. Envolvé la app con ClerkProvider

// app/layout.tsx
import { ClerkProvider } from "@/lib/clerk/client";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <ClerkProvider>
      <html lang="en">
        <body>{children}</body>
      </html>
    </ClerkProvider>
  );
}

3. Páginas de inicio de sesión / registro

Ya están cubiertas por app/sign-in/[[...sign-in]]/page.tsx y app/sign-up/[[...sign-up]]/page.tsx: mirá client.ts para ver el código exacto del componente que tenés que pegar.

4. proxy.ts

Ya está configurado en la raíz del proyecto. createRouteMatcher() está deprecado, por lo que ya no decide qué es público o privado: solo adjunta el contexto de sesión de Clerk a cada request. La protección real ocurre por recurso: llamá a requireUser() de lib/clerk/service.ts al principio de cualquier Server Component, Server Action o Route Handler que necesite un usuario con sesión iniciada. Una página es "pública" simplemente porque nada en ella llama a requireUser().

Checklist del Clerk Dashboard

Configurá esto directamente en el Dashboard: no hace falta código de este lado:

  • Inicio de sesión con email + contraseña habilitado
  • Verificación de email habilitada
  • Flujo de olvidé mi contraseña / restablecer contraseña habilitado
  • Proveedores OAuth conectados: Google, GitHub, Apple, Facebook
  • Los paths de inicio de sesión/registro en Dashboard → Paths coinciden con /sign-in y /sign-up

No incluido en este módulo (fuera de alcance): Magic Link, MFA/2FA, Passkeys, roles/permisos, organizaciones.

Ejemplos de uso

Proteger un Server Component:

import { requireUser } from "@/lib/clerk/service";

export default async function DashboardPage() {
  const user = await requireUser(); // redirects to /sign-in if not authenticated
  return <p>Welcome, {user.firstName}</p>;
}

Menú de usuario (avatar, perfil, cerrar sesión):

import { UserButton } from "@/lib/clerk/client";

<UserButton />

Cerrar sesión desde una Server Action:

import { signOutAction } from "@/lib/clerk/actions";

<form action={signOutAction}>
  <button type="submit">Sign out</button>
</form>

Mostrar contenido según el estado de la sesión:

import { Show } from "@/lib/clerk/client";

<Show when="signed-in">You're logged in</Show>
<Show when="signed-out">Please sign in</Show>