Vue cookbook · Intermediate
Lazy-load routes and keep navigation fast
The initial bundle includes every page, and the first visit to a page shows a blank screen.
Approach
Use dynamic imports for route components so each page is a separate chunk, group related pages, and prefetch
likely next pages when the browser is idle. Restore scroll positions with scrollBehavior.
Solution
// router.ts
import { createRouter, createWebHistory } from "vue-router";
const AccountLayout = () => import("./layouts/AccountLayout.vue");
export const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/", component: () => import("./pages/Home.vue") },
{
path: "/account",
component: AccountLayout,
children: [
{ path: "", component: () => import("./pages/account/Overview.vue") },
{ path: "orders", component: () => import("./pages/account/Orders.vue") },
],
},
{ path: "/:pathMatch(.*)*", component: () => import("./pages/NotFound.vue") },
],
scrollBehavior(to, _from, saved) {
if (saved) return saved; // back/forward keeps position
if (to.hash) return { el: to.hash, behavior: "smooth" };
return { top: 0 };
},
});
// Prefetch the account area once the app is idle.
if ("requestIdleCallback" in window) {
requestIdleCallback(() => void AccountLayout());
}
Pitfalls
- A catch-all route without a real 404 page or status (handle 404s on the server for SSR apps).
- Lazy-loading tiny components, creating many small requests.
- Not handling chunk load failures after deploys; reload the page when a dynamic import fails.
Variations
router.onErrorcan detect failed chunk loads and triggerlocation.reload().- Nuxt prefetches page chunks for visible
<NuxtLink>s automatically.
Further reading: Lazy loading routes
Reference: https://router.vuejs.org/guide/advanced/lazy-loading.html
More Vue recipes
- Access child component methods with template refs and defineExpose
- Add SEO metadata and structured data in Nuxt
- Build an accessible modal with Teleport
- Build custom inputs with defineModel and modifiers
- Catch component errors with an error boundary
- Debounce user input with a custom ref
- Fetch data in a composable and cancel stale requests
- Fetch, refresh and share data with Nuxt useFetch