When NextJS app has some pages meant for authenticated users and some pages for non-authenticated users, we need a conditional root layout.
The routing structure will look something like this :
app/
|-- (unauthorized)/
| |-- layout.js
| |-- unauthApi/
| | |-- route.js
| |-- login/
| | |-- page.js
|-- (authorized)/
| |-- layout.js
| |-- page.js
| |-- authApi/
| | |-- route.js
| |-- blog/
| | |-- page.js
| | |-- [id]/
| | | |-- page.js
middleware.js
- We are using 2 route groups — unauthorized & authorized to organize routes meant for authenticated & non-authenticated users.
- Non-authenticated route is /login which is the route for login page. We also have a /unauthApi route handler to carry out api operations for unauthenticated users (for example login api).
- Authenticated routes are /, /blog & /blog/[id]. Users can access these pages only after authentication. We also have a route handler /authApi to carry out api operations for authenticated users (for example logout, getting blog data).
We can use middleware to check whether the request is non-authenticated or authenticated.
// middleware.js import { NextResponse } from 'next/server' // redirect to login page for non-authenticated requests export async function middleware(request) { // set authentication status using JWT or preferred way const authStatus = true if (!authStatus) { return NextResponse.redirect(new URL('/login', request.url)) } } export const config = { matcher: [ '/', '/authApi', '/blog/:path*' ] }
- (unauthorized)/layout.js will hold the root layout for the non-authenticated pages.
- (authorized)/layout.js will hold the root layout for the authenticated pages.