Skip to content

Smart Layout System

This implementation follows the Vue 3 smart layout pattern as described in the article “Vue 3 layout system: smart layouts for VueJS”. The system provides dynamic layout switching based on route metadata.

Main Layout Wrapper (src/layouts/AppLayout.vue)

Section titled “Main Layout Wrapper (src/layouts/AppLayout.vue)”
<template>
<component :is="$route.meta.layoutComponent">
<slot />
</component>
</template>

This is the main layout that dynamically renders different layout components based on the route metadata.

Layout Middleware (src/router/middleware/loadLayoutMiddleware.ts)

Section titled “Layout Middleware (src/router/middleware/loadLayoutMiddleware.ts)”
export async function loadLayoutMiddleware(route: RouteLocationNormalized) {
try {
const layout = route.meta.layout || 'AppLayout'
const layoutComponent = await import(`@/layouts/${layout}.vue`)
route.meta.layoutComponent = layoutComponent.default
} catch (error) {
// Load default layout on error
}
}

This middleware dynamically imports layout components before each route navigation.

  • Use Case: Authentication pages (login, register)
  • Features: Centered card layout with branding and footer
  • Styling: Gradient background, clean minimal design
  • Use Case: Main application pages for authenticated users
  • Features: Header with navigation, main content area, footer
  • Styling: Full-width layout with sticky header
  • Use Case: Administrative interface
  • Features: Sidebar navigation, admin header, dedicated admin styling
  • Styling: Dark sidebar, admin-specific navigation

Routes are configured with layout metadata:

{
path: "/login",
name: "login",
component: LoginView,
meta: {
layout: 'AuthLayoutGuest'
},
},
{
path: "/",
name: "home",
component: HomeView,
meta: {
requiresAuth: true,
layout: 'AppLayoutUser'
},
}

The main App.vue wraps the RouterView with the dynamic AppLayout:

<template>
<AppLayout>
<RouterView />
</AppLayout>
<Toaster />
</template>
  1. Dynamic Layout Switching: Layouts change automatically based on route
  2. Code Splitting: Layouts are dynamically imported only when needed
  3. Scalable: Easy to add new layouts without router changes
  4. Maintainable: Clear separation of layout concerns
  5. Flexible: Each layout can have completely different structure and styling
  6. Error Handling: Graceful fallback to default layout on errors
  1. Create a new layout file in src/layouts/ (e.g., AppLayoutDashboard.vue)
  2. Add the layout name to route meta: meta: { layout: 'AppLayoutDashboard' }
  3. The middleware will automatically load and apply the new layout
  • AuthLayout* - Authentication-related layouts
  • AppLayout* - Main application layouts
  • AdminLayout* - Administrative layouts
  • Use descriptive suffixes: Guest, User, Admin, Dashboard, etc.

If a layout fails to load, the system automatically falls back to the default AppLayout to ensure the application remains functional.