Next.js Quickstart
Use this guide to add ThunderID authentication to a Next.js application using the @thunderid/nextjs SDK with full App Router support.
What You Will Learn
- Create a new Next.js app
- Install the
@thunderid/nextjspackage
- Add working sign-in and sign-out
- Protect routes with middleware
Prerequisites
- About 15 minutes
- Node.js installed on your system
- npm, yarn, or pnpm
- Your preferred code editor
Run ThunderID
Start a local ThunderID instance. Pick the method that works best for you:
Requires Node.js 18+
Full install guide →Once it's running, the console is available at https://localhost:8090/console.
Create an Application
-
Sign in to the Console.
Test UserIf you used the default setup, sign in to the Console as
adminwith the password generated during setup and printed to the setup output (unless you supplied your own). -
Navigate to Applications, and click Add Application.
-
Under Technology, select Next.js.
-
Enter a name (e.g.
My Next.js App) and create an application. The rest of the settings can stay at their defaults. -
Copy both the Client ID and Client Secret from the window that pops up. The Client ID can also be found in the General tab.
-
Under General, add
http://localhost:3000to the list of Authorized Redirect URIs.
Create a Next.js App
Create your new Next.js app:
npm
Yarn
pnpm
npx create-next-app@latest my-nextjs-app
cd my-nextjs-app
yarn create next-app my-nextjs-app
cd my-nextjs-app
pnpm create next-app my-nextjs-app
cd my-nextjs-app
When prompted, select the App Router option (the default).
Install @thunderid/nextjs
Install the ThunderID Next.js SDK in your project:
npm
Yarn
pnpm
npm install @thunderid/nextjs
yarn add @thunderid/nextjs
pnpm add @thunderid/nextjs
Set Environment Variables
Create a .env.local file in your project root with the following:
Replace <your-client-id> and <your-client-secret> with the values from your ThunderID application.
Generate a random string for THUNDERID_SECRET (at least 32 characters):
openssl rand -base64 32
NEXT_PUBLIC_THUNDERID_BASE_URL=https://localhost:8090
NEXT_PUBLIC_THUNDERID_CLIENT_ID=<your-client-id>
THUNDERID_CLIENT_SECRET=<your-client-secret>
THUNDERID_SECRET=<a-random-secret-for-session-signing>
# DANGER: Disables ALL TLS verification. Only for local development with self-signed certs. NEVER use in production.
NODE_TLS_REJECT_UNAUTHORIZED=0
Add ThunderIDProvider to Your Layout
Wrap your root layout with ThunderIDProvider from the server export. This enables authentication across your entire app.
ThunderIDProvider handles the OAuth callback automatically, so no manual callback route is needed. Make sure the authorized redirect URL in your ThunderID application settings is set to http://localhost:3000.
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import { ThunderIDProvider } from '@thunderid/nextjs/server'
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html
lang="en"
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
>
<body className="min-h-full flex flex-col">
<ThunderIDProvider>{children}</ThunderIDProvider>
</body>
</html>
);
}
Add the ThunderID Proxy
Create a proxy.ts file at your project root to proxy requests through ThunderID and protect routes:
import {
thunderIDProxy,
createRouteMatcher,
} from '@thunderid/nextjs/server'
const isProtectedRoute = createRouteMatcher([
// Add the paths you want to protect, e.g. '/dashboard(.*)'
])
export default thunderIDProxy(async (thunderid, request) => {
if (isProtectedRoute(request)) {
await thunderid.protectRoute()
}
})
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
}
Build with ThunderID components
Update your home page with ThunderID authentication components:
import { SignedIn, UserDropdown, SignedOut, SignInButton } from "@thunderid/nextjs";
export default function Home() {
return (
<section className="flex flex-col items-center justify-center min-h-screen py-2">
<SignedIn>
<UserDropdown />
</SignedIn>
<SignedOut>
<SignInButton>Sign In</SignInButton>
</SignedOut>
</section>
);
}
Run Your App
Start the development server:
npm
Yarn
pnpm
npm run dev
yarn dev
pnpm dev
Visit your app at http://localhost:3000
You should see the sign-in button. Click it to be redirected to the ThunderID-hosted sign-in page. Authenticate with the test user you created in step 2, then return to your app with the user dropdown displayed.