Cansu Arı Logo
Blog
What is it?

Layout and Page Lifecycle: In What Order Do Hooks Run?

In Nuxt 3, layout, page, and component lifecycles interleave. onMounted, onBeforeRouteUpdate, onRenderTracked...

  • #Nuxt 3
  • #Vue.js

Skip to content

When does each hook run?

Vue and Nuxt’s reactivity makes apps feel intuitive, but lifecycles can be tricky.
When navigating between pages, which hook runs when? When does the layout mount? Where does useAsyncData kick in?

The Core Idea

Nuxt 3 has three main layers:
  1. Layout → The skeleton (e.g., navbar, footer).
  2. Page → Route-specific content.
  3. Component → Child components used by the page.
Each has its own lifecycle, and Nuxt orchestrates them for optimal performance. Understanding the order matters across SSR, CSR, and route changes.

Initial Page Load (SSR Phase)

On the very first load with SSR, events occur in this order:
  1. Server-side setupuseAsyncData, useFetch kick off.
  2. Server render → HTML is produced and sent.
  3. Hydration → The client boots the Vue app.
  4. onBeforeMount → Right before nodes attach to the DOM.
  5. onMounted → The DOM is ready—do browser-only work.
During SSR, only setup() and useAsyncData() run. Hooks like onMounted run only on the client.

Route Change Flow (CSR Phase)

When navigating client-side, SSR is out of the picture:
  1. onBeforeRouteLeave (old page) → Runs before leaving. Use for cleanup or guards.
  2. onBeforeRouteUpdate (layout/page) → Fires when route params change under the same layout.
  3. Page setup() → The new page’s setup runs; call useAsyncData here.
  4. onBeforeMount (new page) → Before mounting to the DOM.
  5. onMounted (new page) → After visual render.
  6. onUpdated (page/component) → After reactive updates change the DOM.
If the layout doesn’t change, only the page remounts—the layout stays put.

Layout vs Page Hook Hierarchy

PhaseLayout HookPage Hook
Server Rendersetup()setup()
HydrationonBeforeMountonBeforeMount
MountonMountedonMounted
Route UpdateonBeforeRouteUpdateonBeforeRouteUpdate
UnmountonUnmountedonUnmounted
Important: The layout only re-renders when it changes. Under the same layout, page switches don’t remount the layout.

Example Flow: Blog List → Blog Detail

Going from /blog to /blog/123:
  1. The layout (default.vue) stays; only the page updates.
  2. onBeforeRouteUpdate triggers at both layout and page levels.
  3. Page setup runs again (useAsyncData refetches).
  4. onMounted fires when new content is in the DOM.
The layout staying mounted means your navbar/footer aren’t rebuilt—great for performance. ⚡

Using onBeforeRouteLeave and onBeforeRouteUpdate

Warn before leaving a page:
onBeforeRouteLeave((to, from) => {
if (formChanged.value) {
const confirmLeave = confirm('Unsaved changes. Leave anyway?')
if (!confirmLeave) return false
}
})
Refetch on param change:
onBeforeRouteUpdate((to) => {
fetchPost(to.params.id)
})
This updates data on param-only changes without recreating the page.

Pro Tip: Global Hook Management

You can add global hooks in app.vue or layouts/default.vue. For example, a loading animation during route changes:
onBeforeRouteUpdate(() => startLoading())
onBeforeRouteLeave(() => stopLoading())
Or define global router guards in a plugin:
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('page:start', () => console.log('Loading new page...'))
nuxtApp.hook('page:finish', () => console.log('Page loaded!'))
})

Lifecycle Order — Quick Summary

SSR phase: setup() → render → hydration
CSR phase: onBeforeRouteLeave → setup() → onMounted → onUpdated → onUnmounted
The layout remounts only when it changes. The page component runs on every route change.

Common Pitfalls

  1. Calling useAsyncData inside onMounted → misses SSR data.
  2. Fetching with useRoute params only in onMounted → won’t update on param changes.
  3. Assuming the layout is implicitly keep-alive → it can remount; state may reset.
  4. Forgetting to reset reactive state on route change → stale data leaks into new pages.

Conclusion

Nuxt 3 balances SSR and CSR lifecycles elegantly. Understanding the order helps you place data fetching, animations, cache, and auth at the right moments.

In short:

  • SSR → setup & useAsyncData
  • CSR → onBeforeRouteUpdate & onMounted
  • Layout → remounts only when it changes

Use the right hook at the right time for a smoother Nuxt app flow.

All tags
  • Nuxt 3
  • Vue.js