Layouts & Navigation
In Next.js, layouts are layout.tsx files that live next to the routes they wrap. You can nest them, and each one inherits from its parent. The mental model is inheritance: every route composes its layout from the chain of layout.tsx files above it in the folder tree.
Nuxt uses named layouts and slots. Layouts live in app/layouts/, and every page uses default.vue unless it selects another one. Layout selection is explicit rather than inherited through route folders.
The starter includes a basic layout. You'll inspect its wiring and update the navigation for the pages built so far.
Outcome
Build a shared layout with a header, navigation links, and a footer that wraps every page.
Fast Track
- Review
app/layouts/default.vueand understand the<slot />pattern - Add navigation links to all public pages
- Verify the layout persists across page transitions
Hands-on exercise 1.4
Update the default layout to include navigation links to the browse page and a placeholder for auth links we'll add later.
Requirements:
- Review how
app.vueconnects to the layout system via<NuxtLayout>and<NuxtPage> - Update
app/layouts/default.vuewith a header containing the site title and navigation links - Include a
Browselink that points to/springs - Add a placeholder comment where auth links will go in Section 3
- Include a footer
Implementation hints:
<slot />in a layout is where the page content renders. It's the equivalent of the{children}prop in a Next.jslayout.tsx<NuxtLayout>inapp.vuetells Nuxt to use the layout system.<NuxtPage />renders the matched page inside that layout- Every page gets the default layout automatically. You don't need to import it or specify it unless you want a different layout
Let's start with app.vue, the entry point:
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>NuxtLayout selects the layout, defaulting to default.vue, and NuxtPage renders the matched page inside it. Next.js wires layouts implicitly through the folder tree. Nuxt opts into the layout system through app.vue, so removing NuxtLayout would render pages without a layout.
Now the layout itself. Here's the React equivalent, for orientation:
// Next.js layout.tsx: for comparison
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<div>
<header>
<nav>
<Link href="/">Hot Springs Finder</Link>
<Link href="/springs">Browse</Link>
</nav>
</header>
<main>{children}</main>
<footer>...</footer>
</div>
);
}And the Nuxt version:
<template>
<div>
<header>
<nav>
<NuxtLink to="/">
Hot Springs Finder
</NuxtLink>
<div>
<NuxtLink to="/springs">
Browse
</NuxtLink>
<!-- Auth links will go here -->
</div>
</nav>
</header>
<main>
<slot />
</main>
<footer>
Hot Springs Finder — Built with Nuxt
</footer>
</div>
</template>The matched page renders inside <slot />, which corresponds to {children} in a React layout. Vue's dedicated slot elements can also support multiple named insertion points, although this project only uses the default slot.
Notice there's no <script> block yet. This layout is pure template. We'll add one in Section 3 when we need to check auth state and conditionally show navigation links.
Try It
Start the dev server and navigate between pages:
- Visit
http://localhost:3000. The header should show "Hot Springs Finder" and a "Browse" link - Click "Browse." The URL changes to
/springs, the page content swaps, but the header and footer stay put - Click "Hot Springs Finder" in the nav. You're back on the home page
- Visit
/favorites,/visited,/login. All pages render inside the same layout
During navigation, the layout remains mounted while the content inside <slot /> changes.
Commit
git add -A && git commit -m "feat(layout): update default layout with navigation"Done-When
- The default layout renders a header with the site title and Browse link
- Every page renders inside the layout with consistent header and footer
- Navigation between pages doesn't cause a full page reload
- You can explain how
<slot />in a Vue layout relates to{children}in a Next.js layout
Solution
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template><template>
<div>
<header>
<nav>
<NuxtLink to="/">
Hot Springs Finder
</NuxtLink>
<div>
<NuxtLink to="/springs">
Browse
</NuxtLink>
<!-- Auth links will go here -->
</div>
</nav>
</header>
<main>
<slot />
</main>
<footer>
Hot Springs Finder — Built with Nuxt
</footer>
</div>
</template>Was this helpful?