Vite Plugin for Vue Router Layouts
vite-plugin-vue-layouts is a Vite plugin designed to simplify the implementation of router-based layouts in Vue 3 applications. It is currently at version 0.11.0 and is actively maintained, with regular updates and fixes. The plugin works by transforming Vue Router configurations, effectively wrapping page components within specified layout components as nested routes. It integrates seamlessly with `vite-plugin-pages` and `unplugin-vue-router`, allowing developers to define layouts for individual pages using route blocks (e.g., `<route lang="yaml"> meta: { layout: 'my-layout' } </route>`). Layout components, typically stored in `src/layouts`, are automatically discovered and asynchronously imported, providing a structured approach to managing application layouts.
Common errors
-
Cannot find module 'virtual:generated-layouts' or its corresponding type declarations.
cause The TypeScript compiler or runtime cannot resolve the virtual module. This is often due to missing type definitions in `tsconfig.json` or incorrect plugin setup in `vite.config.js`.fixAdd `"vite-plugin-vue-layouts/client"` to the `compilerOptions.types` array in your `tsconfig.json`. Ensure the plugin is correctly instantiated in `vite.config.ts` and that your `main.ts` imports `setupLayouts` from `virtual:generated-layouts`. -
[vite] Internal server error: Failed to resolve import "virtual:generated-layouts" from "src/main.ts". Does the file exist?
cause The Vite development server failed to generate or resolve the virtual module. This typically indicates that `vite-plugin-vue-layouts` is not correctly configured or loaded in `vite.config.js`.fixVerify that `Layouts()` is included in your `plugins` array in `vite.config.js` (or `.ts`). Ensure there are no syntax errors in your Vite configuration file that might prevent the plugin from initializing. -
Hot Module Replacement (HMR) for new pages or layout components is not working as expected.
cause This can happen if the `pagesDir` or `layoutsDirs` options are not correctly configured, preventing the plugin from watching the relevant directories for changes.fixDouble-check your `pagesDir` and `layoutsDirs` options in the plugin configuration. If you moved your pages or layouts, update these paths. Remember that `pagesDir` changed default in v0.9.0; setting `pagesDir: null` might resolve issues if you need broader file watching.
Warnings
- breaking Version 0.9.0 introduced significant breaking changes by removing support for Vue 2, Vite 2, and Vite 3. The plugin now strictly requires Vite 4 or 5 and Vue 3.2.4 or newer.
- gotcha The default value for the `pagesDir` option changed in version 0.9.0 from `null` (watching all files) to `'src/pages'`. If you rely on the plugin watching page files outside of `src/pages` or in multiple directories, you must explicitly configure `pagesDir`.
- gotcha Layouts are configured via `meta.layout` in route blocks. If a page does not specify a layout, it will default to the layout component named 'default.vue' in your `layoutsDirs`.
Install
-
npm install vite-plugin-vue-layouts -
yarn add vite-plugin-vue-layouts -
pnpm add vite-plugin-vue-layouts
Imports
- Layouts
const Layouts = require('vite-plugin-vue-layouts')import Layouts from 'vite-plugin-vue-layouts'
- setupLayouts
import { setupLayouts } from 'vite-plugin-vue-layouts'import { setupLayouts } from 'virtual:generated-layouts' - Client-side Types
/// <reference types="vite-plugin-vue-layouts/client" />
Quickstart
import { defineConfig } from 'vite';
import Vue from '@vitejs/plugin-vue';
import Pages from 'vite-plugin-pages'; // Recommended companion plugin
import Layouts from 'vite-plugin-vue-layouts';
export default defineConfig({
plugins: [
Vue(),
Pages(), // Optional, but commonly used with this plugin
Layouts({
layoutsDirs: 'src/layouts',
defaultLayout: 'default'
})
]
});
// src/main.ts
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import { setupLayouts } from 'virtual:generated-layouts';
import generatedRoutes from '~pages'; // From vite-plugin-pages
import App from './App.vue';
// Transform generated routes with layouts
const routes = setupLayouts(generatedRoutes);
const router = createRouter({
history: createWebHistory(),
routes,
});
createApp(App).use(router).mount('#app');