"Quickstart: Next.js"
Protect a Next.js app with sign-in in about 10 minutes.
By the end of this page you'll have:
- a Next.js app with Sign in and Sign up buttons
- a
/dashboardpage only signed-in users can open - an API route that knows who is calling it
Note This guide assumes Next.js 15 or 16 with the App Router (the app/ directory). Using something else? See Express, Hono and other servers.
1. Get your keys
Every app gets an instance with two keys. In the developer dashboard, create an instance, add http://localhost:3001 under Settings > Allowed origins, and copy the keys from the Overview and API keys tabs.
Instance: ins_…
Publishable key: pk_test_…
Secret key: sk_test_… (shown once; store it in your secrets manager)Warning The secret key is only shown once. Copy it now. If you lose it, create a new one.
2. Install the SDK
npm install @daywalker/auth3. Add your environment variables
Create .env.local in the root of your Next.js app:
NEXT_PUBLIC_DAYWALKER_PUBLISHABLE_KEY=pk_test_...
NEXT_PUBLIC_DAYWALKER_AUTH_URL=http://localhost:3000
DAYWALKER_SECRET_KEY=sk_test_...- Variables starting with
NEXT_PUBLIC_are bundled into browser code. That's fine for the publishable key and URL. DAYWALKER_SECRET_KEYhas no prefix on purpose. Next.js keeps it on the server.
Warning Never rename it to NEXT_PUBLIC_DAYWALKER_SECRET_KEY. That would publish your secret key to every visitor.
4. Wrap your app in <AuthProvider>
AuthProvider loads the current session and keeps it fresh. Every auth component and hook must be inside it, so put it in your root layout:
// app/layout.tsx
import { AuthProvider } from "@daywalker/auth/react";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<AuthProvider>{children}</AuthProvider>
</body>
</html>
);
}5. Add sign-in and user buttons
// app/header.tsx
"use client";
import { SignedIn, SignedOut, SignInButton, UserButton } from "@daywalker/auth/react";
export function Header() {
return (
<header>
<SignedOut>
<SignInButton />
<SignInButton mode="sign-up">Create account</SignInButton>
</SignedOut>
<SignedIn>
<UserButton afterSignOutUrl="/" />
</SignedIn>
</header>
);
}<SignedOut>and<SignedIn>show their children only in that state.<SignInButton>sends the user to the hosted sign-in page and brings them back to the same page afterwards.<UserButton>shows the user's initials and a menu with Sign out.
Render <Header /> from your layout or a page. Run npm run dev and try signing up.
6. Protect pages and API routes
Create proxy.ts next to your app/ folder. It's named middleware.ts on Next.js 15.
// proxy.ts
import { authProxy } from "@daywalker/auth/nextjs";
export default authProxy({ protect: ["/dashboard*", "/api/private*"] });
export const config = { matcher: ["/((?!_next|favicon.ico).*)"] };"/dashboard*"matches/dashboardand everything under it.- A signed-out visitor to a protected page is redirected to sign-in, then returned.
- A signed-out request to a protected API route (anything under
/api) gets401 Unauthorized.
7. Use the user on the server
auth() works in Server Components, Route Handlers and Server Actions:
// app/dashboard/page.tsx
import { auth, backend } from "@daywalker/auth/nextjs";
export default async function Dashboard() {
const { userId } = await auth();
if (!userId) return null; // proxy.ts already redirects signed-out users
const user = await backend().users.get(userId);
return <h1>Welcome, {user.firstName ?? user.emailAddresses[0].email}</h1>;
}// app/api/private/orders/route.ts
import { auth } from "@daywalker/auth/nextjs";
export async function GET() {
const { userId } = await auth();
if (!userId) return Response.json({ error: "Not signed in" }, { status: 401 });
return Response.json({ orders: await getOrdersFor(userId) });
}You're done
Sign in, open /dashboard, then sign out and try again. You'll be sent to sign in first.
Next steps
- How it works: what happens behind the scenes.
- Call your own API: send the session token from client components.
- Email verification: require a confirmed email.