Skip to main content

Integrate authentication into Next.js

This guide shows how to create a simple Next.js application and secure it with authentication powered by Ory. The guide provides the setup for using Ory Network, but the code can be used with both Ory Network and self-hosted Ory software.

This guide is perfect for you if:

  1. You have Next.js installed.
  2. You want to build an app using Next.js.
  3. You want to give access to your application to signed-in users only.

Before you start, watch this video to see the user flow you're going to implement:

info

You can find the code of the sample application here.

Create Next.js app

First, create a new Next.js project. Run:

npx create-next-app@latest
cd app-name

When prompted, select the following options:

  • Use TypeScript: Yes
  • Use ESLint: Yes
  • Use Tailwind CSS: Yes
  • Use src/ directory: No
  • Use App Router: Yes
  • Customize the default import alias: No

Create a new Ory project

  1. Create an Ory account at https://console.ory.sh
  2. Create a new project at https://console.ory.sh/projects/create
  3. Go to your project settings
https://console.ory.sh/projects/<id>/settings

Project settings tab

  1. Note down your project credentials (ID, slug, endpoint)
https://console.ory.sh/projects/<id>/settings

Project credentials

Add Ory URL to environment variables

Add the following environment variables to your .env file:

NEXT_PUBLIC_ORY_SDK_URL=https://$PROJECT_SLUG.projects.oryapis.com

Install Ory SDK

To interact with Ory's APIs we install the Ory SDK:

npm i --save @ory/elements-react @ory/nextjs

Authenticate user

To implement authentication, create the following files:

ory.config.ts
// Copyright © 2024 Ory Corp

import type { OryConfig } from "@ory/nextjs"

const config: OryConfig = {
override: {
applicationName: "Ory Next.js App Router Example",
loginUiPath: "/auth/login",
registrationUiPath: "/auth/registration",
recoveryUiPath: "/auth/recovery",
verificationUiPath: "/auth/verification",
settingsUiPath: "/settings",
defaultRedirectUri: "/",
},
}

export default config

This configuration file defines the paths for login, registration, and other authentication pages in your Next.js application.

middleware.ts
// Copyright © 2024 Ory Corp

import { createOryMiddleware } from "@ory/nextjs/middleware"
import oryConfig from "@/ory.config"

// This function can be marked `async` if using `await` inside
export const middleware = createOryMiddleware(oryConfig)

// See "Matching Paths" below to learn more
export const config = {}

The middleware protects your routes by checking for valid sessions and redirecting unauthenticated users to the login page.

app/auth/login/page.tsx
// Copyright © 2024 Ory Corp

import { Login } from "@ory/elements-react/theme"
import { enhanceOryConfig } from "@ory/nextjs"
import { getLoginFlow, OryPageParams } from "@ory/nextjs/app"

import baseConfig from "@/ory.config"

export default async function LoginPage(props: OryPageParams) {
const config = enhanceOryConfig(baseConfig)
const flow = await getLoginFlow(config, props.searchParams)

if (!flow) {
return null
}

return (
<Login
flow={flow}
config={config}
components={{
Card: {},
}}
/>
)
}

The login page uses Ory's pre-built Login component to render a complete authentication form with error handling.

Run your Next.js app

Now that your app is ready, it's time to run it! Start the Next.js development server:

npm run dev

Go to localhost:3000 to access your application.

Make authenticated calls to your API

To make authenticated API calls in your Next.js app, you can create a Route Handler that verifies the session:

middleware.ts
import { getServerSession } from "@ory/nextjs/app"
import { NextResponse } from "next/server"

export async function GET() {
// Check if the user is authenticated
const session = await getServerSession()

if (!session) {
// Return 401 if not authenticated
return NextResponse.json({ message: "Unauthorized" }, { status: 401 })
}

// Return data for authenticated users
return NextResponse.json({
message: "Hello from protected API!",
user: session?.identity?.traits,
})
}

When making API calls from client components, make sure to include credentials to send session cookies:

// Client component example
const response = await fetch("/api/hello", {
credentials: "include", // Important for sending cookies
})

See it in action

Access your Next.js app at localhost:3000, sign in, and see if you can make authenticated requests to your API!

Go to production

To promote this app to production:

  1. Build the Next.js app and deploy it (for example on Vercel or Netlify)
  2. Connect your project with a custom domain

These components must be hosted on the same top-level domain as they were on your local machine:

ComponentProductionLocal
Next.js Appwww.example.orglocalhost:3000
Oryory.example.orglocalhost:4000