# Kinde Auth NextJS SDK The Kinde Auth NextJS SDK provides a comprehensive authentication solution for Next.js applications, supporting both App Router and Pages Router architectures. This SDK implements OAuth 2.0 and OpenID Connect protocols to handle user authentication, authorization, session management, and multi-organization support. Built by Kinde, it offers seamless integration with minimal configuration required through environment variables. The SDK provides server-side session management, client-side React hooks and components, middleware for route protection, and utilities for managing feature flags, permissions, roles, and user organizations. It supports flexible authentication flows including login, registration, organization creation, and portal access, with built-in token refresh mechanisms and secure cookie-based session storage. ## APIs and Key Functions ### Authentication Handler Setup Server-side authentication handler that manages all OAuth 2.0 flows including login, logout, callback, registration, and organization creation. ```typescript // app/api/auth/[...kindeAuth]/route.ts import { handleAuth } from "@kinde-oss/kinde-auth-nextjs/server"; export const GET = handleAuth(); ``` ### Server Session Management Access authenticated user data and tokens on the server side in App Router components and API routes. ```typescript import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"; export default async function ServerComponent() { const { getUser, isAuthenticated, getPermission, getOrganization } = getKindeServerSession(); const isSignedIn = await isAuthenticated(); if (!isSignedIn) { return
Please log in
; } const user = await getUser(); const hasPermission = await getPermission("create:posts"); const organization = await getOrganization(); return (

Welcome {user.given_name} {user.family_name}

Email: {user.email}

Organization: {organization.orgName}

{hasPermission.isGranted && }
); } ``` ### Client-Side Authentication Provider Wrap your application with KindeProvider to enable client-side authentication hooks and automatic session synchronization. ```typescript // app/layout.tsx import { KindeProvider } from "@kinde-oss/kinde-auth-nextjs"; export default function RootLayout({ children }) { return ( {children} ); } ``` ### Client-Side Authentication Hook Access authentication state and user data in client components with automatic reactivity to session changes. ```typescript "use client"; import { useKindeBrowserClient } from "@kinde-oss/kinde-auth-nextjs"; export default function ClientComponent() { const { user, isAuthenticated, isLoading, getPermission, getBooleanFlag } = useKindeBrowserClient(); if (isLoading) return
Loading...
; if (!isAuthenticated) return
Not authenticated
; const canDelete = getPermission("delete:posts"); const darkMode = getBooleanFlag("theme_dark_mode", false); return (

User ID: {user.id}

Email: {user.email}

{canDelete?.isGranted && }
); } ``` ### Login and Logout Links Pre-built React components for authentication actions with optional redirect URLs and organization context. ```typescript import { LoginLink, LogoutLink, RegisterLink } from "@kinde-oss/kinde-auth-nextjs/components"; export default function NavBar() { return ( ); } ``` ### Middleware Route Protection Protect routes automatically using Next.js middleware to enforce authentication before page access. ```typescript // middleware.ts import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware"; export default function middleware(req) { return withAuth(req, { isReturnToCurrentPage: true, publicPaths: ["/", "/about", "/pricing"], orgCode: "org_abc123", loginPage: "/custom-login" }); } export const config = { matcher: ["/dashboard/:path*", "/profile/:path*", "/settings/:path*"] }; ``` ### Custom Middleware with Authorization Implement custom authorization logic in middleware with access to decoded tokens and user data. ```typescript // middleware.ts import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware"; import { NextResponse } from "next/server"; export default withAuth( async (req) => { const { token, user } = req.kindeAuth; // Custom authorization logic if (req.nextUrl.pathname.startsWith("/admin")) { const isAdmin = token.permissions.includes("admin:access"); if (!isAdmin) { return NextResponse.redirect(new URL("/unauthorized", req.url)); } } return NextResponse.next(); }, { isReturnToCurrentPage: true, publicPaths: ["/", "/about"] } ); export const config = { matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"] }; ``` ### Page-Level Protection Protect individual pages with role and permission-based access control in App Router. ```typescript import { protectPage } from "@kinde-oss/kinde-auth-nextjs/server"; async function AdminPage() { return (

Admin Dashboard

Only accessible to admins

); } export default protectPage(AdminPage, { roles: ["admin", "superadmin"], permissions: ["admin:access"], postLoginRedirectURL: "/admin", orgCode: "org_abc123" }); ``` ### API Route Protection Secure API routes with authentication and authorization checks returning appropriate HTTP status codes. ```typescript import { protectApi } from "@kinde-oss/kinde-auth-nextjs/server"; import { NextResponse } from "next/server"; async function handler(req) { const data = { message: "Sensitive data", timestamp: Date.now() }; return NextResponse.json(data); } export const GET = protectApi(handler, { permissions: ["read:data"], roles: ["user", "admin"] }); ``` ### Token Access Retrieve and decode access tokens and ID tokens for custom authorization or external API calls. ```typescript import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"; export async function GET() { const { getAccessToken, getAccessTokenRaw, getIdToken } = getKindeServerSession(); const accessToken = await getAccessToken(); const rawToken = await getAccessTokenRaw(); const idToken = await getIdToken(); // Use raw token for external API calls const response = await fetch("https://api.example.com/data", { headers: { Authorization: `Bearer ${rawToken}`, "Content-Type": "application/json" } }); return Response.json({ userId: accessToken.sub, email: idToken.email, permissions: accessToken.permissions, orgCode: accessToken.org_code }); } ``` ### Permission Checks Evaluate user permissions for fine-grained access control in server components and API routes. ```typescript import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"; export default async function PostEditor({ postId }) { const { getPermission, getPermissions } = getKindeServerSession(); const canEdit = await getPermission("edit:posts"); const canDelete = await getPermission("delete:posts"); const allPermissions = await getPermissions(); if (!canEdit.isGranted) { return
You don't have permission to edit posts
; } return (
{canDelete.isGranted && }

Organization: {allPermissions.orgCode}

All permissions: {allPermissions.permissions.join(", ")}

); } ``` ### Role Checks Retrieve and verify user roles for role-based access control in application logic. ```typescript import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"; export default async function AdminPanel() { const { getRoles } = getKindeServerSession(); const roles = await getRoles(); const isAdmin = roles?.some(role => role.key === "admin"); const isSuperAdmin = roles?.some(role => role.key === "superadmin"); if (!isAdmin && !isSuperAdmin) { return
Access denied
; } return (

Admin Panel

Active roles: {roles.map(r => r.name).join(", ")}

{isSuperAdmin && }
); } ``` ### Feature Flags Access feature flags from access tokens for gradual rollouts and A/B testing without backend calls. ```typescript import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"; export default async function FeatureComponent() { const { getBooleanFlag, getStringFlag, getIntegerFlag, getFlag } = getKindeServerSession(); const darkModeEnabled = await getBooleanFlag("theme_dark_mode", false); const apiVersion = await getStringFlag("api_version", "v1"); const maxUploads = await getIntegerFlag("max_uploads", 5); const complexFlag = await getFlag("feature_config", {}, "json"); return (

API Version: {apiVersion}

Upload Limit: {maxUploads} files

{complexFlag.value &&
{JSON.stringify(complexFlag.value, null, 2)}
}
); } ``` ### Organization Management Access current organization data and retrieve all organizations the user belongs to for multi-tenant applications. ```typescript import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"; import { CreateOrgLink } from "@kinde-oss/kinde-auth-nextjs/components"; export default async function OrganizationSelector() { const { getOrganization, getUserOrganizations } = getKindeServerSession(); const currentOrg = await getOrganization(); const allOrgs = await getUserOrganizations(); return (

Current Organization

Name: {currentOrg.orgName}

Code: {currentOrg.orgCode}

All Organizations ({allOrgs.orgCodes.length})

Create Organization
); } ``` ### Custom Claims Extract custom claims from access tokens or ID tokens for application-specific metadata. ```typescript import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"; export default async function CustomDataComponent() { const { getClaim } = getKindeServerSession(); const customUserId = await getClaim("custom_user_id", "access_token"); const subscriptionTier = await getClaim("subscription_tier", "access_token"); const emailVerified = await getClaim("email_verified", "id_token"); return (

Custom User ID: {customUserId.value}

Subscription: {subscriptionTier.value}

Email Verified: {emailVerified.value ? "Yes" : "No"}

); } ``` ### Environment Configuration Configure the SDK using environment variables in your `.env.local` file for secure credential management. ```bash # .env.local KINDE_CLIENT_ID=your_client_id KINDE_CLIENT_SECRET=your_client_secret KINDE_ISSUER_URL=https://yourdomain.kinde.com KINDE_SITE_URL=http://localhost:3000 KINDE_POST_LOGOUT_REDIRECT_URL=http://localhost:3000 KINDE_POST_LOGIN_REDIRECT_URL=http://localhost:3000/dashboard KINDE_COOKIE_DOMAIN=localhost ``` ### Pages Router Integration Use the SDK with Next.js Pages Router for authentication in traditional page-based applications. ```typescript // pages/api/auth/[...kindeAuth].ts import { handleAuth } from "@kinde-oss/kinde-auth-nextjs/server"; export default handleAuth(); // pages/dashboard.tsx import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"; export async function getServerSideProps(context) { const { getUser, isAuthenticated } = getKindeServerSession(context.req, context.res); const isSignedIn = await isAuthenticated(); if (!isSignedIn) { return { redirect: { destination: "/api/auth/login", permanent: false } }; } const user = await getUser(); return { props: { user } }; } export default function Dashboard({ user }) { return

Welcome {user.given_name}

; } ``` ### Management API Client Create a Kinde Management API client for administrative operations on users, organizations, and applications. ```typescript import { createKindeManagementAPIClient } from "@kinde-oss/kinde-auth-nextjs/server"; export async function POST(req) { const kindeClient = await createKindeManagementAPIClient(); try { // Create a new user const newUser = await kindeClient.usersApi.createUser({ profile: { given_name: "John", family_name: "Doe" }, identities: [{ type: "email", details: { email: "john.doe@example.com" } }] }); // Add user to organization await kindeClient.organizationsApi.addOrganizationUsers({ org_code: "org_abc123", users: [{ id: newUser.data.id }] }); return Response.json({ success: true, userId: newUser.data.id }); } catch (error) { return Response.json({ error: error.message }, { status: 500 }); } } ``` ## Use Cases and Integration The Kinde Auth NextJS SDK is designed for modern Next.js applications requiring secure authentication and authorization with minimal configuration. It's ideal for SaaS applications with multi-tenant architecture, supporting organization-based access control and user management. The SDK seamlessly handles both server-rendered and client-rendered content through its dual-mode architecture, making it suitable for applications using Next.js 12+ with either App Router or Pages Router patterns. Common integration patterns include protecting entire application sections using middleware, implementing role-based dashboards with server-side permission checks, managing multi-organization access with organization switchers, and integrating feature flags for gradual feature rollouts. The SDK's built-in token refresh mechanism ensures sessions remain valid without manual intervention, while the Management API client enables programmatic user provisioning and organization management for complex enterprise workflows. Support for custom claims and properties allows extension of user profiles with application-specific data.