
Research
/Security News
60 Malicious Ruby Gems Used in Targeted Credential Theft Campaign
A RubyGems malware campaign used 60 malicious packages posing as automation tools to steal credentials from social media and marketing tool users.
vite-plugin-vue-layouts-next
Advanced tools
Router-based layout plugin for Vite and Vue, supports the latest versions.
Router based layout for Vue 3 applications using Vite
A fork of vite-plugin-vue-layouts with some improvements and fixes, supports the latest versions of Vite and Vue.
This works best along with the vite-plugin-pages.
Layouts are stored in the /src/layouts
folder by default and are standard Vue components with a <router-view></router-view>
in the template.
Pages without a layout specified use default.vue
for their layout.
You can use route blocks to allow each page to determine its layout. The block below in a page will look for /src/layouts/users.vue
for its layout.
<route lang="yaml">
meta:
layout: users
</route>
Install Layouts:
# npm
npm install -D vite-plugin-vue-layouts-next
# yarn
yarn add -D vite-plugin-vue-layouts-next
# pnpm
pnpm add -D vite-plugin-vue-layouts-next
Add to your vite.config.ts
:
import Vue from '@vitejs/plugin-vue'
import Pages from 'vite-plugin-pages'
import Layouts from 'vite-plugin-vue-layouts-next'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [Vue(), Pages(), Layouts()],
})
In main.ts, you need to add a few lines to import the generated code and setup the layouts.
import { setupLayouts } from 'virtual:generated-layouts'
import { createRouter } from 'vue-router'
import generatedRoutes from '~pages'
const routes = setupLayouts(generatedRoutes)
const router = createRouter({
// ...
routes,
})
import { setupLayouts } from 'virtual:generated-layouts'
import { createRouter } from 'vue-router'
import { routes } from 'vue-router/auto-routes'
const router = createRouter({
// ...
routes: setupLayouts(routes),
})
If you want type definition of virtual:generated-layouts
, add vite-plugin-vue-layouts-next/client
to compilerOptions.types
of your tsconfig
:
{
"compilerOptions": {
"types": ["vite-plugin-vue-layouts-next/client"]
}
}
interface UserOptions {
layoutsDirs?: string | string[]
pagesDirs?: string | string[] | null
extensions?: string[]
exclude?: string[]
defaultLayout?: string
importMode?: (name: string) => 'sync' | 'async'
}
To use custom configuration, pass your options to Layouts when instantiating the plugin:
// vite.config.ts
import Layouts from 'vite-plugin-vue-layouts-next'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
Layouts({
layoutsDirs: 'src/mylayouts',
pagesDirs: 'src/pages',
defaultLayout: 'myDefault'
}),
],
})
Relative path to the layouts directory. Supports globs. All .vue files in this folder are imported async into the generated code.
Can also be an array of layout dirs
Can use **
to support scenarios like module1/layouts
and modules2/layouts
with a setting of src/**/layouts
Any files named __*__.vue
will be excluded, and you can specify any additional exclusions with the exclude
option
Default: 'src/layouts'
Defines the pages dir to avoid HMR reloading for all added or deleted files anywhere in the project.
Relative path to the pages directory. If you want it to watch for all files, like in v0.8.0 or earlier, set to null.
Can also be an array of layout dirs or use **
glob patterns
Default: 'src/pages'
Valid file extensions for page components.
Default: ['vue']
List of path globs to exclude when resolving pages.
Filename of default layout (".vue" is not needed).
Default: 'default'
Mode for importing layouts.
Default: ssg is 'sync'
,other is 'async'
setupLayouts
transforms the original router
by
children
property.Simply put, layouts are nested routes with the same path.
Before:
router: [ page1, page2, page3 ]
After setupLayouts()
:
router: [
layoutA: page1,
layoutB: page2,
layoutA: page3,
]
That means you have the full flexibility of the vue-router API at your disposal.
Layouts and Transitions work as expected and explained in the vue-router docs only as long as Component
changes on each route. So if you want a transition between pages with the same layout and a different layout, you have to mutate :key
on <component>
(for a detailed example, see the vue docs about transitions between elements).
App.vue
<template>
<router-view v-slot="{ Component, route }">
<transition name="slide">
<component :is="Component" :key="route" />
</transition>
</router-view>
</template>
Now Vue will always trigger a transition if you change the route.
If you want to send data down from the layout to the page, use props
<router-view foo="bar" />
If you want to set state in your page and do something with it in your layout, add additional properties to a route's meta
property. Doing so only works if you know the state at build-time.
You can use the <route>
block if you work with vite-plugin-pages.
In page.vue
:
<template><div>Content</div></template>
<route lang="yaml">
meta:
layout: default
bgColor: yellow
</route>
Now you can read bgColor
in layout.vue
:
<script setup lang="ts">
import { useRouter } from 'vue-router'
</script>
<template>
<div :style="`background: ${useRouter().currentRoute.value.meta.bgColor};`">
<router-view />
</div>
</template>
If you need to set bgColor
dynamically at run-time, you can use custom events.
Emit the event in page.vue
:
<script setup lang="ts">
import { defineEmit } from 'vue'
const emit = defineEmit(['setColor'])
if (2 + 2 === 4)
emit('setColor', 'green')
else
emit('setColor', 'red')
</script>
Listen for setColor
custom-event in layout.vue
:
<script setup lang="ts">
import { ref } from 'vue'
const bgColor = ref('yellow')
const setBg = (color) => {
bgColor.value = color
}
</script>
<template>
<main :style="`background: ${bgColor};`">
<router-view @set-color="setBg" />
</main>
</template>
The clientSideLayout uses a simpler virtual file + glob import scheme, This means that its hmr is faster and more accurate, but also more limited
// vite.config.ts
import { ClientSideLayout } from 'vite-plugin-vue-layouts-next'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
ClientSideLayout({
layoutsDir: 'src/mylayouts', // default to 'src/layouts'
defaultLayout: 'myDefault', // default to 'default', no need '.vue'
importMode: 'sync' // The default will automatically detect -> ssg is sync,other is async
}),
],
})
[1.0.0] - 2025-07-02
cjs
exportlayouts-generated
moduleFAQs
Router-based layout plugin for Vite and Vue, supports the latest versions.
The npm package vite-plugin-vue-layouts-next receives a total of 4,954 weekly downloads. As such, vite-plugin-vue-layouts-next popularity was classified as popular.
We found that vite-plugin-vue-layouts-next demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
A RubyGems malware campaign used 60 malicious packages posing as automation tools to steal credentials from social media and marketing tool users.
Security News
The CNA Scorecard ranks CVE issuers by data completeness, revealing major gaps in patch info and software identifiers across thousands of vulnerabilities.
Research
/Security News
Two npm packages masquerading as WhatsApp developer libraries include a kill switch that deletes all files if the phone number isn’t whitelisted.