Isolate Layouts with Route Groups

Used in this guide:
Next.js 15.3.4

Introduction

When building a modern full-stack app with Next.js 13+ App Router, it's common to have multiple layout types in the same project. For example, a public-facing site and an admin dashboard or CMS (like Sanity Studio). However, without careful structure, your CMS may unintentionally inherit your main site layout including headers, footers, and styling — which breaks its design.

This guide walks you through the process of isolating layouts using route groups, allowing each part of your app to have its own layout tree while keeping everything in one unified project.


Purpose

We want to:

  • Keep our main site layout (with header, footer, global navigation)
  • Prevent it from affecting other sections like a CMS or admin panel
  • Avoid layout inheritance issues in the App Router
  • Keep clean, maintainable folder structure

Use Case Example:

You integrated Sanity Studio under /studio, but it inherits your site's layout, causing layout and scroll issues. This tutorial solves that.


Final Folder Structure (What We're Bulding)

You must restart vscode after moving directory to apply the changes

app/
├── (main)/                   # Main site layout (public-facing)
│   ├── layout.tsx            # Contains header, footer, etc.
│   ├── page.tsx              # Homepage
│   ├── favicon.ico
│   └── (pages)/              # About, Blog, Shop, etc.
│       ├── about/
│       ├── contact/
│       └── ...

├── (studio)/                 # CMS layout (clean, standalone)
│   ├── layout.tsx            # Minimal layout without any outer wrappers
│   └── studio/
│       └── [[...tool]]/
│           └── page.tsx      # Sanity Studio mount point

├── api/                      # Shared API routes
├── components/               # Shared UI components
├── error/                    # Error boundaries
├── globals.css               # Global styles

Set Up a Clean Layout for Sanity

This prevents global styles, margins, or scroll from leaking into your studio.

app/(studio)/layout.tsx
import type { Metadata } from "next";
import "../globals.css";
 
export const metadata: Metadata = {
  title: "Sanity Studio",
  description: "Sanity Studio",
};
 
export default function StudioLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
      </body>
    </html>
  );
}

By importing globals.css this makes Tailwind works in this route group as well.

JKT

Stay focused, and the rest will follow

©Jakkrit Turner. All rights reserved