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. You can use this guide with both Ory Cloud 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 we create a new Next.js project:

npx create-next-app@latest --typescript
cd <your-project-directory>

Install Ory

Ory provides integration tools that quickly combine Ory with Next.js. Let's install Ory's SDK, used to make API calls to Ory, and Ory's Integration Tools for JavaScript frameworks:

npm i --save @ory/integrations @ory/client

and create a special route in [...paths].js at pages/api/.ory/.

// @ory/integrations offers a package for integrating with Next.js.
import { config, createApiHandler } from "@ory/integrations/next-edge"

// We need to export the config.
export { config }

// And create the Ory Cloud API "bridge".
export default createApiHandler({
fallbackToPlayground: true,
})

This route connects your Next.js app with Ory's APIs and ensures that all cookies and credentials are set up. Without it, your Next.js application won't be able to talk to Ory's APIs.

Require login to access the home page

Next we add a session check to the default home page of the Next.js example application.The highlighted code is what we added to check whether the user is signed in, and redirect them to the login page if not:

import Head from "next/head"
import Image from "next/image"
import styles from "../styles/Home.module.css"
import { useEffect, useState } from "react"
import { useRouter } from "next/router"

import { Configuration, V0alpha2Api, Session, Identity } from "@ory/client"
import { edgeConfig } from "@ory/integrations/next"

const ory = new V0alpha2Api(new Configuration(edgeConfig))

// Returns either the email or the username depending on the user's Identity Schema
const getUserName = (identity: Identity) =>
identity.traits.email || identity.traits.username

const Home = () => {
const router = useRouter()

const [session, setSession] = useState<Session | undefined>()
const [logoutUrl, setLogoutUrl] = useState<string | undefined>()

useEffect(() => {
ory
.toSession()
.then(({ data }) => {
// User has a session!
setSession(data)
// Create a logout url
ory.createSelfServiceLogoutFlowUrlForBrowsers().then(({ data }) => {
setLogoutUrl(data.logout_url)
})
})
.catch(() => {
// Redirect to login page
return router.push(edgeConfig.basePath + "/ui/login")
})
})

if (!session) {
// Still loading
return null
}

return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>

<main className={styles.main}>
<h1 className={styles.title}>
Welcome to{" "}
<a href="https://nextjs.org">
Next.js,{" "}
{
getUserName(session?.identity)
}
!
</a>
</h1>

<p className={styles.description}>
<a href={logoutUrl}>Log out</a>
</p>

<p className={styles.description}>
Get started by editing{" "}
<code className={styles.code}>pages/index.tsx</code>
</p>

<div className={styles.grid}>
<a href="https://nextjs.org/docs" className={styles.card}>
<h2>Documentation &rarr;</h2>
<p>Find in-depth information about Next.js features and API.</p>
</a>

<a href="https://nextjs.org/learn" className={styles.card}>
<h2>Learn &rarr;</h2>
<p>Learn about Next.js in an interactive course with quizzes!</p>
</a>

<a
href="https://github.com/vercel/next.js/tree/canary/examples"
className={styles.card}
>
<h2>Examples &rarr;</h2>
<p>Discover and deploy boilerplate example Next.js projects.</p>
</a>

<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
>
<h2>Deploy &rarr;</h2>
<p>
Instantly deploy your Next.js site to a public URL with Vercel.
</p>
</a>
</div>
</main>

<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by{" "}
<span className={styles.logo}>
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
</span>
</a>
</footer>
</div>
)
}

export default Home

Run your Next.js app

Great, that's it. Let's run your application. Set up your environment variables to connect with Ory's APIs

# This is a public Ory Cloud Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up for Ory Cloud at
#
# https://console.ory.sh/registration
#
# and create a free Ory Cloud Project to see your own configuration embedded in code samples.
export ORY_SDK_URL=https://{your-project-slug-here}.projects.oryapis.com

and start the Next.js development server:

npm run dev

Then open http://localhost:3000 in your browser. are presented with Ory's Sign In page. Let's click on sign up and create your first user.

Go to production

Release your app bundled with Ory to production using:

# This is a public Ory Cloud Project.
# Don’t submit any personally identifiable information in requests made with this project.
# Sign up for Ory Cloud at
#
# https://console.ory.sh/registration
#
# and create a free Ory Cloud Project to see your own configuration embedded in code samples.
npx vercel deploy --prod -e ORY_SDK_URL=https://{your-project-slug-here}.projects.oryapis.com