Layout Stacking from Root to Leaf
In the app router, each directory can have its own layout.js or layout.tsx. These layouts stack from the root downward: the root layout wraps the next level, which wraps the next, and so on. This creates a compositional UI where each segment contributes its own surrounding UI. How stacking works: app/layout.tsx (root) is the outermost wrapper. app/dashboard/layout.tsx wraps everything under /dashboard. app/dashboard/settings/layout.tsx wraps everything under /dashboard/settings. Each layout receives a children prop that renders the matched page or child layout for its segment. Layout composition example: app/ ├── layout.tsx (root: html/body, global nav, persists across all nav) ├── dashboard/ │ ├── layout.tsx (dashboard: sidebar, persists across /dashboard and /dashboard/settings) │ │ ├── settings/ │ │ │ └── layout.tsx (settings: breadcrumbs, persists only under /dashboard/settings) │ │ │ └── page.js (the settings page UI) │ │ └── page.js (dashboard settings page UI) │ └── page.js (dashboard home page UI) └── page.js (home page UI) When navigating from /dashboard to /dashboard/settings using next/link: The root layout (app/layout.tsx) stays mounted. The dashboard layout (app/dashboard/layout.tsx) stays mounted. The settings layout (app/dashboard/settings/layout.tsx) mounts for the first time. Only the page.js content unmounts and remounts. Preserving UI state: Because layouts stay mounted across client-side navigation, any state, event listeners, or DOM nodes placed in a layout persist. This is the primary mechanism for keeping an open sidebar, a shopping cart icon count, or a user profile widget visible as the user navigates through a section. This layout persistence model is one of the most powerful differentiators between the Next.js app router and traditional routing approaches, because it enables UI patterns that were previously difficult or impossible to implement without custom JavaScript. The children prop: Each layout's children prop renders the output of the matched child layout or page. A layout typically looks like: export default function DashboardLayout({ children }) { return ( <aside className="sidebar" stays mounted, state persists>{/* sidebar content /}
Interview Framework for Nested Layouts
When asked about nested layouts, a strong answer covers three key areas: 1) Stacking order—the root layout is the outermost wrapper, and each subsequent layout nests within it, creating a hierarchy from root to leaf. Each layout in the hierarchy is responsible for rendering its own surrounding UI (sidebar, header, navigation, etc.) and passing the children prop down to the next level. 2) Persistence across navigation—layouts stay mounted when using next/link, which is why UI like open sidebars persists across route changes within a section. When a user navigates from /dashboard to /dashboard/settings using next/link, the root and dashboard layouts stay mounted, while only the settings page component unmounts and remounts. This is why UI like open sidebars, profile widgets, and theme preferences persist across navigation. This persistence model is a key differentiator between the app router and traditional routing, and interviewers value candidates who can explain why this matters for user experience. 3) State management—layouts are the ideal place for section-level UI state (sidebar open/closed, theme preference, profile widgets), but too much client-side state can lead to memory leaks on refresh. The recommended pattern is to initialize layout state from server data and persist cross-tab consistency via localStorage/sessionStorage if needed. A common pattern is to fetch the user's preferred sidebar state from an API on the server and then persist it in localStorage for cross-tab consistency. Interview framing: When asked about preserving UI state across navigation, a strong answer explains that layouts are the mechanism—because they stay mounted, any state placed in them persists. Mentioning that you initialize from server data and persist to localStorage for cross-tab consistency shows you understand the trade-offs. Discussing the risk of too much client-side layout state (memory leaks on refresh) shows you've thought about edge cases. Typical interview scenario: An interviewer asks: "Your application needs to keep a sidebar open across navigation within a section. How do you implement this?" A strong answer: "I'd use nested layouts, with the sidebar in the dashboard layout. Because layouts stay mounted across navigation via next/link, the sidebar state persists. I'd initialize the sidebar state from server data and persist it to localStorage for cross-tab consistency if needed." Another common question: "What persists across client-side navigation?" The answer is: "The root and intermediate layouts, not page components." Key takeaway: Layouts stack root-to-leaf; layouts persist across navigation; ideal for section-level UI state; initialize from server data; only pages unmount/remount.\n\nAdditional interview insights: Interviewers often follow up with questions about the trade-offs of layout persistence. A strong candidate will discuss both the benefits (persistent sidebars, preserved form state, consistent theming) and the risks (memory usage, stale state, the need for cleanup). They might mention that the decision of what state to place in layouts versus pages or global contexts depends on the specific application requirements, the frequency of navigation, and the need for cross-tab consistency. Another common follow-up question is: "What happens if the user opens your app in a new tab?" The answer typically involves discussing how layout state initialized from server data and persisted to localStorage can provide cross-tab consistency, while purely client-side layout state would be lost. A thoughtful answer demonstrates that you've considered not just the happy path, but also the edge cases and real-world production scenarios.\n\nKey takeaway: Layouts stack root-to-leaf; layouts persist across navigation; ideal for section-level UI state; initialize from server data; only pages unmount/remount; consider cross-tab consistency for layout state.
Quiz
1. How do layouts stack in the app router?
2. Why do layouts persist across client-side navigation?
3. What is a common use case for persisting state in layouts?
4. What should you be cautious about when placing state in layouts?
Flashcards
Question
How do nested layouts stack in the app router?
Click to reveal answer
Answer
Each segment's layout wraps its children; root is outermost, leaf is innermost. Each receives children with the matched child output.
Question
Why do layouts persist across client-side navigation?
Click to reveal answer
Answer
Layouts stay mounted; only page components unmount/remount when using next/link.
Question
What UI state is ideal for layout persistence?
Click to reveal answer
Answer
Section-level state like sidebar open/closed, theme preference, or profile widget visible within a section.
Question
What is a risk of too much client-side layout state?
Click to reveal answer
Answer
May lead to memory leaks on refresh/new tab.
Question
How can you persist layout state across tabs?
Click to reveal answer
Answer
Initialize from server data and persist to localStorage/sessionStorage for cross-tab consistency.
Revision Notes
Key Takeaways
- 1. Layouts stack root-downward; each has children prop with child output
- 2. Layouts persist across navigation; pages unmount/remount
- 3. Ideal for: sidebar state, theme, section widgets
- 4. Initialize from server data; persist to localStorage for cross-tab if needed
- 5. Only page.js unmounts/remounts; layouts stay mounted
Interview Tips
- • How do nested layouts stack?—root downward; each layout has children with child output
- • Why do layouts persist across navigation?—they stay mounted via next/link; pages unmount/remount.
- • What UI state is ideal for layouts?—sidebar open/closed, theme preference, section widgets.
- • How to avoid memory leaks?—initialize from server data, persist to localStorage for cross-tab consistency if needed.
- • What only unmounts on navigation?—page components; layouts stay mounted.
Cheat Sheet
Nested Layouts Cheat Sheet
Stacking order: root → segment → sub-segment; each layout wraps its children
Persistence: layouts stay mounted across navigation via next/link; pages unmount/remount
Ideal for: sidebar state, theme, section widgets
State initialization: initialize from server data; persist to localStorage/sessionStorage for cross-tab consistency if needed
Interview quick answers:
- How do nested layouts stack?—root downward; each layout has children with child output
- Why do layouts persist across navigation?—they stay mounted via next/link; pages unmount/remount
- What UI state is ideal for layouts?—sidebar open/closed, theme preference, section widgets
- How to avoid memory leaks?—initialize from server data, persist to localStorage for cross-tab consistency if needed
- What only unmounts on navigation?—page components; layouts stay mounted