cf.completefrontend
Open lab My progress
THE NEXT.JS FIELD GUIDE

Route groups and private folders

Use (group) folders to sort routes and give each section its own layout without changing URLs, and _private folders to keep your files out of routing.

By the end, you can
  • 01
    Group routes without changing URLsSort pages into (group) folders and say which address each page still has.
  • 02
    Give each section its own layoutAdd a layout to one group, or a whole root layout, and know when that costs a full page load.
  • 03
    Keep your own files out of routingUse _private folders and pick one way to place components and data, and use it everywhere.

Round brackets keep a folder out of the address

In File-system routing, each ordinary folder on the way to a page added one segment to the address: app/teas/page.tsx was the page for /teas. That works until you want to sort your folders in a way the address shouldn't show. The tea shop has pages for shopping, like the teas and the cart, and pages about the shop, like About. You want them in two folders, but you don't want addresses like /shop/teas.

A folder whose name is in round brackets, like (shop), is a route group. It sorts the files inside it, but it isn't part of the address. Here is the shop with two groups. Like every example in this lesson, it's a real Next.js 16.4.3 project, built with next build and run with next start, and what it sent back was recorded. Click through its files, then its pages.

The tea shop, sorted into two groupsNext.js
app/(info)/about/(shop)/cart/teas/
app/(shop)/teas/page.tsx
export default function TeasPage() {  return (    <main>      <h1>Our teas</h1>      <ul>        <li>Green tea: $4</li>        <li>Mint tea: $3</li>      </ul>    </main>  );}
Recorded from Next.js 16.4.3
localhost:3000/teasTea shop
Our teas
  • Green tea: $4
  • Mint tea: $3

The page as the browser shows it when its HTML arrives, drawn with plain styles. Its JavaScript doesn't run here.

The file shown first, app/(shop)/teas/page.tsx, is the same teas page as before: line 1 exports it, and line 4 is its heading, Our teas. Only its place changed. It now sits in (shop), next to cart, and about sits in (info). app/page.tsx and the root layout, app/layout.tsx, stay at the top, outside both groups.

Open the Terminal tab. The route table that next build prints lists ○ /, ○ /_not-found, ○ /about, ○ /cart and ○ /teas. The ○ means "prerendered as static content": each page was made once, during the build. There's no (shop) and no (info) in any address. In the Browser tab, pick /shop/teas and /(shop)/teas: both answered 404, the page for addresses that don't exist. The group's name isn't in the address, with round brackets or without.

Each row is one page file of this shop: the group it's in, and the address the build gave it.

The grouped shop's pages
FileIts groupIts address
app/page.tsxNone/
app/(shop)/teas/page.tsx(shop)/teas
app/(shop)/cart/page.tsx(shop)/cart
app/(info)/about/page.tsx(info)/about
An editor window for the app folder lists page.tsx, (shop)/teas/page.tsx, (shop)/cart/page.tsx and (info)/about/page.tsx. An arrow goes from each file to a tag with its address: slash, slash teas, slash cart and slash about. No address has shop or info in it.apppage.tsx(shop)/teas/page.tsx(shop)/cart/page.tsx(info)/about/page.tsx//teas/cart/aboutthe round brackets keep a folder out of the address
The grouped tea shop. (shop) and (info) sort the files, but each page keeps the address of its other folders: /teas, /cart and /about.
Real-life analogyCorners of a library

A library sorts its books into corners, each with a sign. The sign helps you find your way, but a book's number stays the same whichever corner it sits in, and you ask for a book by its number. A corner can have its own carpet and lamps, which only the books there get. Behind a door, the staff room holds things the library uses, and no visitor can ask for them.

In real life: A corner of the library with a sign, like "Children's books"
In Next.js: A route group, like (shop)
In real life: The number on a book's spine, which you use to ask for it
In Next.js: A page's address, like /teas
In real life: The corner's own carpet and lamps
In Next.js: A layout.tsx inside the group, around its pages only
In real life: A staff room, where visitors can't ask for anything
In Next.js: A private folder, like _components, which has no address
The main idea

A folder in round brackets, like (shop), is a route group: it sorts routes without changing their addresses. A folder that starts with an underscore, like _components, is a private folder: nothing inside it becomes a route. The rest of this lesson shows what each one is for.

A layout for each section

Sorting files is only half of what groups do. The bigger reason is layouts. A layout.tsx in a folder goes around every page in that folder and in the folders below it (the Layouts and pages lesson shows layouts in full). Without groups, a layout for only the teas and the cart would need a folder they share, and that folder would add a segment: /shop/teas. A group gives them a folder to share with no segment.

Here, each group gets a layout. The shop's pages get a line about delivery, and the info pages get the opening hours at the bottom. A checkout page is added outside both groups:

A layout in each groupNext.js
app/(info)/about/(shop)/cart/teas/checkout/
app/(shop)/layout.tsx
export default function ShopLayout({ children }: LayoutProps<"/">) {  return (    <>      <p>Free delivery on orders over $20.</p>      {children}    </>  );}
Recorded from Next.js 16.4.3
localhost:3000/teasTea shop

Free delivery on orders over $20.

Our teas
  • Green tea: $4
  • Mint tea: $3

The page as the browser shows it when its HTML arrives, drawn with plain styles. Its JavaScript doesn't run here.

In app/(shop)/layout.tsx, line 4 is the delivery line, and line 5, {children}, is where the page goes. In app/(info)/layout.tsx, line 4 places the page first and line 5 puts the opening hours under it. Line 1 of each types the props with LayoutProps<"/">, a type Next.js writes for you. The route it names is "/", not "/(shop)", because the group adds nothing to the address. Exercise 4 shows what the type check says otherwise.

Now pick each page in the Browser tab. /teas and /cart show Free delivery on orders over $20. above the page. /about shows Open every day, 9 to 5. under it. /checkout and / show only the root layout's links. The Terminal tab still lists plain addresses, with ○ /checkout added. Each row is one recorded page, with what goes around it, from the outside in:

What goes around each page
AddressLayouts around the pageWhat the visitor sees besides the page
/teasThe root layout, then (shop)/layout.tsxThe links, then Free delivery on orders over $20.
/cartThe root layout, then (shop)/layout.tsxThe links, then Free delivery on orders over $20.
/aboutThe root layout, then (info)/layout.tsxThe links, and Open every day, 9 to 5. under the page.
/checkoutOnly the root layoutOnly the links.
/Only the root layoutOnly the links.
Three addresses, each with crates nested inside each other. For slash teas, the root layout holds the shop group's layout, which holds the teas page. For slash about, the root layout holds the info group's layout, which holds the about page. For slash checkout, the root layout holds the checkout page directly./teasteas page(shop) layoutroot layout/aboutabout page(info) layoutroot layout/checkoutcheckout pageroot layout
Each page sits inside the layouts of the folders above it. /teas gets the root layout and (shop)'s, /about gets (info)'s, and /checkout, outside both groups, gets only the root layout.

This is also how you keep one page out of a layout that its neighbors share. The checkout page shouldn't tempt anyone to keep shopping, so it sits outside (shop). Try both places. Before you click, guess what /checkout shows in each:

Playground: should checkout get the shop's layout?
The tea shop, with checkout in this folderNext.js
app/(info)/about/(shop)/cart/teas/checkout/
app/checkout/page.tsx
export default function CheckoutPage() {  return (    <main>      <h1>Checkout</h1>      <p>Enter your address to finish your order.</p>    </main>  );}
Recorded from Next.js 16.4.3
localhost:3000/checkoutTea shop
Checkout

Enter your address to finish your order.

The page as the browser shows it when its HTML arrives, drawn with plain styles. Its JavaScript doesn't run here.

Try it yourself
app/checkout

Checkout sits outside both groups, so only the root layout goes around it: /checkout shows the links, then Checkout, with no delivery line.

Both versions were built with next build from Next.js 16.4.3 and run with next start, which was asked for /checkout. Only the checkout folder's place changes. Reset goes back to the first version.

Inside (shop), the checkout page gets the delivery line. Outside it, it doesn't. Its address is /checkout both times. Moving a folder in or out of a group changes which layouts go around its pages, and never their addresses.

One address, one page

Groups don't add segments, so two pages in two groups can end up with the same address. Say the shop wants a page about its teas in (shop), and puts it in about/page.tsx there too. Both files would be /about. Pick the second version to see what next build does with that:

Playground: one About page, or two?
The tea shop, with these About pagesNext.js
app/(info)/about/(shop)/cart/teas/checkout/
app/(info)/about/page.tsx
export default function AboutPage() {  return (    <main>      <h1>About us</h1>      <p>Asha and Ravi run the shop.</p>    </main>  );}
Recorded from Next.js 16.4.3
$ next build▲ Next.js 16.4.3 (Turbopack)- Cache Components enabled- Partial Prefetching enabled   Creating an optimized production build ...✓ Compiled successfully  Running TypeScript ...  Finished TypeScript ...  Collecting page data ...✓ Generating static pages (7/7)  Finalizing page optimization ... Route (app)┌ ○ /├ ○ /_not-found├ ○ /about├ ○ /cart├ ○ /checkout└ ○ /teas ○  (Static)  prerendered as static content
Try it yourself
Only (info)/about

One About page, in (info). The build lists ○ /about, and it means one page.

Both versions were built with next build from Next.js 16.4.3. The second adds one file, app/(shop)/about/page.tsx. Reset goes back to the first version.

The build stops with You cannot have two parallel pages that resolve to the same path. "Resolve to the same path" means both page files would answer the same address. Next.js doesn't pick one for you. Each address must belong to exactly one page, so give the second page an address of its own, like app/(shop)/teas/about/page.tsx for /teas/about.

Two root layouts in one app

The root layout is the layout at the top of the app. It's the one that writes <html> and <body>, and every page sits inside it. So far, that was app/layout.tsx. To be exact, a root layout is any layout with no other layout above it. Delete app/layout.tsx and give each group a layout with its own <html> and <body>, and the app has two root layouts.

That's useful when parts of one app look completely different. Here, the shop gets a blog called Tea notes, with its own header and its own page title:

The shop and its blog, with a root layout eachNext.js
app/(blog)/blog/(shop)/teas/
app/(blog)/layout.tsx
import Link from "next/link"; export const metadata = { title: "Tea notes" }; export default function BlogRootLayout({ children }: LayoutProps<"/">) {  return (    <html lang="en">      <body>        <header>          <p>Tea notes, a blog from the tea shop</p>          <Link href="/">Back to the shop</Link>        </header>        {children}      </body>    </html>  );}
Recorded from Next.js 16.4.3
localhost:3000/Tea shop
Tea shop

Fresh tea, sent to your door.

The page as the browser shows it when its HTML arrives, drawn with plain styles. Its JavaScript doesn't run here.

The file shown first is app/(blog)/layout.tsx. Line 3 gives the blog's pages the title Tea notes, lines 7 and 8 open its own <html> and <body>, and line 11 links back to the shop. In app/(shop)/layout.tsx, the same lines make the shop's document, with the title Tea shop on line 3 and the links Home, Teas and Blog on line 10. There's no app/layout.tsx. The home page moved into the group too, as app/(shop)/page.tsx, so that a root layout goes around it. In the Browser tab, / and /teas have the shop's links, and /blog has the blog's header.

Moving between the two has a cost. Inside one root layout, a click on a Link is a client-side navigation: the page's JavaScript swaps in the new page, and the layout and everything else on the screen stay (How Next.js works showed this). Between two root layouts that's impossible: the old <html> can't stay, because the new page needs its own. So Next.js does a full page load instead: the browser asks for a whole new HTML document and starts over, as if you typed the address.

This example was also clicked through in real Chrome. The Steps tab below lists four steps: open /, click Teas, click Blog, and click Back to the shop. Each step shows the page after it and the requests the page made, without the script and style files. It opens on step 3.

Clicking through the shop and its blog in ChromeNext.js
app/(blog)/blog/(shop)/teas/
app/(blog)/layout.tsx
import Link from "next/link"; export const metadata = { title: "Tea notes" }; export default function BlogRootLayout({ children }: LayoutProps<"/">) {  return (    <html lang="en">      <body>        <header>          <p>Tea notes, a blog from the tea shop</p>          <Link href="/">Back to the shop</Link>        </header>        {children}      </body>    </html>  );}
Recorded from Next.js 16.4.3

Each step was taken in real Chrome against next start. Pick one to see the page after it.

localhost:3000/blogTea notes

Tea notes, a blog from the tea shop

Back to the shop
How to brew green tea

Use water just below boiling, and wait three minutes.

Focus
nothing: the page itself
Scrolled
0 px down

Requests the page made during this step (3), without the files it loaded

  1. GET/blog200a whole page
  2. GET/200text/x-component
    rsc
    1
    next-router-prefetch
    1
    next-router-segment-prefetch
    /_tree
    next-url
    /blog
  3. GET/200text/x-component
    rsc
    1
    next-router-prefetch
    1
    next-router-segment-prefetch
    /!KHNob3Ap/__PAGE__
    next-url
    /blog
  • Step 1, open /: one request for a whole page, GET /, and then requests marked text/x-component. Those are prefetches: the page's JavaScript asking early for the linked pages, /teas and /blog, before anyone clicks. Both are ○ pages, made during the build, so the prefetches bring all of them.
  • Step 2, click Teas: no requests at all. /teas shares the shop's root layout, and its prefetch had already arrived, so the page was swapped in place.
  • Step 3, click Blog: GET /blog, marked a whole page. /blog was prefetched in step 1 too, but it has another root layout, so Next.js loaded it as a new document.
  • Step 4, click Back to the shop: the same again the other way: GET /, a whole page.
Two browser windows. The left one, Tea shop, holds the shop's root layout with the pages slash and slash teas; an arrow between those two pages says only the page is swapped. The right one, Tea notes, holds the blog's root layout with the page slash blog. A curved arrow under the two windows, from the left one to the right one, says a whole new page loads.Tea shop(shop)/layout.tsx//teasonly the page is swappedTea notes(blog)/layout.tsx/bloga whole new page loads
Each root layout is a whole document of its own, with its own <html>. Inside one, Next.js swaps only the page. Going to the other one loads a whole new page.

A full page load means the browser runs the page's JavaScript again from the start, and anything only kept in the browser, like a half-typed form or a Client Component's state, is gone. Within the shop, or within the blog, nothing changes. So split an app into root layouts only where visitors rarely cross, like a shop and its blog, or a public site and a signed-in app. Next.js makes this decision by comparing the two routes' root layouts, in is-navigating-to-new-root-layout.ts if you want to read it.

Every page needs a root layout

Without app/layout.tsx, a page outside both groups has no root layout above it, and next build stops. That's why the home page moved to app/(shop)/page.tsx. Exercise 5 shows the error.

Private folders: _folder

Project structure gave a first look at the other special folder name: a folder whose name starts with an underscore, like _components, is a private folder. Next.js leaves it out of routing, with every folder and file inside it. Here the teas page draws each tea with a card from its own private folder, and someone left a preview page in there too:

A private folder beside the teas pageNext.js
app/%5Fhelp/(info)/about/(shop)/cart/teas/_components/preview/checkout/
app/(shop)/teas/page.tsx
import TeaCard from "./_components/tea-card"; export default function TeasPage() {  return (    <main>      <h1>Our teas</h1>      <ul>        <TeaCard name="Green tea" price={4} />        <TeaCard name="Mint tea" price={3} />      </ul>    </main>  );}
Recorded from Next.js 16.4.3
localhost:3000/teasTea shop
Home Cart About

Free delivery on orders over $20.

Our teas
  • Green tea: $4
  • Mint tea: $3

The page as the browser shows it when its HTML arrives, drawn with plain styles. Its JavaScript doesn't run here.

Line 1 of app/(shop)/teas/page.tsx imports TeaCard from ./_components/tea-card, and lines 8 and 9 draw a card for each tea. The /teas page shows Green tea: $4 and Mint tea: $3, so the import works like any other.

Now pick /teas/_components/preview. There's a page.tsx at app/(shop)/teas/_components/preview/page.tsx, two folders down, and still the server answered 404. So did /teas/_components/tea-card. The route table in the Terminal tab has no address with _components in it. An underscore at the start of a folder's name switches off routing for everything inside it, page files and route.ts files too.

The last address, /_help, answered 200 with the help page. What if you really want an address that starts with an underscore? Write the underscore as %5F, the way URLs write it in code: the folder app/%5Fhelp is the address /_help, and the build lists ○ /_help.

An editor window for the teas folder lists page.tsx, _components/tea-card.tsx and _components/preview/page.tsx. page.tsx has an arrow to the tag slash teas. The two files in _components are faded and crossed out: they have no address. Below, a card for %5Fhelp/page.tsx has an arrow to the tag slash underscore help.(shop)/teaspage.tsx_components/tea-card.tsx_components/preview/page.tsx/teasno address for these two%5Fhelp/page.tsx/_help
A folder that starts with _ takes itself and everything inside it out of routing, even a page.tsx. To get an address that really starts with an underscore, name the folder %5F….

Now the same folder without its underscore. Guess first: does the preview page get an address?

Playground: _components or components?
The tea shop, with the tea card's folder named like thisNext.js
app/%5Fhelp/(info)/about/(shop)/cart/teas/_components/preview/checkout/
app/(shop)/teas/_components/preview/page.tsx
export default function CardPreview() {  return (    <main>      <h1>Tea card preview</h1>    </main>  );}
Recorded from Next.js 16.4.3
localhost:3000/teas/_components/preview404: This page could not be found.
Home Cart About
404
This page could not be found.

The page as the browser shows it when its HTML arrives, drawn with plain styles. Its JavaScript doesn't run here.

Try it yourself
_components

The underscore makes _components a private folder. The preview's page.tsx has no address: the route table has no new route, and /teas/_components/preview answers 404.

Both versions were built with next build from Next.js 16.4.3 and run with next start, which was asked for /teas and for the preview page's address. Only the folder's name changes. Reset goes back to the first version.

Without the underscore, components is an ordinary folder, and its page.tsx made a page anyone can open, at /teas/components/preview. That's the mistake a private folder rules out.

You don't need a private folder to keep a component beside a page: a tea-card.tsx straight in teas never gets an address either, as File-system routing showed. Private folders are still worth it:

  • They keep the folders that make routes apart from the folders that hold your code, so a glance tells them apart.
  • A stray page.tsx or route.ts inside one never becomes a route, as the preview page showed.
  • Their names all start with _, so editors list them together.
  • No file in one can clash with a special file name, like loading.tsx, including names Next.js adds in later versions.
No address doesn't mean secret

A private folder only keeps files from becoming routes. Code in it still reaches the browser if a Client Component imports it, and whatever a page shows is sent to the browser. Keep secrets, like API keys, in code that only runs on the server. The Server-only code and environment variables lesson shows how.

Three ways to place your own files

Keeping a file next to the code that uses it is called colocation. Next.js doesn't mind where your components and data live, so teams pick a pattern. Each row is one of the three common ones:

Three ways to place components and data
PatternWhere the files goWhat it gives you
Outside appIn folders beside app, like components and lib.app holds only routes. Everything else is one folder away.
In private folders at the top of appIn app/_components and app/_lib.All of the code is inside app, and none of it can become a route.
Beside the route that uses itShared code at the top; a page's own parts in its folder, like teas/_components.A page and its parts sit together, so you find them together.

The patterns mix well. Here is the tea shop using all three: the logo in components beside app, the teas in a private folder at the top of app, and the tea card in a private folder beside the teas page.

The organized tea shop's filesText
app/
  (info)/
    about/
      page.tsx
    layout.tsx
  (shop)/
    cart/
      page.tsx
    teas/
      _components/
        tea-card.tsx
      page.tsx
    layout.tsx
  _lib/
    teas.ts
  checkout/
    page.tsx
  layout.tsx
  page.tsx
components/
  logo.tsx

(info) and (shop) sort the pages and hold their layouts. _lib/teas.ts is shared data that any page can import, and teas/_components/tea-card.tsx belongs to the teas page alone. components/logo.tsx sits outside app. The next section runs this shop. Whichever pattern you choose, use it across the whole project, so everyone knows where to look.

The whole tea shop, organized

Here is the organized shop, built and run. The file shown first is the teas page:

The tea shop with groups, private folders and componentsNext.js
app/(info)/about/(shop)/cart/teas/_components/_lib/checkout/components/
app/(shop)/teas/page.tsx
import { teas } from "@/app/_lib/teas";import TeaCard from "./_components/tea-card"; export default function TeasPage() {  return (    <main>      <h1>Our teas</h1>      <ul>        {teas.map((tea) => (          <TeaCard key={tea.id} name={tea.name} price={tea.price} />        ))}      </ul>    </main>  );}
Recorded from Next.js 16.4.3
localhost:3000/teasTea shop
Tea shop Home Cart

Free delivery on orders over $20.

Our teas
  • Green tea: $4
  • Mint tea: $3

The page as the browser shows it when its HTML arrives, drawn with plain styles. Its JavaScript doesn't run here.

Line 1 imports the teas from @/app/_lib/teas. @/ means the project's top folder, set in tsconfig.json. Line 2 imports the card from the private folder beside the page, and line 10 draws one for each tea. In app/layout.tsx, line 2 imports the logo from components.

Open the Terminal tab: the route table is /, /_not-found, /about, /cart, /checkout and /teas, the same addresses as before the shop was organized. In the Browser tab, /teas and /about work, each with its group's layout, and /_lib/teas and /components/logo answered 404. Organizing the files changed nothing a visitor can see.

Now sort the folder names from this lesson: which ones become part of an address?

Is this folder part of the address?
  • teas
  • (shop)
  • _components
  • %5Fhelp
  • checkout
  • (blog)
Try it yourself
0 of 6 correct

Sort each folder name: does it become a part of the address, or is it never in the address?

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Common mix-ups

  • "A route group adds its name to the address." No. /shop/teas and /(shop)/teas answered 404; the page is /teas.
  • "Two groups can each have their own /about." No. Both would be /about, and the build stops.
  • "A group's layout goes around every page." No. Only around the pages inside the group: /checkout didn't get the shop's layout.
  • "Moving between root layouts is a normal client-side navigation." No. Clicking Blog loaded /blog as a whole new page.
  • "A page.tsx inside a private folder still makes a page." No. /teas/_components/preview answered 404.
  • "A file in a private folder is hidden from the browser." No. It only has no address. A Client Component that imports it sends its code to the browser.

Each row is one kind of folder name: whether it becomes part of the address, and whether its pages can be visited.

Three kinds of folder names
Folder nameIs it part of the address?Can its pages be visited?
teasYes: it's /teas.Yes, if it has a page.tsx.
(shop)No. Its pages keep their addresses.Yes. Each page in it keeps its own address.
_componentsNo.No. Nothing inside it is a route, even a page.tsx.
%5FhelpYes, as /_help.Yes, if it has a page.tsx.

Practice exercises

These exercises are about Next.js projects, which can't run inside this page. Answer first, then use the hints.

Exercise 1 · Warm-upRead an address through a group

Which address does app/(shop)/cart/page.tsx make?

Starter codeText
app/
  (info)/
    about/
      page.tsx
  (shop)/
    cart/
      page.tsx
    teas/
      page.tsx
  layout.tsx
  page.tsx

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · Warm-upOpen a page in a private folder

    What does /teas/_components/preview answer?

    Starter codeText
    app/
      (shop)/
        teas/
          _components/
            preview/
              page.tsx
            tea-card.tsx
          page.tsx

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeGive checkout the shop's layout

      The shop wants the delivery line on its checkout page after all. Where does checkout/page.tsx go?

      Starter codeText
      app/
        (info)/
          about/
            page.tsx
          layout.tsx
        (shop)/
          cart/
            page.tsx
          teas/
            page.tsx
          layout.tsx
        checkout/
          page.tsx
        layout.tsx
        page.tsx

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeFix the layout's type

        With this app/(shop)/layout.tsx, the build fails its type check: Type '"/(shop)"' does not satisfy the constraint '"/"'. What goes between the angle brackets?

        Starter codeTSX
        export default function ShopLayout({ children }: LayoutProps<"/(shop)">) {
          return (
            <>
              <p>Free delivery on orders over $20.</p>
              {children}
            </>
          );
        }
        

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeA page without a root layout

          This shop has two root layouts. The build stops with about/page.tsx doesn't have a root layout. To fix this error, make sure every page has a root layout. Where should the About page go, so that it shows with the shop's links and keeps the address /about?

          Starter codeText
          app/
            (blog)/
              blog/
                page.tsx
              layout.tsx
            (shop)/
              teas/
                page.tsx
              layout.tsx
              page.tsx
            about/
              page.tsx

          Answer, then press Check. Spacing and letter case don’t matter.

            Exercise 6 · ChallengeAn address that starts with an underscore

            The shop wants a help page at /_help, but app/_help/page.tsx answers 404. What should the folder be called?

            Starter codeText
            app/
              _help/
                page.tsx
              layout.tsx
              page.tsx

            Answer, then press Check. Spacing and letter case don’t matter.

              Check your understanding

              The route groups and private folders quiz · 7 questionsScore: first tries count
              1. Question 1 of 7Which address does app/(shop)/cart/page.tsx make?

                Choose an answer to see the explanation.

              2. Question 2 of 7In this shop, which pages show the layout in (shop)/layout.tsx?

                Read the code, then predictText
                app/
                  (info)/
                    about/
                      page.tsx
                    layout.tsx
                  (shop)/
                    cart/
                      page.tsx
                    teas/
                      page.tsx
                    layout.tsx
                  checkout/
                    page.tsx
                  layout.tsx
                  page.tsx

                Choose an answer to see the explanation.

              3. Question 3 of 7Both (shop) and (info) get an about/page.tsx. What happens?

                Choose an answer to see the explanation.

              4. Question 4 of 7In the shop with two root layouts, a visitor on /teas clicks the Blog link. What does the browser do?

                Choose an answer to see the explanation.

              5. Question 5 of 7app/(shop)/teas/_components/preview/page.tsx exists. What does /teas/_components/preview answer?

                Choose an answer to see the explanation.

              6. Question 6 of 7Which folder name makes the address /_help?

                Choose an answer to see the explanation.

              7. Question 7 of 7Which type fits the layout in app/(shop)/layout.tsx, when app/layout.tsx is the only other layout?

                Choose an answer to see the explanation.

              Key takeaways

              • A folder in round brackets, like (shop), is a route group. It sorts routes and never shows in the address: app/(shop)/teas/page.tsx is /teas.
              • A layout.tsx in a group goes around the pages in that group only. Move a folder in or out to choose its layouts.
              • Two groups can't both make the same address: the build stops.
              • Without app/layout.tsx, each group can have its own root layout. Every page needs one, and moving between two root layouts is a full page load.
              • A folder starting with _ is private: nothing inside it is a route. %5F gives a real underscore in the address.
              • No address doesn't mean secret: keep secrets in code that only runs on the server.

              Remember the one-liner.
              Round brackets sort without changing the address, and an underscore keeps a folder out of routing.

              Coming next: Loading UI. It shows loading.tsx, the file that shows a loading state while a page waits for its data.

              CompleteFrontend Clear concepts. Working examples.