logo
post image

NextJS Conditional Root Layout for Authenticated Applications (App Router)

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 groupsunauthorized & 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.