Templates and the file hierarchy
See how layout, template, error, loading, not-found and page nest in one folder, why template.tsx starts fresh for each page, and what default.tsx does.
- 01Name the nesting orderSay which special file wraps which, and what that means for loading states, errors and not-found screens.
- 02Choose a template or a layoutTell what keeps its state between pages and what starts fresh, and pick template.tsx only when you want that.
- 03Read the tree Next.js buildsSketch the components for an address from its folders, and know when a slot needs a default.tsx.
A wrapper that starts fresh for each page
In Layouts and pages you saw that a layout.tsx wraps every page in its folder, and stays on the screen, with its state, while the visitor moves between those pages. Most of the time that's what you want. Sometimes you want the opposite: a wrapper that starts fresh on each page. That's a template, a file named template.tsx.
Here are the tea shop's tea pages with both. The tea layout has the menu of teas and a cup counter. The template puts a box for tasting notes under each tea page. 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.
app/teas/template.tsximport NotesBox from "./notes-box"; export default function TeasTemplate({ children }: { children: React.ReactNode }) { return ( <div> {children} <NotesBox /> </div> );}Cups brewed: 0
Light and fresh. $4 a box.
The page as the browser shows it when its HTML arrives, drawn with plain styles. Its JavaScript doesn't run here.
app/teas/template.tsx, the file shown first, looks like a layout. Line 3 takes children, the page, and types it as React.ReactNode, anything React can render. Line 6 puts the page there, and line 7 puts NotesBox under it. Click app/teas/notes-box.tsx: it starts with "use client", which marks where the part of the app that also runs in the browser begins, and line 6 keeps the notes in state. The template itself is a Server Component, as layouts and pages are by default; NotesBox is where the client part starts.
The Browser tab shows /teas/green: the shop's links, the tea menu and Cups brewed: 0 from the tea layout, the page, then Tasting notes from the template. Open the Network tab to see the nesting in the HTML: the tea layout's <section> holds its <nav>, the counter, and then the template's <div>; the <div> holds the page's <main> and the notes' <label>. Pick /teas/mint: the same layout and the same template, around a different page.
/teas/green, from the outside in, as the HTML in the Network tab nests it. The template sits between the tea layout and the page: it gets the page as children, and puts its notes box under it.A café sets each table once in the morning. Each new guest gets a fresh paper placemat, and doodles on it while they wait. When a guest leaves for a moment, the waiter puts their placemat aside, doodles and all, and gives it back if they return. The table never changes.
- In real life: The café table, set the same way all day
- In Next.js: The tea layout, the same for every tea page
- In real life: A paper placemat on the table
- In Next.js: The template, around the page
- In real life: A fresh placemat for each new guest
- In Next.js: A new copy of the template for each tea page
- In real life: The last few placemats kept aside, in case those guests come back
- In Next.js: Pages you left, kept hidden with their state: up to two beside the one on the screen
A template is a layout that Next.js makes again for each page under it. template.tsx sits inside the layout of its folder and wraps the rest. A layout keeps one copy, and its state, for all its pages; a template gives each page its own copy, so state inside it starts fresh on a new page.
The order of special files in one folder
Six of the special files a folder can hold wrap each other in a fixed order, the same in every folder, which Loading UI listed briefly. Each row is one file, from the outside in: what it wraps, and what that means for you.
| File | What it wraps | What that means for you |
|---|---|---|
layout.tsx | Everything else in its folder, and the folders below. | It stays on the screen around every other screen of the folder, and keeps its state between the pages under it. |
template.tsx | The error, loading and not-found screens and the page, inside the layout. | It stays around those screens too. Next.js makes a new copy of it for each page under it. |
error.tsx | The loading state, the not-found screen, the page and the folders below. | It catches what breaks inside it, never in the layout.tsx or template.tsx beside it: errors there go to the folder above. |
loading.tsx | The not-found screen, the page and the folders below, in a Suspense. | Its fallback shows inside the layout and the template, as the recording of /teas/today shows. |
not-found.tsx | The page and the folders below. | When the page calls notFound(), this screen shows inside the layout and the template. |
page.tsx | Nothing. | The innermost part: what the address itself shows. |
error.tsx can catch an error in the page, but not one in the layout.tsx or template.tsx beside it.You can see part of the order in a recording. Here the tea folder has all six files, plus a page for today's tea that reads its data for each request:
app/
teas/
green/
page.tsx
mint/
page.tsx
today/
page.tsx
error.tsx
layout.tsx
loading.tsx
not-found.tsx
page.tsx
template.tsx
layout.tsx
page.tsxapp/teas/loading.tsxexport default function Loading() { return <p>Loading the tea…</p>;}GET /teas/today200
- Response headers
Varyrsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch, Accept-Encodingx-nextjs-stale-time300x-nextjs-prerender1x-nextjs-postponed1X-Powered-ByNext.jsCache-Controlprivate, no-cache, no-store, max-age=0, must-revalidateContent-Typetext/html; charset=utf-8
The HTML that arrived, one element per line, with the code of its 19 scripts left out
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preload" as="script" fetchpriority="low" href="/_next/static/chunks/1x6obpmlu1_c2.js">
<script src="/_next/static/chunks/06bs-nf19b2js.js" async=""></script>
<script src="/_next/static/chunks/2ki52vdnbo2ft.js" async=""></script>
<script src="/_next/static/chunks/3l_qmp-61z4yc.js" async=""></script>
<script src="/_next/static/chunks/turbopack-3-ry682tkyiqk.js" async=""></script>
<script src="/_next/static/chunks/3oh00mkbkq8u6.js" async=""></script>
<script src="/_next/static/chunks/44sbnxvltlcyy.js" async=""></script>
<script src="/_next/static/chunks/02thki4p6-q9o.js" async=""></script>
<script src="/_next/static/chunks/2xcgb3osv6l_b.js" async=""></script>
<title>Tea shop</title>
<script src="/_next/static/chunks/0cz1d0mv5g_q7.js" nomodule=""></script>
</head>
<body>
<div hidden="">
<!--$-->
<!--/$-->
</div>
<nav><a href="/">Home</a> <a href="/teas">Teas</a></nav>
<!--&-->
<section>
<nav><a href="/teas/green">Green tea</a> <a href="/teas/mint">Mint tea</a></nav>
<p>Cups brewed: <!-- -->0<!-- --> <button>Brew a cup</button></p>
<!--&-->
<div>
<!--$?-->
<template id="B:0"></template>
<p>Loading the tea…</p>
<!--/$-->
<label>Tasting notes <input value=""></label>
</div>
<!--/&-->
</section>
<!--/&-->
<script>…</script>
<script id="_R_">…</script>
<script src="/_next/static/chunks/1x6obpmlu1_c2.js" async=""></script>
<div hidden="" id="S:0">
<!--&-->
<template id="P:1"></template>
<!--$-->
<!--/$-->
<!--/&-->
</div>
<script>…</script>
<script>…</script>
<script>…</script>
<script>…</script>
<script src="/_next/static/chunks/0cz1d0mv5g_q7.js" nomodule=""></script>
<div hidden="" id="S:1">
<main>
<h1>Tea of the day</h1>
<p>Mint tea, brewed at 9.</p>
</main>
</div>
<script>…</script>
<script>…</script>
</body>
</html>app/teas/loading.tsx, shown first, returns Loading the tea… on line 2. In app/teas/today/page.tsx, line 4 calls connection(), which tells Next.js to make this page for each request, and line 6 waits a second, as a slow database would. The Terminal tab lists ◐ /teas/today: a static shell made during the build, and the page streamed in for each request.
The Network tab is open on /teas/today, and shows the HTML in the order it arrived. Inside the tea layout's <section> comes the template's <div>, and inside it, <p>Loading the tea…</p>, then the notes' <label>. So the loading state sits inside the template, and the template inside the layout: the menu, the counter and the notes box show at once, and only the page waits. The page itself arrives further down, in a hidden <div>, and takes the fallback's place. error.tsx and not-found.tsx add nothing to the HTML: nothing broke, and nothing was missing.
Two rules follow from the order. First, error.tsx catches errors from what's inside it, never from the layout.tsx or template.tsx of its own folder; an error there goes to the error.tsx of the folder above. Second, the layout and the template stay on the screen around the loading, error and not-found screens of their folder, so the menu keeps working while the page part waits or fails. Error handling and Not found, forbidden and unauthorized show those screens.
Folders inside folders
Each folder's files nest inside the folder above. On /teas/green, the root layout from app wraps everything from app/teas, and the tea files wrap the page from app/teas/green. Written by hand, the tree Next.js builds for that address in the full tea folder is roughly this:
<RootLayout>
<TeasLayout>
<TeasTemplate key="green">
<ErrorBoundary fallback={<TeaError />}>
<Suspense fallback={<Loading />}>
<NotFoundBoundary fallback={<TeaNotFound />}>
<GreenTeaPage />
</NotFoundBoundary>
</Suspense>
</ErrorBoundary>
</TeasTemplate>
</TeasLayout>
</RootLayout>Line 1 is the root layout, and line 2 the tea layout. Line 3 is the template, with a key: React makes a new component whenever its key changes, and Next.js takes the key from the folder below the template, here green. Lines 4 to 6 are the three boundaries from error.tsx, loading.tsx and not-found.tsx. Line 7 is the page. This is a sketch to read, not code you write: in Next.js's code, the three boundaries are called ErrorBoundary, LoadingBoundary and HTTPAccessFallbackBoundary.
A layout stays; a template starts again
Now the difference you came for. Clicks need a browser with the page's JavaScript running, so this recording was made in real Chrome. The recorder opened /teas/green, pressed Brew a cup twice, typed Grassy into the tasting notes, clicked Mint tea, then clicked Green tea. Before you open the Steps tab, guess what the counter and the notes show after each click.
app/teas/template.tsximport NotesBox from "./notes-box"; export default function TeasTemplate({ children }: { children: React.ReactNode }) { return ( <div> {children} <NotesBox /> </div> );}Each step was taken in real Chrome against next start. Pick one to see the page after it.
Cups brewed: 2
Cool and sweet. $3 a box.
- Focus
- the link “Mint tea”
- Scrolled
- 0 px down
No requests during this step: the page already had what it needed
The Steps tab is open on step 5, right after the click on Mint tea. Cups brewed: 2: the tea layout stayed on the screen, so its BrewCounter kept its state, as in the layouts lesson. But the tasting notes are empty. Mint tea is a new page under the template, so Next.js made a new copy of the template for it, with a new NotesBox and a new, empty state. The click made no request at all: the Mint tea page had been prefetched, loaded in the background, when its link appeared.
Now pick step 6, back on Green tea. The notes say Grassy again. Next.js didn't throw Green tea's copy away when you left. With Cache Components on, as in new projects, it hides the page you leave with React's Activity, state and all, and shows it again when you come back. At each level of folders, it keeps the page on the screen plus up to two you left: in bfcache-state-manager.ts, MAX_BF_CACHE_ENTRIES is 3 with Cache Components on, counting the visible one, and 1 without. The template's copy for Green tea is part of what it kept. So a template doesn't forget everything on each visit: each page under it has its own copy, and a page you return to soon gets its copy back.
Cups brewed: 2, and one template copy for each tea page. Mint tea's copy is new, with empty notes. Green tea's copy, with Grassy, is kept hidden, and comes back with the next click on Green tea.Which navigations make a new copy? The template's key comes from the folder right below it, so a new copy comes when that part of the address changes: /teas to /teas/green, or /teas/green to /teas/mint. The docs add two cases this recording doesn't show: moving deeper below that folder doesn't make a new copy of a template higher up, and a change in the query, the part after ?, doesn't either.
When a template beats a layout
A new copy also means its Effects run again. That's the other reason to use a template: code that should run each time a page shows, like logging a page view. Here a small Client Component logs a view in an Effect, and shows how many it logged. app/teas/views.ts stands in for an analytics service:
import ViewLogger from "./view-logger";
export default function TeasTemplate({ children }: { children: React.ReactNode }) {
return (
<div>
{children}
<ViewLogger />
</div>
);
}
Line 1 imports ViewLogger, and line 7 puts it under each tea page. Both versions below use the same ViewLogger: once in the template, once in the layout. Each was clicked through in Chrome: Green tea, Mint tea, Green tea, Home, then Teas. Guess the counts first.
app/teas/template.tsximport ViewLogger from "./view-logger"; export default function TeasTemplate({ children }: { children: React.ReactNode }) { return ( <div> {children} <ViewLogger /> </div> );}Each step was taken in real Chrome against next start. Pick one to see the page after it.
Light and fresh. $4 a box.
Views logged: 3
- Focus
- the link “Green tea”
- Scrolled
- 0 px down
No requests during this step: the page already had what it needed
The template puts ViewLogger under each tea page, on line 7. Every tea page that shows runs its Effect: 1 on Green tea, 2 on Mint tea, 3 back on Green tea, and 4 on Teas.
In the template, every tea page that shows runs the Effect: Views logged: 1, 2, 3, then 4 on Teas. Even Green tea's copy, shown again from hiding, ran it again: React runs a hidden component's Effects again when it shows. In the layout, the count stays at 1 while you move between teas, because the layout never left the screen. It only logs 2 after Home and Teas, when the whole tea layout was hidden and shown again.
Next.js's docs name three reasons to pick a template:
- State that belongs to one page. An input or a form that should start empty on each page, like the tasting notes.
- Effects that run on each page. Logging a view, or anything else that must happen each time a page shows.
- A loading state on every navigation. The docs say a
Suspensein a layout shows its fallback only the first time, and one in a template shows it again on each navigation, because the template is new.
Everything else belongs in a layout. A template costs a new copy on each page, so use one only when you want that.
default.tsx: a first look
One more special file belongs in the hierarchy, though it only matters with slots. A slot is a folder whose name starts with @, like app/@offer. It's a second place for a page, beside children: the layout gets it as a prop named after the folder. Slots are part of parallel routes, which have a lesson of their own: Parallel routes. Here the shop shows a special offer above the home page:
app/@offer/default.tsxexport default function OfferDefault() { return null;}Each step was taken in real Chrome against next start. Pick one to see the page after it.
Fresh tea, sent to your door.
- Focus
- nothing: the page itself
- Scrolled
- 0 px down
Requests the page made during this step (5), without the files it loaded
GET/200a whole pageGET/200text/x-component- rsc
- 1
- next-router-prefetch
- 1
- next-router-segment-prefetch
- /_tree
- next-url
- /
GET/teas200text/x-component- rsc
- 1
- next-router-prefetch
- 1
- next-router-segment-prefetch
- /_tree
- next-url
- /
GET/teas200text/x-component- rsc
- 1
- next-router-prefetch
- 1
- next-router-segment-prefetch
- /teas/__PAGE__
- next-url
- /
GET/teas200text/x-component- rsc
- 1
- next-router-prefetch
- 1
- next-router-segment-prefetch
- /@offer/__DEFAULT__
- next-url
- /
In app/layout.tsx, line 3 takes offer next to children, and line 10 puts it above the page. app/@offer/page.tsx is the offer for /. But the slot has no page for /teas. app/@offer/default.tsx, the file shown first, is what it shows then: line 2 returns null, nothing.
The Steps tab shows when that happens. Step 1 opens /, with the offer. Step 2 clicks Teas, and the offer is still there: on a click, Next.js keeps showing the slot's last page. Step 4 opens /teas as a fresh page load, and the offer is gone. With nothing to keep, Next.js rendered default.tsx. The Network tab's /teas shows the same: no <aside>.
@offer slot has a page only for /. After a click on Teas, Next.js keeps showing the slot's last page. On a fresh load of /teas it has nothing to keep, so it renders @offer/default.tsx.Without default.tsx, Next.js 16.4.3 doesn't build at all:
app/layout.tsximport Link from "next/link"; export default function RootLayout({ children, offer }: LayoutProps<"/">) { return ( <html lang="en"> <body> <nav> <Link href="/">Home</Link> <Link href="/teas">Teas</Link> </nav> {offer} {children} </body> </html> );}$ next build▲ Next.js 16.4.3 (Turbopack)- Cache Components enabled- Partial Prefetching enabled Creating an optimized production build ...⚠ Strict route matching is enabled by default. This validation indicates a bug in your app's route structure, but you can temporarily restore loose route matching by setting `deprecated.looseRouteMatching` to `true` in your Next.js config. > Build error occurredError: Turbopack build failed with 2 errors:./app/layout.tsxError: Parallel route slots cannot render the same URLsThe following layouts have parallel route slots that cannot render the same URLs:app/layout.tsx- /teas is missing a matching page or default.tsx in @offer Every URL matched by one slot must have a matching page or default.tsx in every sibling slot. ./app/teas/page.tsxError: Unmatched app pagesThe following page files do not match any complete route:- app/teas/page.tsx Every page must be part of at least one complete route. Add matching pages or default files for the sibling parallel route slots, or remove the unreachable pages. at ignore-listed framesThe build stops with Parallel route slots cannot render the same URLs, and names the problem: /teas is missing a matching page or default.tsx in @offer. So this named slot needs a default.tsx: on a fresh load of /teas, @offer has no page and no last page to keep. (children is a slot too, without the @. The docs page for default.js still describes the older behavior for it, a 404, but Next.js 16.4.3's strict route matching stops the build when children has no default.tsx for an address its sibling slots can show. Parallel routes records both.)
Reading the tree Next.js builds
The sketch earlier was written by hand. You can read the real thing in Next.js's source, at the release every example here was built with. Two files do the work. First, create-component-tree.tsx reads each folder's special files: layout, template, error, loading, not-found, and two more for access errors, forbidden and unauthorized. A folder without a template gets React's Fragment in its place, which renders only its children (lines 218 to 226). Then it hands them to a component called LayoutRouter, which fills the layout's children (lines 696 to 724).
Second, LayoutRouter, in layout-router.tsx, nests them. Simplified, with the props and the development-only parts left out, it renders this for the folder below a layout:
<Activity key={stateKey} mode={stateKey === activeStateKey ? "visible" : "hidden"}>
<TemplateContext.Provider key={stateKey} value={
<ErrorBoundary errorComponent={error}>
<LoadingBoundary loading={parentLoadingData}>
<HTTPAccessFallbackBoundary notFound={notFound} forbidden={forbidden} unauthorized={unauthorized}>
<RedirectBoundary>
<InnerLayoutRouter tree={tree} />
</RedirectBoundary>
</HTTPAccessFallbackBoundary>
</LoadingBoundary>
</ErrorBoundary>
}>
{template}
</TemplateContext.Provider>
</Activity>In plain words, from the outside in:
- Line 1: with Cache Components on, an
Activityfor each page Next.js keeps, visible or hidden. This is what kept Green tea's notes. - Line 2: the template's place, with the
keyfrom the folder below. Your template gets lines 3 to 11 as itschildren; line 13 is your template. - Line 3: an error boundary with your
error.tsx. - Line 4: a loading boundary with your
loading.tsx. - Line 5: one boundary for
not-found.tsx,forbidden.tsxandunauthorized.tsx. - Line 6: a boundary for redirects. It catches a
redirect()that reaches the browser while the page renders, and moves the router to the new address (Redirects covers the function). - Line 7: the folder below, with its own layout and its own
LayoutRouter, all the way down to the page.
That's the whole hierarchy: the order of the boundaries in this one component. How a route becomes a React tree, in the course's last stage, reads these files properly.
Layout or template for the tea shop?
Each row asks one question of both files:
| Question | layout.tsx | template.tsx |
|---|---|---|
| How many copies are there? | One, for every page under it. | One for each page under it. |
| What happens on a click to another page under it? | It stays, with its state. | A new copy for the new page, with fresh state. |
| What happens when you come back to a page you left? | It's the same one it always was. | Its old copy comes back, with its state, if Next.js kept it hidden: with Cache Components on, up to two pages you left, beside the one on the screen. |
| When do Effects inside it run? | Once, and again only after the whole layout was hidden and shown. | Each time a page under it shows. |
| What is it good for? | Menus, headers, and state the pages share. | State that belongs to one page, like a notes box, and logging each page view. |
Sort the tea shop's parts: which file should hold each one?
- The tea menu at the top of every tea page.
- A cup counter that keeps counting as the shopper moves between teas.
- A tasting notes box that should be empty on each new tea.
- An Effect that logs a page view each time a tea page shows.
- A small cart summary that should keep what the shopper added.
- A "Was this page helpful?" form whose answer belongs to one page.
Sort each part of the tea pages: does it belong in the layout, or in a template?
Common mix-ups
- "A template replaces the layout." No. It goes inside the layout of its folder, and a folder can have both, as the tea folder does.
- "A template starts fresh on every visit." No. Each page under it gets its own copy. Coming back to a page you left soon brings its copy back, with its state.
- "A template has to be a Client Component." No. Like a layout, it starts as a Server Component; the state lives in the Client Components it renders.
- "
error.tsxcatches errors in the layout beside it." No. The layout and the template are outside it. Theerror.tsxof the folder above catches those. - "The loading state replaces the whole folder." No. It shows inside the layout and the template; only the page part waits.
- "
default.tsxis the page for a folder." No. That'spage.tsx.default.tsxstands in for a slot that has no page for the address.
Practice exercises
These exercises are about Next.js projects, which can't run inside this page.
Write these six special files of one folder from the outside in.
page.tsx
error.tsx
layout.tsx
not-found.tsx
template.tsx
loading.tsxlayout, template, error, loading, not-found, page. Each one wraps the ones after it, which is why error.tsx can't catch an error in the layout or the template of its folder.
This is app/teas/today/page.tsx in the full tea folder. In the first HTML of /teas/today, what shows where the page will go?
import { connection } from "next/server";
export default async function TodayPage() {
await connection();
// Wait a moment, as a real database would, so the recording can catch the loading state.
await new Promise((resolve) => setTimeout(resolve, 1000));
return (
<main>
<h1>Tea of the day</h1>
<p>Mint tea, brewed at 9.</p>
</main>
);
}
Loading the tea…, from loading.tsx. The recording's first HTML has it inside the template's <div>, above the notes box, with the menu and the counter around it.
On Green tea, you press Brew a cup twice, then click Mint tea. With this template and the counter in the tea layout, what does the counter say on Mint tea?
import NotesBox from "./notes-box";
export default function TeasTemplate({ children }: { children: React.ReactNode }) {
return (
<div>
{children}
<NotesBox />
</div>
);
}
Cups brewed: 2. The layout stays on the screen across the tea pages, so its counter keeps its state. Step 5 of the recording shows it.
Then you type Grassy into the notes on Green tea, click Mint tea, and click Green tea again. What do the notes say?
Grassy. Green tea's copy of the template was kept hidden while Mint tea was on the screen, and came back with its state. Step 6 of the recording shows it.
With ViewLogger in the template, you open Green tea, then click Mint tea, Green tea, Home and Teas. What does the page say on Teas?
import ViewLogger from "./view-logger";
export default function TeasTemplate({ children }: { children: React.ReactNode }) {
return (
<div>
{children}
<ViewLogger />
</div>
);
}
4. Green tea logs 1, Mint tea 2, Green tea again 3, Home has no tea page, and Teas logs 4. The recording's last step shows Views logged: 4.
The shop's build fails with /teas is missing a matching page or default.tsx in @offer. Which file is missing? Write it so the offer shows nothing on /teas.
// app/@offer/default.tsx
export default function OfferDefault() {
// What should the offer slot show on pages it has no page.tsx for?
}export default function OfferDefault() {
return null;
}
app/@offer/default.tsx, returning null. With it, the build passes and lists ○ / and ○ /teas, and a fresh load of /teas shows no offer.
Check your understanding
For each question, find the file in the nesting order, and ask whether a new copy of it was made.
Question 1 of 7In one folder, which file sits outside
error.tsx, soerror.tsxcan't catch what breaks in it?Choose an answer to see the explanation.
Question 2 of 7The recorder typed Grassy into the template's notes on Green tea, then clicked Mint tea. What does the notes box show?
Read the code, then predictTSXimport NotesBox from "./notes-box"; export default function TeasTemplate({ children }: { children: React.ReactNode }) { return ( <div> {children} <NotesBox /> </div> ); }Choose an answer to see the explanation.
Question 3 of 7Then the recorder clicked Green tea again. What do the notes show now?
Choose an answer to see the explanation.
Question 4 of 7
ViewLoggerlogs a view in an Effect. In the template, the recording counts 1, 2, 3 over Green tea, Mint tea and Green tea. What does it count in the layout?Choose an answer to see the explanation.
Question 5 of 7What does Next.js render inside
{children}ofapp/teas/template.tsxon/teas/today, before the page is ready?Choose an answer to see the explanation.
Question 6 of 7This is
app/@offer/default.tsx. When does Next.js render it?Read the code, then predictTSXexport default function OfferDefault() { return null; }Choose an answer to see the explanation.
Question 7 of 7Without
app/@offer/default.tsx, what happens?Choose an answer to see the explanation.
Key takeaways
- In one folder, the special files nest in this order:
layout,template,error,loading,not-found,page. A folder below nests inside the folder above. - The layout and the template stay around the loading, error and not-found screens;
error.tsxnever catches errors from the layout or template beside it. - A layout is one copy for all its pages. A template is a new copy for each page under it, so state inside it starts fresh on a new page.
- With Cache Components on, a page you leave is kept hidden with its state, template copy included, and comes back as it was.
- Effects in a template run each time a page shows. Use a template for per-page state and per-page Effects; use a layout for the rest.
- A named slot, a folder starting with
@like@offer, shows itsdefault.tsxon a fresh load of an address it has no page for. Without one, this shop's build stopped.
Remember the one-liner.
Layout, template, error, loading, not-found, page: a layout stays for all its pages, and a template is made again for each one.
Coming next: Server Components in Next.js. It starts the stage about where your code runs, with the kind of component every layout, template and page starts as.