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

File-system routing

See how Next.js turns folders into URLs: each folder is a segment, page.tsx makes a route public, folders nest, and other files in app never become routes.

By the end, you can
  • 01
    Map folders to URLsTell which address a page.tsx makes from the folders it sits in, at any depth.
  • 02
    Say when a route is publicExplain why a folder without page.tsx answers 404, and which file names make a page.
  • 03
    Keep other files beside your pagesPut components and data next to the page that uses them, knowing they never get an address.

Folders become addresses

A route is an address in your app, like /teas, and the page it shows. Most tools ask you to list your routes in code. Next.js doesn't: its App Router, the router this course teaches, reads the folders inside app, and the folders are the list. That's called file-system routing. If you built the notes app in Your first Next.js app, you already used it: app/new/page.tsx was the page for /new. This lesson gives you the rules behind that.

Here is the tea shop with three pages. 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: three folders, three pagesNext.js
app/about/teas/
app/teas/page.tsx
export default function TeasPage() {  return (    <main>      <h1>Our teas</h1>      <ul>        <li>Green tea</li>        <li>Mint tea</li>      </ul>    </main>  );}
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.

app/teas/page.tsx exports its component with export default on line 1, and line 4 is its heading, Our teas. Nothing in the file says /teas: its place does. The file sits in a folder named teas, inside app, so it's the page for /teas. In the same way, app/page.tsx is / and app/about/page.tsx is /about. app/layout.tsx is the root layout: it goes around every page, and its links on line 10 lead to all three.

Open the Terminal tab. After building, next build prints the routes it found: ○ /, ○ /_not-found, ○ /about and ○ /teas. You never wrote that list. The build made it from the folders, and added /_not-found, the page for addresses that don't exist. The ○ in front of each one means prerendered as static content, as the legend under the table says: every page in this lesson is. In the Browser tab, click Teas and About to switch between the recorded pages.

An editor window for the app folder lists page.tsx, teas/page.tsx, about/page.tsx and layout.tsx. Arrows go from the three page files to tags for the addresses slash, slash teas and slash about. layout.tsx has no arrow: it goes around every page.apppage.tsxteas/page.tsxabout/page.tsxlayout.tsx//teas/aboutaround every page: no address
The tea shop's app folder. Each page file becomes the address of the folders it sits in. layout.tsx has no address: it goes around every page.
Real-life analogyA postal address

A postal address narrows down step by step: the street, then the house on it, then the flat inside. A visitor can only knock where there's a front door. A hallway between flats has no door of its own, and the boxes stored inside a flat have no address of their own.

In real life: Each part of a postal address: the street, then the house, then the flat
In Next.js: Each folder: one part of the URL, in order
In real life: A front door with a bell, where visitors can knock
In Next.js: A page.tsx, which makes the address a page
In real life: A hallway with no door of its own
In Next.js: A folder without page.tsx: its address answers 404
In real life: Boxes stored inside a flat
In Next.js: Other files beside page.tsx, which get no address of their own
The main idea

In the App Router, the folders in app are your routes. Each folder is one part of the address, and a page.tsx in a folder makes that address a page that visitors can open. Ordinary files beside it, like a component or some data, get no route of their own: page and route are the two files that make a route public.

One folder for each part of the address

The part of a URL after the site's name is its path: in localhost:3000/teas/green, the path is /teas/green. The / characters split a path into parts called segments: here, teas and green. Next.js matches each segment with one folder, in order:

The address slash teas slash green, split into three cards: slash, the root segment; teas; and green. An arrow goes down from each card to a folder: app, teas and green. A page.tsx card sits in the green folder./teas/green/folderapp/teasfolderteas/greenfoldergreen/page.tsxthe root segment
/teas/green in parts: the root segment /, then teas, then green. Each part is one folder, and the page.tsx in the last folder is the page.
  • The root segment is app itself. It stands for /, and its name never shows in the address. That's why app/page.tsx is the page for /, not /app.
  • Every folder inside app is one more segment, with the folder's name as the text of the address: app/teas is /teas.
  • A folder inside that one adds the next segment: app/teas/green is /teas/green.

Each row is one address from this lesson's recordings: its segments, and the folder its page sits in.

Addresses and their folders
AddressIts segmentsThe folder of its page
/None: the root segmentapp
/teasteasapp/teas
/teas/greenteas, then greenapp/teas/green
/account/ordersaccount, then ordersapp/account/orders

Because a folder's name is the text of the address, name folders the way you want the address to read: short, lowercase words, with hyphens between them, like gift-boxes for /gift-boxes.

Folders inside folders

A route made of several segments is a nested route. The shop wants a page for each tea, so app/teas gets a folder for each: green and mint, each with its own page.tsx. The list at /teas now links to them.

A page for each tea, one folder deeperNext.js
app/about/teas/green/mint/
app/teas/green/page.tsx
export default function GreenTeaPage() {  return (    <main>      <h1>Green tea</h1>      <p>Light and fresh. $4 a box.</p>    </main>  );}
Recorded from Next.js 16.4.3
localhost:3000/teasTea shop
Home About
Our teas

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

app/teas/green/page.tsx is an ordinary page: a heading on line 4 and a line about the tea on line 5. Its folders, teas then green, make its address /teas/green. In app/teas/page.tsx, lines 9 and 12 link to /teas/green and /teas/mint.

The Terminal lists two new routes, ○ /teas/green and ○ /teas/mint, under ○ /teas. In the Browser, click Green tea. The page shows the layout's links, then Green tea and Light and fresh. $4 a box., and nothing from the /teas page. A nested route doesn't show its parent page; each address shows one page. What pages share goes in a layout, and folders can have layouts of their own, which the next lesson shows.

One folder for each tea works for two teas. For two hundred, you write one folder whose name is a placeholder, and Next.js fills it from the address. That's a dynamic route, a few lessons on, in Dynamic routes.

page.tsx makes a route public

A folder gives a route its place, but not a page. Only a page file makes the route public: an address that visitors can open. The shop's account area shows the difference. It has app/account/orders/page.tsx, so /account/orders is a page. The folder above it, app/account, holds only that folder. Pick a version, then look at what /account answered.

Playground: does /account have a page?
The tea shop, with this app/account folderNext.js
app/about/account/orders/teas/
app/account/orders/page.tsx
export default function OrdersPage() {  return (    <main>      <h1>Your orders</h1>      <p>No orders yet.</p>    </main>  );}
Recorded from Next.js 16.4.3
localhost:3000/account404: This page could not be found.
Home Teas 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
Only orders/page.tsx

The folder account holds only another folder. /account/orders is a page, but /account has no page.tsx, so it answers 404, with the page Next.js made for addresses that don't exist.

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

In the first version, /account answered with a page that says 404 and This page could not be found. Open its Network tab: the status is 404, the title is 404: This page could not be found., and the page is the one Next.js made as /_not-found. The route table has ○ /account/orders but no /account. In the second version, app/account/page.tsx adds ○ /account, and the same request answers 200 with Your account.

A terminal window titled next build lists five routes: slash, slash underscore not-found, slash about, slash account slash orders, and slash teas. A card for the request slash account slash orders has an arrow to a card, Your orders, marked 200. A card for the request slash account has an arrow to a card, 404 page, marked 404: the list has no slash account.next build//_not-found/about/account/orders/teasa request/account/ordersYour orders200: founda request/account404 page404: not in the list
In this shop, next build lists every route. A request for /account/orders finds its page. /account isn't in the list, because app/account has no page file, so Next.js answers with the 404 page.

So next build reads the folders and builds a tree of routes from them. In this shop, every route is a fixed address, so the tree is the list in the Terminal: a request for a path in it gets its page, and any other path gets the 404 page. A route can also be a pattern, with a folder name like [slug] that matches addresses the build never listed; Dynamic routes shows those.

Which names count as a page file? Each button below is the same About page, saved under a different name. Before you click, guess which ones make /about.

Playground: which file makes /about?
The tea shop, with the About page in this fileNext.js
app/about/teas/
app/about/page.tsx
export default function AboutPage() {  return (    <main>      <h1>About us</h1>      <p>We sell tea from one small 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 (5/5)  Finalizing page optimization ... Route (app)┌ ○ /├ ○ /_not-found├ ○ /about└ ○ /teas ○  (Static)  prerendered as static content
Try it yourself
about/page.tsx

A folder named about with a page.tsx in it: the build lists ○ /about, and /about answers 200 with the page.

Each version was built with next build from Next.js 16.4.3 and run with next start, which was asked for /about. The file's content is the same About page in all four; only its name and place change. Reset goes back to the first version.

about/page.tsx and about/page.js make a page: the App Router accepts page.js, page.jsx and page.tsx. about/index.tsx and about.tsx don't, and /about answers 404. Those two names come from the Pages Router, Next.js's older router, which reads a pages folder: there, every file is a page, pages/about.tsx is /about, and pages/index.tsx is /. It's still supported, and you'll meet it in older projects. In the App Router, only page files make pages.

One more file makes a route public

A route.ts file makes a route public too, but it answers with data, like JSON, instead of a page. It's called a Route Handler, and Route Handlers, in the Fetching and mutating data stage, teaches it. A folder holds a page file or a route.ts, not both.

Files that never become routes

Since only page files make addresses here, every other file in app has no address. You can keep a page's own parts right next to it, which is called colocation. Here, the teas page takes its list from data.ts and draws each tea with tea-card.tsx, both in app/teas.

A component and data beside the teas pageNext.js
app/about/teas/
app/teas/page.tsx
import TeaCard from "./tea-card";import { teas } from "./data"; export default function TeasPage() {  return (    <main>      <h1>Our teas</h1>      <ul>        {teas.map((tea) => (          <TeaCard key={tea.slug} name={tea.name} price={tea.price} />        ))}      </ul>    </main>  );}
Recorded from Next.js 16.4.3
localhost:3000/teasTea shop
Home About
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.

Lines 1 and 2 of app/teas/page.tsx import the two files beside it. Line 10 draws a TeaCard for each tea in teas. The /teas page shows Green tea: $4 and Mint tea: $3, so both files did their job.

Now pick /teas/tea-card and /teas/data in the Browser tab. The recorder asked for both, and both answered 404. The route table still has one route for the folder, ○ /teas. A component or a data file beside a page is part of that page, and has no address of its own.

No address doesn't mean private

A file without an address can still reach the browser in other ways. What a page renders is in its HTML: both teas' names and prices from data.ts are right there in the Network tab. And the code of a Client Component, with everything its file imports, is sent to the browser too. So never keep a secret, like a password or a key, in a file just because it has no address. The Server-only code and environment variables lesson shows where secrets belong.

An editor window for the app/teas folder lists page.tsx, tea-card.tsx and data.ts. An arrow goes from page.tsx to a tag for slash teas. tea-card.tsx and data.ts are labeled: used by page.tsx, no address of their own.app/teaspage.tsxtea-card.tsxdata.ts/teasused by page.tsx,no address of their ownshaded: the only file with an address
Three files in app/teas, one address. page.tsx is the page for /teas, and it uses the other two files. tea-card.tsx and data.ts have no address: /teas/tea-card and /teas/data answer 404.

Other files in app never become routes either. layout.tsx goes around pages, and other special files, like loading.tsx for a loading screen, each do one job for a route, as the next lessons show. Two folder names change the rules on purpose: a folder whose name starts with _, like _components, is left out of routing with everything in it, and a folder in brackets, like (shop), groups routes without adding a segment. Route groups and private folders, later in this stage, covers both.

Planning the tea shop's folders

When you plan an app, start from the addresses you want, then make a folder for each segment and a page file where the address should open. Each row is one address the recordings in this lesson served, and the file that made it.

The tea shop's addresses and files
AddressFileWhat it shows
/app/page.tsxThe home page.
/teasapp/teas/page.tsxThe list of teas.
/teas/greenapp/teas/green/page.tsxOne tea's page.
/aboutapp/about/page.tsxAbout the shop.
/about/teamapp/about/team/page.tsxThe people who pack the boxes.
/accountapp/account/page.tsxThe visitor's account.
/account/ordersapp/account/orders/page.tsxThe visitor's orders.

Notice /account and /account/orders: they're two pages, so they need two page files, one in each folder. Now sort these files: which ones make a page?

Does this file make a page?
  • app/page.tsx
  • app/teas/green/page.tsx
  • app/about/page.js
  • app/about/index.tsx
  • app/about.tsx
  • app/teas/tea-card.tsx
  • app/teas/data.ts
  • app/layout.tsx
Try it yourself
0 of 8 correct

Sort each file of the tea shop: does it make a page, or is it never a page?

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

Common mix-ups

  • "Every file in app is a page." No. Only page files are. /teas/tea-card and /teas/data answered 404.
  • "app/about.tsx makes /about." No. Only folders make segments: the recorded /about answered 404.
  • "index.tsx is a folder's page." No. That's the Pages Router. The App Router looks for page.tsx, page.jsx or page.js.
  • "A folder is enough to make its address work." No. Without a page file, /account answered 404, though /account/orders worked.
  • "A nested page shows its parent page too." No. /teas/green showed only its own page, inside the layout. Shared parts go in layouts.
  • "You list the routes somewhere." No. next build reads the folders and prints the list itself.

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 from the folders

These are the shop's files. Which address does app/teas/green/page.tsx make?

Starter codeText
app/
  about/
    page.tsx
  teas/
    green/
      page.tsx
    mint/
      page.tsx
    page.tsx
  layout.tsx
  page.tsx

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

    Exercise 2 · Warm-upName the file for an address

    The shop wants this page at /about/team. Where does the file go?

    Starter codeTSX
    export default function TeamPage() {
      return (
        <main>
          <h1>Our team</h1>
          <p>Asha and Ravi pack every box.</p>
        </main>
      );
    }
    

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

      Exercise 3 · PracticeSpot the address that answers 404

      With these files, one of /account and /account/orders answers 404. Which one?

      Starter codeText
      app/
        about/
          page.tsx
        account/
          orders/
            page.tsx
        teas/
          page.tsx
        layout.tsx
        page.tsx

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

        Exercise 4 · PracticeFix the missing About page

        A teammate saved this About page as app/about/index.tsx, and /about answers 404. What should the file be named?

        Starter codeTSX
        export default function AboutPage() {
          return (
            <main>
              <h1>About us</h1>
              <p>We sell tea from one small shop.</p>
            </main>
          );
        }
        

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

          Exercise 5 · ChallengeOpen the tea card

          A visitor types /teas/tea-card. What does the shop answer?

          Starter codeText
          app/
            teas/
              data.ts
              page.tsx
              tea-card.tsx

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

            Exercise 6 · ChallengeFind why the build stops

            With this file as app/about/page.js, next build stops with The default export is not a React Component in "/about/page". What's missing?

            Starter codeJSX
            export function AboutPage() {
              return (
                <main>
                  <h1>About us</h1>
                  <p>We sell tea from one small shop.</p>
                </main>
              );
            }
            

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

              Check your understanding

              For each question, walk the folders from app, and ask whether the last one has a page file.

              The File-system routing quiz · 7 questionsScore: first tries count
              1. Question 1 of 7Which address does app/teas/mint/page.tsx make?

                Choose an answer to see the explanation.

              2. Question 2 of 7This shop has no app/account/page.tsx. What does /account answer?

                Read the code, then predictText
                app/
                  about/
                    page.tsx
                  account/
                    orders/
                      page.tsx
                  teas/
                    page.tsx
                  layout.tsx
                  page.tsx

                Choose an answer to see the explanation.

              3. Question 3 of 7Which of these files makes /about a page?

                Choose an answer to see the explanation.

              4. Question 4 of 7Where does the list of routes that next build prints come from?

                Choose an answer to see the explanation.

              5. Question 5 of 7What does the recorded /teas/green show?

                Choose an answer to see the explanation.

              6. Question 6 of 7app/teas/tea-card.tsx sits next to app/teas/page.tsx. What does /teas/tea-card answer?

                Choose an answer to see the explanation.

              7. Question 7 of 7Which folders does Next.js follow for /account/orders?

                Choose an answer to see the explanation.

              Key takeaways

              • The App Router builds its routes from the folders in app. next build prints the list; you never write it.
              • Each folder is one segment of the address. app is the root segment, /, so app/teas/green is /teas/green.
              • A page.tsx (or page.jsx, or page.js) makes a route public. A folder without one answers 404, even when the folders inside it have pages.
              • Each address shows one page, inside the layout. A nested page doesn't show its parent page.
              • Every other file in app, like a component or data beside a page, never gets an address. index.tsx and about.tsx are Pages Router names, not App Router pages.

              Remember the one-liner.
              Folders make the address, and page.tsx opens the door.

              Coming next: Layouts and pages. It shows the root layout in full, layouts inside folders that wrap only their own pages, and the props each one gets.

              CompleteFrontend Clear concepts. Working examples.