Protect a Page with Login in Next.js
In this guide, we set up a new Next.js application and protect its home page with a login page using Ory. It will also add features such as profile settings, registration, and more. You can use this guide with both Ory Cloud and by self-hosting Ory software.
This guide is for you if you:
- have NodeJS installed;
- want to use Next.js to build an application;
- want to show your app only if the user is logged in.
Before we start, let's take a look at what user flow you will implement with this guide.
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
// @ory/integrations offers a package for integrating with NextJS.
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 correctly. Without it, your Next.js application will not 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>()
useEffect(() => {
ory
.toSession()
.then(({ data }) => {
// User has a session!
setSession(data)
})
.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}>
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 →</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 →</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 →</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 →</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
- Mac OS
- Linux
- Windows CMD
- Windows Powershell
- Self-Hosted Ory Kratos
# 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://playground.projects.oryapis.com
# 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://playground.projects.oryapis.com
# 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!
set ORY_SDK_URL=https://playground.projects.oryapis.com
# 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!
$Env:ORY_SDK_URL = "https://playground.projects.oryapis.com"
Clone and run Ory Kratos locally
git clone --depth 1 --branch master https://github.com/ory/kratos.git
cd kratos
git checkout master
git pull -ff
docker-compose -f quickstart.yml -f contrib/quickstart/kratos/cloud/quickstart.yml up --build --force-recreate -d
and set the environment variable to the exposed port:
export ORY_SDK_URL=http://localhost:4433
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://playground.projects.oryapis.com