Search code examples
reactjstypescriptnext.jsreact-hooksnext-auth

How to Create Independent Layouts in Next.js App Router for Specific Routes?


Problem

I want to create a specific layout for the /api/auth/* routes that do not include the CustomNavbar and Footer components defined in the main RootLayout. Despite my efforts, the main layout still appears on these routes.

I'm working on a Next.js project with the following details:

  • Next.js Version: 14.2.3
  • NextAuth Version: 4.24.7
  • Using: App Router

Project Structure

Here's my project structure within the app directory:

app/
├── (auth)/
│   ├── api/
│   │   ├── auth/
|   |   |   ├── [...nextauth]
│   │   │   ├── layout.tsx  // Auth-specific layout
│   │   │   ├── signin/
│   │   │   │   └── page.tsx
├── layout.tsx  // Main layout
├── page.tsx    // Home page

Issue

Even with these setups, the CustomNavbar and Footer components are still rendered on the /api/auth routes. How can I ensure the RootLayout is not applied to these specific routes, and only the auth layout is used?

Additional Info

  1. I've restarted the server multiple times.
  2. The useIsAuth hook is correctly placed in a directory where it can be imported.

Question

What is the correct way to isolate layouts in Next.js using the App Router to achieve independent layouts for specific routes like /api/auth/*?

What I've Tried

  1. Auth-Specific Layout: Created a separate layout.tsx within the (auth)/api/auth directory.
  2. Custom Hook: Implemented a useIsAuth hook to check if the pathname starts with /api/auth and conditionally render components.

useIsAuth Hook:

"use client";
import { usePathname } from "next/navigation";

export const useIsAuth = () => {
    const pathname = usePathname();
    return pathname.startsWith("/api/auth");
};

RootLayout: https://gist.github.com/Kumala3/96f57abb72497163d611f9a561046a32


Solution

  • I came up with an idea on how to implement an independent layout and it's working just perfectly.

    Moreover, my app directory is better-structured thanks to the route groups.

    My solution is to remove Footer and Navbar components from the RootLayout and wrap all public pages into users route group. After doing this, we can create a custom layout for a specific route group, create layout.tsx inside /app/(users)/*, and add needed components there (Footer, NavBar). I also created layout.tsx for all Auth pages, so now I am independent of the RootLayout. In addition, added needed components to my main page.

    The project structure looks like this now:

    app/
    ├── (auth)/
    │   ├── api/
    │   │   ├── auth/
    |   |   |   ├── [...nextauth]
    │   │   │   ├── signin/
    │   │   │   │   └── page.tsx
    │   ├── layout.tsx // Auth Layout specific for these pages
    ├── (users)/
    │   ├── layout.tsx // Users Layout for all public pages
    │   ├── ... // Other pages located here
    ├── layout.tsx  // Root layout
    ├── page.tsx    // Home page