Browse the docs
Quickstarts

Next.js quickstart

Wire OrthID into a Next.js App Router app. You will add the provider, middleware, a sign-in page, and server-side session reads, then protect a route.

This guide assumes the App Router (Next.js 13.4+). If you have not created a project and set your keys yet, do the five-minute Quickstart first, then come back. You should already have NEXT_PUBLIC_ORTHID_PUBLISHABLE_KEY, ORTHID_SECRET_KEY, and ORTHID_REGION in your environment.

1. Install the Next.js package

The @orthid/nextjs package adds the provider, middleware, and server helpers on top of the core SDK.

Terminal
npm install @orthid/nextjs

2. Wrap your app in the provider

Add <OrthIDProvider> to your root layout. It reads the publishable key, manages the session in the browser, and makes the OrthID hooks and components available everywhere in the tree.

app/layout.tsx
import { OrthIDProvider } from "@orthid/nextjs";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <OrthIDProvider
      publishableKey={process.env.NEXT_PUBLIC_ORTHID_PUBLISHABLE_KEY!}
    >
      <html lang="en">
        <body>{children}</body>
      </html>
    </OrthIDProvider>
  );
}

3. Add the middleware

The middleware verifies the session on every matched request and keeps the token fresh. Create middleware.ts at the project root (next to app/).

middleware.ts
import { orthidMiddleware } from "@orthid/nextjs";

export default orthidMiddleware();

export const config = {
  // Run on app routes and APIs, skip Next internals and static files.
  matcher: ["/((?!_next|.*\\..*).*)", "/api/(.*)"],
};
Note
The middleware only verifies and refreshes the session; it does not block anonymous traffic by default. You decide which routes require a signed-in actor in step 6.

4. Add a sign-in route

Drop the <SignIn/> component on a route. It renders the full authentication flow (passkeys, MFA, SSO) and handles the redirect back into your app on success. No extra wiring required.

app/sign-in/page.tsx
import { SignIn } from "@orthid/nextjs";

export default function SignInPage() {
  return (
    <main className="grid min-h-screen place-items-center">
      <SignIn afterSignInUrl="/dashboard" />
    </main>
  );
}

5. Read the user server-side

In a Server Component (or route handler), call currentUser() to read the signed-in actor. Because the middleware already verified the session, this is a fast, local lookup with no extra round trip.

app/dashboard/page.tsx
import { currentUser } from "@orthid/nextjs/server";

export default async function Dashboard() {
  const user = await currentUser();

  if (!user) {
    return <p>You are signed out.</p>;
  }

  return <h1>Welcome back, {user.firstName}.</h1>;
}

6. Protect a route

To require a signed-in actor, read the auth state and redirect when it is missing. Use auth() for a lightweight check that returns the actor id and session without loading the full user record.

app/settings/page.tsx
import { redirect } from "next/navigation";
import { auth } from "@orthid/nextjs/server";

export default async function Settings() {
  const { actorId } = await auth();

  if (!actorId) {
    redirect("/sign-in");
  }

  return <h1>Account settings</h1>;
}
Tip
Prefer to guard whole route segments in one place? Pass a matcher to orthidMiddleware with a list of protected paths and it will redirect anonymous requests for you, before they reach your components.

Next steps

  • <SignIn/> reference for props, hosted vs embedded modes, and theming.
  • Sessions to understand what the middleware verifies and refreshes.