vite-plugin-vue-meta-layouts
raw JSON → 0.6.1 verified Mon Apr 27 auth: no javascript
Vite plugin providing a meta-based layout system for vue-router. Current version 0.6.1 (released 2023), with active development and frequent releases. Key differentiator from vite-plugin-vue-layouts: proper HMR support in modern Vite versions. Allows defining layouts via route meta (e.g., meta: { layout: 'other' }) or using a default layout. Supports both sync and async import modes, file-based routing plugins (vite-plugin-pages, unplugin-vue-router), customizable layout directory, excludes, and meta field name. Written in TypeScript with bundled types. Requires Vite >=2.0.0 and vue-router >=4.0.14.
Common errors
error Cannot find module 'virtual:meta-layouts' or its corresponding type declarations. ↓
cause TypeScript declarations for the virtual module are not included without the client types augmentation.
fix
Add
"types": ["vite-plugin-vue-meta-layouts/client"] to your tsconfig.json compilerOptions. error [vite] Internal server error: The layout 'default' is not defined in the layouts directory. ↓
cause Missing or misnamed layout file in src/layouts/ (default.vue).
fix
Ensure src/layouts/default.vue exists and exports a valid Vue component. Or change defaultLayout option to an existing layout.
error TypeError: setupLayouts is not a function ↓
cause Importing setupLayouts from the wrong source (likely 'vite-plugin-vue-meta-layouts' instead of 'virtual:meta-layouts').
fix
Change import to
import { setupLayouts } from 'virtual:meta-layouts'. Warnings
gotcha setupLayouts must be imported from 'virtual:meta-layouts', not from the package itself. ↓
fix Use `import { setupLayouts } from 'virtual:meta-layouts'` in your route configuration file.
breaking In v0.6.0, the 'metaName' option was added, changing the default meta field from 'layout' to potentially custom names. If you rely on the default, ensure you don't pass a different metaName inadvertently. ↓
fix If you were relying on the meta field name before v0.6.0, it remains 'layout' by default. Only breaking if you used a different metaName explicitly.
deprecated The 'skipTopLevelRouteLayout' option exists but is labeled as fixing a specific issue; it's not deprecated but may cause confusion if misused. ↓
fix Only set skipTopLevelRouteLayout: true if you encounter the nested route issue referenced in https://github.com/JohnCampionJr/vite-plugin-vue-layouts/issues/134.
gotcha The 'excludes' option accepts glob patterns, not exact paths. For example, use 'excludes: ['**\\/secret/*']'. ↓
fix Use glob patterns like 'excludes: ['**/secret/*']' to exclude routes from layout wrapping.
Install
npm install vite-plugin-vue-meta-layouts yarn add vite-plugin-vue-meta-layouts pnpm add vite-plugin-vue-meta-layouts Imports
- MetaLayouts wrong
const MetaLayouts = require('vite-plugin-vue-meta-layouts')correctimport MetaLayouts from 'vite-plugin-vue-meta-layouts' - setupLayouts wrong
import { setupLayouts } from 'vite-plugin-vue-meta-layouts'correctimport { setupLayouts } from 'virtual:meta-layouts' - ClientOptions wrong
import { ClientOptions } from 'vite-plugin-vue-meta-layouts'correctimport type { ClientOptions } from 'vite-plugin-vue-meta-layouts/client' - setupLayouts (type) wrong
import { setupLayouts } from 'vite-plugin-vue-meta-layouts'correctimport { setupLayouts } from 'virtual:meta-layouts'
Quickstart
// vite.config.ts
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import MetaLayouts from 'vite-plugin-vue-meta-layouts'
export default defineConfig({
plugins: [Vue(), MetaLayouts()],
})
// src/layouts/default.vue
<template>
<div>
<h1>Default Layout</h1>
<router-view />
</div>
</template>
// src/main.ts (or router setup)
import { createRouter, createWebHistory } from 'vue-router'
import { setupLayouts } from 'virtual:meta-layouts'
const routes = setupLayouts([
{
path: '/',
component: () => import('./pages/Home.vue'),
},
{
path: '/about',
component: () => import('./pages/About.vue'),
meta: { layout: 'other' },
},
])
export default createRouter({
routes,
history: createWebHistory(),
})