Route Groups & Private Folders
Why organise routes?
A real website has three kinds of pages: public marketing pages, login/register pages and an admin panel. Each needs a different look, but you do not want /marketing/about in the URL. Route groups solve this.
Route groups: (folder)
Wrap a folder name in parentheses. Next.js uses it for organisation and layouts, but skips it in the URL.
📁 app/ 📁 (marketing)/ # group – not in URL layout.jsx # big header + footer page.jsx # / about/page.jsx # /about courses/page.jsx # /courses 📁 (auth)/ layout.jsx # small centered card, no menu login/page.jsx # /login register/page.jsx # /register 📁 (admin)/ layout.jsx # sidebar dashboard admin/page.jsx # /admin admin/students/page.jsx # /admin/students 📁 _lib/ # private – never a route format.js layout.jsx # root layout (html, body)
| File | URL |
|---|---|
| app/(marketing)/about/page.jsx | /about |
| app/(auth)/login/page.jsx | /login |
| app/(admin)/admin/students/page.jsx | /admin/students |
Different layouts per group
// app/(auth)/layout.jsx — login & register pages share this
export default function AuthLayout({ children }) {
return (
<div style={{ minHeight: '100vh', display: 'grid', placeItems: 'center', background: '#eef2ff' }}>
<div style={{ width: 360, background: '#fff', padding: 28, borderRadius: 16 }}>
<h2>EduSite</h2>
{children}
</div>
</div>
)
}
// app/(auth)/login/page.jsx → URL is /login (not /(auth)/login)
export default function Login() {
return (
<form>
<input placeholder="Email" />
<input type="password" placeholder="Password" />
<button>Login</button>
</form>
)
}(marketing) pages
- Full header with menu
- Footer with links
- Wide content
(auth) pages
- No menu (less distraction)
- Centered card
- Same root
Private folders: _folder
A folder starting with an underscore, like _lib or _components, and everything in it is never a route, even if it contains a page.jsx. Use it for helper files you want inside app/.
Colocation: keeping files together
Only page.jsx (and route.js) make a folder publicly visible. So a component used by one page can live right next to it:
app/
courses/
page.jsx # the route
CourseSearch.jsx # used only by this page – not a route
courses.module.css # styles for this page
[slug]/page.jsxThe @/ import alias
// jsconfig.json (created by create-next-app)
{
"compilerOptions": {
"paths": { "@/*": ["./*"] }
}
}
// anywhere in the project:
import Header from '@/components/Header' // ✅ clean
import Header from '../../../components/Header' // ❌ hard to readCommon mistakes
- Two groups resolving to the same URL (
(a)/aboutand(b)/about) → build error. - Expecting
(admin)to protect pages → a group is only organisation; protect with auth checks (Auth lesson). - Multiple root layouts without a top
app/layout.jsx→ each group's layout must then include<html>and<body>.
Summary
(group)folders organise routes and allow separate layouts, without changing URLs._privatefolders are never routes.- Colocate page-specific components; use
@/for clean imports.
Move your home and about pages into (marketing) and create (auth)/login with a centered-card layout. Confirm the URLs are still /about and /login.
