Your Ultimate Guide to Next.js Authentication
This tutorial describes Next.js authentication patterns and helps you learn step-by-step how to authenticate a Next.js application.

Table of Contents
- What is Authentication?
- Should You Build Your Authentication System or Use a Third-party Solution?
- What is LoginRadius?
- Understanding Next.js Authentication Patterns
- Authenticating Next.js Apps with LoginRadius
- Conclusion
What is Authentication?
In this article, you'll learn about authentication in Next.js and how you can authenticate Next.js applications with LoginRadius.
Note: An understanding of React, Hooks, and Next.js is beneficial to follow this tutorial.
What is Authentication?
Authentication is the process of validating that an individual is who they claim to be. Authentication is an essential feature for applications, particularly those that store user data.
You should not mistake authentication for authorization. Authorization is the process of verifying that whether a user has required permission to access an asset or data set.
Authentication deals with identifying a user, while authorization checks what resources or data an authenticated user has permission to access.
Some of the methods used to implement authentication are:
- Username/email and password
- Fingerprint
- Face recognition
- Security questions
- One time pins (OTPs)
- Magic links
Should You Build Your Authentication System or Use a Third-party Solution?
Authentication is one of the most critical parts of an application’s security, so you should address it adequately.
A few aspects you should consider when assessing if you should build your authentication system or use a third-party solution:
-
Progressive Enhancements: Security systems require frequent enhancements and upgrades to keep users safe from evolving threats and techniques. How much time and resources can you commit to keeping your security system up-to-date with the latest countermeasures to safeguard data and access against emerging threats?
-
Identity Provider Support: How many identity providers do you plan to support, if any? With third-party solutions, you can authenticate users with email/password as well as identity providers such as Google, Github, Facebook, and more. Third-party solutions are always working hard to add support to even more providers. They also provide other authentication methods like Magic Link for passwordless authentication.
Can you build an authentication system that allows users to use their preferred authentication method, or will they be restricted?
-
Advanced Security Features: Security and authentication go beyond email/password sign-in. Most third-party solutions provide necessary features, such as email confirmation, two-factor authentication (2FA), etc.
You should let the security experts such as LoginRadius do what they do best while focusing on your main tasks — building excellent applications.
Considering these factors, it's pretty easier to rely on a third-party solution, and it's also cheaper and more secure than building your own authentication system.
What is LoginRadius?
Loginradius is the world's first no-code identity platform. It is a simple, implementable solution for adding user authentication and authorization to your website.
LoginRadius provides no-code services for authorization, authentication, account security, and much more. It has several interesting features, and some of them are:
- Social login
- Passwordless login
- Standard login (email and password)
- Multi-factor authentication
- Phone login
- Single sign-on
- User management
Understanding Next.js Authentication Patterns
Next.js offers two authentication patterns — client-side and server-side authentication.
Client-Side Authentication
With client-side authentication, the authentication logic and user redirection are done in the browser. The page component fully loads before the redirect logic is executed.
When this authentication approach is used, developers usually use a loading indicator to indicate to the user that a process is running in the background. The loading indicator helps boost user experience. If the user’s authentication fails, redirect the user to a login page.
The following example shows how to handle client-side redirects:
1import { useEffect } from "react"
2import { useRouter } from "next/router"
3import authService from "auth-service" //imaginary auth service
4export default function ProtectedPage() {
5const router = useRouter()
6useEffect(() => {
7const authUser = authService.getUser()
8// if there is no authenticated user, redirect to login page_
9
10if (!authUser) {
11 router.push("/login")
12}
13
14}, [])
15return (
16<>
17<h1>Welcome {user.name}. This is a protected page</h1>`
18</>
19)
20}
The above code snippet handles client-side redirects in the browser using next/router. It also uses an imaginary authentication service, auth-service
, for illustration purposes. You’ll work with LoginRadius later in this tutorial.
It checks if there is an authenticated user with the authService.getUser()
method in the useEffect
. If there is none, it redirects the user to the /login
page using Next.js’s router object.
This is a simple illustration of client-side authentication and redirection.
Server-Side Authentication
With server-side authentication, you can redirect a user from, say, pages/profile
to pages/login
. When non-authenticated users try to access a protected page, they are redirected to a login page. All of this is done on the server — before the request reaches the browser.
A benefit of this pattern is that non-authenticated users do not see flashes of unauthenticated content before they are redirected.
The following example below shows how to handle server-side redirects:
1export default function ProtectedPage({ user }) {
2 return (
3 <>
4 <h1>Welcome {user.name}. This is a protected page</h1>
5 </>
6 )
7}
8export const getServerSideProps = async context => {
9const { user } = authService.getUser(context.req)
10// if there is no authenticated user, redirect to login page
11
12if (!user)
13 return {
14 props: {},
15
16 redirect: { destination: "/login" },
17 }
18
19 return { props: { user } }
20}
21
22}
Using getServerSideProps
enables rendering pages on the server. You can take advantage of that to also handle the redirection on the server.
The above code snippet uses the authService.getUser()
method to get the authenticated user’s object. If there is no user, it returns an object with a redirect
object. The redirect
object contains a destination
key, where you can put the page you want to redirect the user to, which is your application’s login page.
Now that you’ve understood the authentication patterns available, let’s see how to authenticate a Next.js application with LoginRadius.
Authenticating Next.js Apps with LoginRadius
The steps below highlight how you can integrate and authenticate your Next.js applications with LoginRadius:
Create a LoginRadius Account
You should create an account to get started with LoginRadius. There is a free plan you can start with.
Get Account Credentials
Now that you have an account, you should get the credentials for your appName
and apiKey
from the dashboard. You'll need them later to use the React SDK.
Start a New Next.js Application
Run the following command in your terminal to create a new Next.js application:
1npx create-next-app <name-of-project>
2//or
3yarn add create-next-app <name-of-project>
Install LoginRadius React SDK
Next, install the React SDK into the project:
1```javascript
2npm install loginradius-react
3//or
4yarn add loginradius-react
5```
Integrate the React SDK
You need to wrap the root component with the SDK’s authentication provider.
You also need to pass the account credentials to the provider. You can get these credentials from your LoginRadius account dashboard.
Navigate to pages/_app.js
and update it with the code below:
1import Head from "next/head"
2import { LRAuthProvider } from "loginradius-react"
3import { ChakraProvider } from "@chakra-ui/react"
4import Layout from "../layout"
5import "../styles/globals.css"
6function MyApp({ Component, pageProps }) {
7return (
8<>
9<Head>
10<title>Loginradius Next</title>
11</Head>
12 <LRAuthProvider
13 appName="your-app-name"
14 apiKey="your-api-key"
15 redirectUri={"http://localhost:3000/"}
16 >
17 <ChakraProvider>
18 <Layout>
19 <Component {...pageProps} />
20 </Layout>
21 </ChakraProvider>
22 </LRAuthProvider>
23</>
24
25)
26}
27export default MyApp
The above code snippet imports the LRAuthProvider
component from loginradius-react
. It passes the appName
and apiKey
taken from the LoginRadius account dashboard earlier to LRAuthProvider
. It also sets the redirectUri
to http://localhost:3000/
.
The redirectUri
is the callback URL where you want to redirect users after being authenticated. You should whitelist the redirect_uri
in your LoginRadius account dashboard. Localhost URLs are whitelisted by default.
Now that you've integrated the SDK, let’s add the authentication functionality.
Add Login and Logout Functionality
Your users should be able to log in and out of our application, so let’s set that up.
We will add the log in and log out functionality to a Nav
component. Let’s set up the component.
Create a layout
folder in the root directory, and create a Nav.js
file there. Add the following code to Nav.js
:
1import { Button, Flex, Stack } from "@chakra-ui/react"
2import { useLRAuth } from "loginradius-react"
3export default function Nav() {
4const { loginWithRedirect, logout } = useLRAuth()
5return (
6<Flex>
7<Stack spacing={[6, 8]}>
8<Button onClick={() => loginWithRedirect()}>Login to continue</Button>
9<Button onClick={() => logout()}>Log out</Button>
10</Stack>
11</Flex>
12)
13}
Here, Chakra UI is used for UI components.
First, it imports the useLRAuth
hook from the SDK. Next, it accesses the loginWithRedirect
and logout
methods from the useLRAuth
hook.
Then, it passes loginWithRedirect
and logout
to the login and logout buttons’ onClick
event handlers, respectively.
Having created the Nav
component, we need to create the Layout
component we mentioned earlier.
Create an index.js
file in the layout
folder, and paste the code below:
1import { Box } from "@chakra-ui/react"
2import Nav from "./Nav"
3export default function Layout({ children }) {
4return (
5<Box h="100vh" bg="green.50">
6<Nav />
7<Box>{children}</Box>
8</Box>
9)
10}
With that, you've added authentication to your application. However, you need a way to track the authentication state. You need to know if there is a logged-in user and do something with that information.
Tracking Authentication State
The SDK also provides error
and user
objects, along with isLoading
and isAuthenticated
booleans. You'll use these to track the authentication state.
You can access information about an authenticated user, such as their email address, from the user
object. If any, you can display error messages from the error
object.
isAuthenticated
returns true if there is an authenticated user and false if there is not.
We are currently rendering both the login and logout buttons in the Nav
component. However, we don’t want that. We want to display the login button when there is no authenticated user and logout when there is an authenticated user.
Let’s update the Nav.js
file with the code below to fix that:
1import { Button, Flex, Stack } from "@chakra-ui/react"
2import { useLRAuth } from "loginradius-react"
3export default function Nav() {
4const { isAuthenticated, user, loginWithRedirect, logout } = useLRAuth()
5return (
6<Flex as="nav">
7<Stack spacing={[6, 8]}>
8{!user && (
9<Button onClick={() => loginWithRedirect()}>Login to continue</Button>
10)}
11 {isAuthenticated && user && (
12 <Button onClick={() => logout()}>Log out</Button>
13 )}
14 </Stack>
15</Flex>
16
17)
18}
We conditionally display the login and logout buttons based on the authentication state.
If there is a logged-in user, we want to redirect them to the profile page.
Navigate to pages/index.js
file and update it with the code below:
1import { useEffect } from "react"
2import { useRouter } from "next/router"
3import { useLRAuth } from "loginradius-react"
4import { Button, Heading, VStack, Center } from "@chakra-ui/react"
5export default function Home() {
6const { isLoading, isAuthenticated, error, user } = useLRAuth()
7const router = useRouter()
8useEffect(() => {
9if (user && isAuthenticated) {
10router.push("/profile")
11}
12}, [router, user, isAuthenticated])
13if (isLoading) {
14return <div>Loading...</div>
15}
16if (error) {
17return <div>Oops... {error.message}</div>
18}
19return (
20<Center pt={10}>
21<VStack spacing={[6, 8]}>
22<Heading as="h2">Welcome</Heading>
23<Text fontSize="3xl">Login to continue</Text>
24</VStack>
25</Center>
26)
27}
Let’s break down the above code snippet:
- In the
useEffect
, it checks if there is a user object and ifisAuthenticated
is true. If these conditions are true, it redirects the user to their profile page. These conditions will only be true when the user has logged in. You'll set up the profile page later. - It checks if the page is loading using the
isLoading
boolean. If true, it displays “loading…”. In a production-ready application, you would display a loading spinner. - If there is an error during the authentication process, it accesses the message from the
error
object and displays it to the user.
- Finally, return some JSX.
Displaying Authenticated User Data
You have to display information about the authenticated user. Let’s set that up. Create a profile.js file in the pages directory and paste the code below:
1import { Box, Center, Heading } from "@chakra-ui/react"
2import { useLRAuth } from "loginradius-react"
3export default function Profile() {
4const { user, isLoading, isAuthenticated } = useLRAuth()
5if (isLoading) {
6return <div>Loading...</div>
7}
8if (isAuthenticated) {
9return (
10<Box>
11<Center mt={10}>
12<Heading a="h2">
13Welcome to your profile {user.Email[0].Value}
14</Heading>
15</Center>
16</Box>
17)
18}
19}
You should display a user’s information if they're authenticated. Here, you check that they're authenticated with the isAuthenticated
hook. If they're authenticated, return some JSX and display the user’s email address.
Protecting a Route
You can create protected routes to ensure only authenticated users can access those routes.
1import { withAuthenticationRequired } from "loginradius-react"
2const Profile = () => {
3if (isAuthenticated) {
4return (
5<Box
6...markup goes here
7</Box
8)
9}
10}
11export default withAuthenticationRequired(Profile,
12//Show a message while the user waits to be redirected to the login page.
13onRedirecting: () => (
14<div>Redirecting you to LoginRadius awesome Login page</div>
15),
16});
Here, the code snippet uses the withAuthenticationRequired
higher-order component to wrap the Profile
component. With this, anytime an unauthenticated user tries to access the /profile
route, they'll be redirected to LoginRadius’s login page and then back to /profile
after they log in.
The image below shows an authenticated user's profile page.

Conclusion
In this tutorial, you have learned about user authentication and understood whether you should develop an authentication system in-house or use a modern identity platform like LoginRadius.
Then, you have briefly learned different authentication patterns available in Next.js. And you step-by-step understood how to authenticate Next.js applications with LoginRadius’s React SDK.
A working version of the code used in this tutorial is available on Github.

Featured Posts
How to Implement JWT Authentication for CRUD APIs in Deno
Multi-Factor Authentication (MFA) with Redis Cache and OTP
Introduction to SolidJS
Build a Modern Login/Signup Form with Tailwind CSS and React
Implement HTTP Streaming with Node.js and Fetch API
NestJS: How to Implement Session-Based User Authentication
NestJS User Authentication with LoginRadius API
How to Authenticate Svelte Apps
Flutter Authentication: Implementing User Signup and Login
How to Secure Your LoopBack REST API with JWT Authentication
Node.js User Authentication Guide
Your Ultimate Guide to Next.js Authentication
Local Storage vs. Session Storage vs. Cookies
How to Secure a PHP API Using JWT
Using JWT Flask JWT Authentication- A Quick Guide
Build Your First Smart Contract with Ethereum & Solidity
What are JWT, JWS, JWE, JWK, and JWA?
How to Build an OpenCV Web App with Streamlit
32 React Best Practices That Every Programmer Should Follow
How to Build a Progressive Web App (PWA) with React
Bootstrap 4 vs. Bootstrap 5: What is the Difference?
JWT Authentication — Best Practices and When to Use
What Are Refresh Tokens? When & How to Use Them
How to Upgrade Your Vim Skills
How to Implement Role-Based Authentication with React Apps
How to Authenticate Users: JWT vs. Session
How to Use Azure Key Vault With an Azure Web App in C#
How to Implement Registration and Authentication in Django?
11 Tips for Managing Remote Software Engineering Teams
Implementing User Authentication in a Python Application
Add Authentication to Play Framework With OIDC and LoginRadius