├── .env.local.example ├── .eslintrc.json ├── .gitignore ├── .prettierrc ├── README.md ├── next.config.js ├── package-lock.json ├── package.json ├── public ├── next.svg └── vercel.svg ├── src ├── app │ ├── account │ │ └── page.tsx │ ├── actions │ │ └── signOut.ts │ ├── api │ │ └── get-name │ │ │ └── route.ts │ ├── callback │ │ └── route.ts │ ├── components │ │ ├── footer.tsx │ │ └── sign-in-button.tsx │ ├── favicon.ico │ ├── layout.tsx │ ├── login │ │ └── route.ts │ └── page.tsx └── middleware.ts └── tsconfig.json /.env.local.example: -------------------------------------------------------------------------------- 1 | WORKOS_CLIENT_ID= 2 | WORKOS_API_KEY= 3 | NEXT_PUBLIC_WORKOS_REDIRECT_URI=http://localhost:3000/callback 4 | WORKOS_COOKIE_PASSWORD= 5 | 6 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "tabWidth": 2, 4 | "useTabs": false 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Next.js integration example using AuthKit 2 | 3 | An example application demonstrating how to authenticate users with AuthKit and the WorkOS Node SDK. 4 | 5 | > Refer to the [User Management](https://workos.com/docs/user-management) documentation for reference. 6 | 7 | ## Prerequisites 8 | 9 | You will need a [WorkOS account](https://dashboard.workos.com/signup). 10 | 11 | ## Running the example 12 | 13 | 1. In the [WorkOS dashboard](https://dashboard.workos.com), head to the Redirects tab and create a [sign-in callback redirect](https://workos.com/docs/user-management/1-configure-your-project/configure-a-redirect-uri) for `http://localhost:3000/callback` and set the app homepage URL to `http://localhost:3000`. 14 | 15 | 2. After creating the redirect URI, navigate to the API keys tab and copy the _Client ID_ and the _Secret Key_. Rename the `.env.local.example` file to `.env.local` and supply your Client ID and API key as environment variables. 16 | 17 | 3. Additionally, create a cookie password as the private key used to encrypt the session cookie. Copy the output into the environment variable `WORKOS_COOKIE_PASSWORD`. 18 | 19 | It has to be at least 32 characters long. You can use https://1password.com/password-generator/ to generate strong passwords. 20 | 21 | 4. Verify your `.env.local` file has the following variables filled. 22 | 23 | ```bash 24 | WORKOS_CLIENT_ID= 25 | WORKOS_API_KEY= 26 | WORKOS_COOKIE_PASSWORD= 27 | 28 | NEXT_PUBLIC_WORKOS_REDIRECT_URI=http://localhost:3000/callback 29 | ``` 30 | 31 | 5. Run the following command and navigate to [http://localhost:3000](http://localhost:3000). 32 | 33 | ```bash 34 | npm run dev 35 | ``` 36 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | module.exports = nextConfig; 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-authkit-example", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "reset": "rm -rf node_modules && rm -rf .next && npm i", 10 | "start-local-dev": "rm -rf .next && npm run prepare && npm run dev", 11 | "lint": "next lint", 12 | "prepare": "relative-deps" 13 | }, 14 | "dependencies": { 15 | "@radix-ui/react-icons": "^1.3.2", 16 | "@radix-ui/themes": "^3.2.1", 17 | "@workos-inc/authkit-nextjs": "^2.1.0", 18 | "next": "^15.2.3", 19 | "react": "^18", 20 | "react-dom": "^18" 21 | }, 22 | "devDependencies": { 23 | "@types/node": "^20", 24 | "@types/react": "^18", 25 | "@types/react-dom": "^18", 26 | "eslint": "^8.57.0", 27 | "eslint-config-next": "^14.2.5", 28 | "relative-deps": "^1.0.7", 29 | "typescript": "^5" 30 | }, 31 | "relativeDependencies": {} 32 | } 33 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/account/page.tsx: -------------------------------------------------------------------------------- 1 | import { withAuth } from "@workos-inc/authkit-nextjs"; 2 | import { Text, Heading, TextField, Flex, Box } from "@radix-ui/themes"; 3 | 4 | export default async function AccountPage() { 5 | const { user, role, permissions } = await withAuth({ ensureSignedIn: true }); 6 | 7 | const userFields = [ 8 | ["First name", user?.firstName], 9 | ["Last name", user?.lastName], 10 | ["Email", user?.email], 11 | role ? ["Role", role] : [], 12 | permissions ? ["Permissions", permissions] : [], 13 | ["Id", user?.id], 14 | ].filter((arr) => arr.length > 0); 15 | 16 | return ( 17 | <> 18 | 19 | 20 | Account details 21 | 22 | 23 | Below are your account details 24 | 25 | 26 | 27 | {userFields && ( 28 | 29 | {userFields.map(([label, value]) => ( 30 | 31 | 40 | 41 | ))} 42 | 43 | )} 44 | 45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /src/app/actions/signOut.ts: -------------------------------------------------------------------------------- 1 | "use server"; 2 | 3 | import { signOut } from "@workos-inc/authkit-nextjs"; 4 | 5 | export const handleSignOutAction = async () => { 6 | await signOut(); 7 | }; 8 | -------------------------------------------------------------------------------- /src/app/api/get-name/route.ts: -------------------------------------------------------------------------------- 1 | import { authkit } from "@workos-inc/authkit-nextjs"; 2 | import { NextRequest, NextResponse } from "next/server"; 3 | 4 | export const GET = async (request: NextRequest) => { 5 | // Use 'authkit' for edge functions that don't have access to headers 6 | const { session } = await authkit(request); 7 | 8 | if (!session || !session.user) { 9 | return NextResponse.json({ error: "User not found" }, { status: 404 }); 10 | } 11 | 12 | return NextResponse.json({ name: session.user.firstName }); 13 | }; 14 | -------------------------------------------------------------------------------- /src/app/callback/route.ts: -------------------------------------------------------------------------------- 1 | import { handleAuth } from "@workos-inc/authkit-nextjs"; 2 | 3 | export const GET = handleAuth(); 4 | -------------------------------------------------------------------------------- /src/app/components/footer.tsx: -------------------------------------------------------------------------------- 1 | import { Card, Grid, Heading, Text } from "@radix-ui/themes"; 2 | 3 | export function Footer() { 4 | return ( 5 | 6 | 7 | 8 | 9 | Documentation 10 | 11 | 12 | View integration guides and SDK documentation. 13 | 14 | 15 | 16 | 17 | 22 | 23 | API Reference 24 | 25 | 26 | Every WorkOS API method and endpoint documented. 27 | 28 | 29 | 30 | 31 | 32 | 33 | WorkOS 34 | 35 | Learn more about other WorkOS products. 36 | 37 | 38 | 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /src/app/components/sign-in-button.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | /** 4 | * Example of a client component using the useAuth hook to get the current user session. 5 | */ 6 | 7 | import { Button, Flex } from "@radix-ui/themes"; 8 | import { useAuth } from "@workos-inc/authkit-nextjs/components"; 9 | import { handleSignOutAction } from "../actions/signOut"; 10 | 11 | export function SignInButton({ large }: { large?: boolean }) { 12 | const { user, loading } = useAuth(); 13 | 14 | if (loading) { 15 | return
Loading...
; 16 | } 17 | 18 | if (user) { 19 | return ( 20 | 21 |
22 | 25 |
26 |
27 | ); 28 | } 29 | 30 | return ( 31 | 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/workos/next-authkit-example/413db73338d1573d2670d712eec1e1ebb5bbc024/src/app/favicon.ico -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | // Import the base CSS styles for the radix-ui components. 2 | import "@radix-ui/themes/styles.css"; 3 | 4 | import type { Metadata } from "next"; 5 | import NextLink from "next/link"; 6 | import { Theme, Card, Container, Flex, Button, Box } from "@radix-ui/themes"; 7 | import { Footer } from "./components/footer"; 8 | import { SignInButton } from "./components/sign-in-button"; 9 | import { 10 | AuthKitProvider, 11 | Impersonation, 12 | } from "@workos-inc/authkit-nextjs/components"; 13 | 14 | export const metadata: Metadata = { 15 | title: "Example AuthKit Authenticated App", 16 | description: "Example Next.js application demonstrating how to use AuthKit.", 17 | }; 18 | 19 | export default function RootLayout({ 20 | children, 21 | }: { 22 | children: React.ReactNode; 23 | }) { 24 | return ( 25 | 26 | 27 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | 42 | 45 | 46 | 49 | 50 | 51 | 52 |
53 |
54 | 55 | 56 |
{children}
57 |
58 |
59 |
60 |
61 |