Skip to the solution
MediumFrontend8 min read

What are route groups in Next.js and how do you use them?

249 views

The problem

Question presented to candidate: "Our marketing pages, the logged-in app and the auth screens all need different chrome, but we do not want /marketing/ or /app/ in the URLs. How would you structure the app directory?"

What a strong answer should cover:

  • A folder in parentheses, such as (marketing), is a route group: it is left out of the URL, so app/(marketing)/about/page.tsx serves /about.
  • Groups let a set of routes share a layout (and loading or error files) while other routes at the same URL level opt out.
  • Groups are also for organization: by team, feature or concern, without affecting routing.
  • Several root layouts are possible by putting html and body in each group layout instead of app/layout.tsx; navigating between different root layouts is a full page load.
  • Two groups must not resolve to the same URL, such as (a)/about and (b)/about; the build fails.
  • Leaving a group unmounts its layout, so its client state resets when you come back.

Clarifying questions expected:

  • "Do the sections share the same html, fonts and providers?" β€” decides between one root layout and several.
  • "How often do users move between the sections?" β€” with several root layouts, each crossing reloads the page.

Code / implementation expected: Yes β€” (site), (auth) and (admin) groups with their own layouts under one root layout.

  • nextjs
  • route-groups
  • routing
  • app-router

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

8 min read Β· 8 sections

Read the code

Three groups under one root layout
// app/layout.tsx
// One root layout: html and body live here, so every group shares one document.
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return <html lang="en"><body>{children}</body></html>;
}

// app/(site)/layout.tsx
import Link from "next/link";

// Only routes inside (site) get the marketing header. The folder name is not in the URL.
export default function SiteLayout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <header>
        <Link href="/about">About</Link> <Link href="/pricing">Pricing</Link> <Link href="/login">Log in</Link>
      </header>
      <main>{children}</main>
    </>
  );
}

// app/(auth)/layout.tsx
// Login and signup opt out of the marketing header and get a centred card instead.
export default function AuthLayout({ children }: { children: React.ReactNode }) {
  return <div className="auth-card">{children}</div>;
}

// app/(admin)/layout.tsx
// A group is also a home for segment files: the loading.tsx next to this layout
// applies to every route inside (admin), and "(admin)" never appears in the URL.
export default function AdminLayout({ children }: { children: React.ReactNode }) {
  return <div className="admin-shell">{children}</div>;
}

// app/(admin)/loading.tsx
export default function AdminLoading() {
  return <p>Loading admin...</p>;
}

// app/(site)/about/page.tsx
export default function About() { return <h1>About</h1>; }   // URL: /about

// app/(auth)/login/page.tsx
export default function Login() { return <h1>Log in</h1>; }    // URL: /login

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 84 of 129 in Next.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Next.js questions
Up nextMedium

What is loading.js in Next.js and how does Suspense streaming work?

Continue