{"id":26087847,"url":"https://github.com/loicduong/vite-plugin-vue-layouts-next","last_synced_at":"2025-11-26T20:01:15.235Z","repository":{"id":279337458,"uuid":"938479263","full_name":"loicduong/vite-plugin-vue-layouts-next","owner":"loicduong","description":"Vue layout plugin for Vite, supports the Vite 7 and Vue 3.","archived":false,"fork":false,"pushed_at":"2025-11-17T15:35:22.000Z","size":1992,"stargazers_count":50,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-17T16:20:43.903Z","etag":null,"topics":["typescript","vite-plugin","vite7","vue-router","vue3"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/vite-plugin-vue-layouts-next","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"JohnCampionJr/vite-plugin-vue-layouts","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loicduong.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-25T02:48:51.000Z","updated_at":"2025-11-17T15:35:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"1b216e48-cdc8-4c93-a5b3-99c6bbc06e12","html_url":"https://github.com/loicduong/vite-plugin-vue-layouts-next","commit_stats":null,"previous_names":["loicduong/vite-plugin-vue-layouts-next"],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/loicduong/vite-plugin-vue-layouts-next","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loicduong%2Fvite-plugin-vue-layouts-next","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loicduong%2Fvite-plugin-vue-layouts-next/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loicduong%2Fvite-plugin-vue-layouts-next/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loicduong%2Fvite-plugin-vue-layouts-next/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loicduong","download_url":"https://codeload.github.com/loicduong/vite-plugin-vue-layouts-next/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loicduong%2Fvite-plugin-vue-layouts-next/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286079811,"owners_count":27282121,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-26T02:00:06.075Z","response_time":193,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["typescript","vite-plugin","vite7","vue-router","vue3"],"created_at":"2025-03-09T07:57:53.805Z","updated_at":"2025-11-26T20:01:15.229Z","avatar_url":"https://github.com/loicduong.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vite-plugin-vue-layouts-next\n\n[![npm version][npm-badge]][npm]\n[![monthly downloads][monthly-downloads-badge]][monthly-downloads]\n[![Keep a Changelog v1.1.0 badge][changelog-badge]][changelog]\n[![standard-readme compliant][standard-readme-badge]][standard-readme]\n\nRouter based layout plugin for Vite 7 and Vue 3.\n\nA fork of [vite-plugin-vue-layouts](https://github.com/JohnCampionJr/vite-plugin-vue-layouts) with some improvements and fixes, supports Vite 7 and Vue 3.\n\nThis works best along with the [vite-plugin-pages](https://github.com/hannoeru/vite-plugin-pages).\n\nLayouts are stored in the `/src/layouts` folder by default and are standard Vue components with a `\u003crouter-view\u003e\u003c/router-view\u003e` in the template.\n\nPages without a layout specified use `default.vue` for their layout.\n\nYou 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.\n\n```html\n\u003croute lang=\"yaml\"\u003e\nmeta:\n  layout: users\n\u003c/route\u003e\n```\n\n## Table of Contents\n\n- [Install](#install)\n- [Usage](#usage)\n- [API](#api)\n- [How it works](#how-it-works)\n- [Common patterns](#common-patterns)\n- [ClientSideLayout](#clientsidelayout)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Install\n\n```bash\n# npm\nnpm install -D vite-plugin-vue-layouts-next\n\n# yarn\nyarn add -D vite-plugin-vue-layouts-next\n\n# pnpm\npnpm add -D vite-plugin-vue-layouts-next\n```\n\n## Usage\n\nAdd to your `vite.config.ts`:\n\n```js\nimport Vue from '@vitejs/plugin-vue'\nimport { defineConfig } from 'vite'\nimport Pages from 'vite-plugin-pages'\nimport Layouts from 'vite-plugin-vue-layouts-next'\n\nexport default defineConfig({\n  plugins: [Vue(), Pages(), Layouts()],\n})\n```\n\nIn main.ts, you need to add a few lines to import the generated code and setup the layouts.\n\n### vue-router\n\n```js\nimport { setupLayouts } from 'virtual:generated-layouts'\nimport { createRouter } from 'vue-router'\nimport generatedRoutes from '~pages'\n\nconst routes = setupLayouts(generatedRoutes)\n\nconst router = createRouter({\n  // ...\n  routes,\n})\n```\n\n### unplugin-vue-router\n\n```js\nimport { setupLayouts } from 'virtual:generated-layouts'\nimport { createRouter } from 'vue-router'\nimport { routes } from 'vue-router/auto-routes'\n\nconst router = createRouter({\n  // ...\n  routes: setupLayouts(routes),\n})\n```\n\n### Client Types\n\nIf you want type definition of `virtual:generated-layouts`, add `vite-plugin-vue-layouts-next/client` to `compilerOptions.types` of your `tsconfig`:\n\n```json\n{\n  \"compilerOptions\": {\n    \"types\": [\"vite-plugin-vue-layouts-next/client\"]\n  }\n}\n```\n\n## API\n\n```ts\ninterface UserOptions {\n  layoutsDirs?: string | string[]\n  pagesDirs?: string | string[] | null\n  extensions?: string[]\n  exclude?: string[]\n  defaultLayout?: string\n  importMode?: (name: string) =\u003e 'sync' | 'async'\n  inheritDefaultLayout?: boolean\n}\n```\n\n### Using configuration\n\nTo use custom configuration, pass your options to Layouts when instantiating the plugin:\n\n```js\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport Layouts from 'vite-plugin-vue-layouts-next'\n\nexport default defineConfig({\n  plugins: [\n    Layouts({\n      layoutsDirs: 'src/mylayouts',\n      pagesDirs: 'src/pages',\n      defaultLayout: 'myDefault'\n    }),\n  ],\n})\n```\n\n### layoutsDirs\n\nRelative path to the layouts directory. Supports globs.\nAll .vue files in this folder are imported async into the generated code.\n\nCan also be an array of layout dirs\n\nCan use `**` to support scenarios like `module1/layouts` and `modules2/layouts` with a setting of `src/**/layouts`\n\nAny files named `__*__.vue` will be excluded, and you can specify any additional exclusions with the `exclude` option\n\n**Default:** `'src/layouts'`\n\n### pagesDirs\n\nDefines the pages dir to avoid HMR reloading for all added or deleted files anywhere in the project.\n\nRelative path to the pages directory. If you want it to watch for all files, like in v0.8.0 or earlier, set to null.\n\nCan also be an array of layout dirs or use `**` glob patterns\n\n**Default:** `'src/pages'`\n\n### extensions\n\nValid file extensions for page components.\n\n**Default:** `['vue']`\n\n### exclude\n\nList of path globs to exclude when resolving pages.\n\n### defaultLayout\n\nFilename of default layout (\".vue\" is not needed).\n\n**Default:** `'default'`\n\n### importMode\n\nMode for importing layouts.\n\n**Default:** ssg is `'sync'`, other is `'async'`\n\n### inheritDefaultLayout\n\nWhether nested routes should inherit the default layout from parent routes. When `false`, if a child route has its own layout, the parent route won't use the default layout. This prevents double-wrapping layouts when child routes specify their own layout. This option only works with [unplugin-vue-router](https://github.com/posva/unplugin-vue-router). It has no effect when using [vite-plugin-pages](https://github.com/hannoeru/vite-plugin-pages) because `vite-plugin-pages` generates flat route structures without nested parent-child relationships, while `unplugin-vue-router` generates nested route structures with `children` arrays. This option can only be set globally in the plugin configuration.\n\n**Default:** `true`\n\n## How it works\n\n`setupLayouts` transforms the original `router` by\n\n1. Replacing every page with its specified layout\n2. Appending the original page in the `children` property.\n\nSimply put, layouts are [nested routes](https://next.router.vuejs.org/guide/essentials/nested-routes.html#nested-routes) with the same path.\n\nBefore:\n\n```text\nrouter: [ page1, page2, page3 ]\n```\n\nAfter `setupLayouts()`:\n\n```text\nrouter: [\n  layoutA: page1,\n  layoutB: page2,\n  layoutA: page3,\n]\n```\n\nThat means you have the full flexibility of the [vue-router API](https://next.router.vuejs.org/api/) at your disposal.\n\n## Common patterns\n\n### Transitions\n\nLayouts and Transitions work as expected and explained in the [vue-router docs](https://next.router.vuejs.org/guide/advanced/transitions.html) 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 `\u003ccomponent\u003e` (for a detailed example, see the vue docs about [transitions between elements](https://v3.vuejs.org/guide/transitions-enterleave.html#transitioning-between-elements)).\n\n`App.vue`\n\n```html\n\u003ctemplate\u003e\n  \u003crouter-view v-slot=\"{ Component, route }\"\u003e\n    \u003ctransition name=\"slide\"\u003e\n      \u003ccomponent :is=\"Component\" :key=\"route\" /\u003e\n    \u003c/transition\u003e\n  \u003c/router-view\u003e\n\u003c/template\u003e\n```\n\nNow Vue will always trigger a transition if you change the route.\n\n### Data from layout to page\n\nIf you want to send data *down* from the layout to the page, use props\n\n```html\n\u003crouter-view foo=\"bar\" /\u003e\n```\n\n### Set static data at the page\n\nIf 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.\n\nYou can use the `\u003croute\u003e` block if you work with [vite-plugin-pages](https://github.com/hannoeru/vite-plugin-pages).\n\nIn `page.vue`:\n\n```html\n\u003ctemplate\u003e\u003cdiv\u003eContent\u003c/div\u003e\u003c/template\u003e\n\u003croute lang=\"yaml\"\u003e\nmeta:\n  layout: default\n  bgColor: yellow\n\u003c/route\u003e\n```\n\nNow you can read `bgColor` in `layout.vue`:\n\n```html\n\u003cscript setup lang=\"ts\"\u003e\nimport { useRouter } from 'vue-router'\n\u003c/script\u003e\n\u003ctemplate\u003e\n  \u003cdiv :style=\"`background: ${useRouter().currentRoute.value.meta.bgColor};`\"\u003e\n    \u003crouter-view /\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n```\n\n### Data dynamically from page to layout\n\nIf you need to set `bgColor` dynamically at run-time, you can use [custom events](https://v3.vuejs.org/guide/component-custom-events.html#custom-events).\n\nEmit the event in `page.vue`:\n\n```html\n\u003cscript setup lang=\"ts\"\u003e\nimport { defineEmit } from 'vue'\nconst emit = defineEmit(['setColor'])\n\nif (2 + 2 === 4)\n  emit('setColor', 'green')\nelse\n  emit('setColor', 'red')\n\u003c/script\u003e\n```\n\nListen for `setColor` custom-event in `layout.vue`:\n\n```html\n\u003cscript setup lang=\"ts\"\u003e\nimport { ref } from 'vue'\n\nconst bgColor = ref('yellow')\nconst setBg = (color) =\u003e {\n  bgColor.value = color\n}\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cmain :style=\"`background: ${bgColor};`\"\u003e\n    \u003crouter-view @set-color=\"setBg\" /\u003e\n  \u003c/main\u003e\n\u003c/template\u003e\n```\n\n## ClientSideLayout\n\nThe clientSideLayout uses a simpler [virtual file](https://vitejs.dev/guide/api-plugin.html#importing-a-virtual-file) + [glob import](https://vitejs.dev/guide/features.html#glob-import) scheme, This means that its hmr is faster and more accurate, but also more limited\n\n### Usage\n\n```js\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport { ClientSideLayout } from 'vite-plugin-vue-layouts-next'\n\nexport default defineConfig({\n  plugins: [\n    ClientSideLayout({\n      layoutsDir: 'src/mylayouts', // default to 'src/layouts'\n      defaultLayout: 'myDefault', // default to 'default', no need '.vue'\n      importMode: 'sync' // The default will automatically detect -\u003e ssg is sync，other is async\n    }),\n  ],\n})\n```\n\n## Contributing\n\nPRs accepted.\n\nOpen an issue or submit PRs for any improvements.\n\n## License\n\nMIT © loicduong\n\n[npm]: https://www.npmjs.com/package/vite-plugin-vue-layouts-next\n[npm-badge]: https://img.shields.io/npm/v/vite-plugin-vue-layouts-next\n[monthly-downloads]: https://npmjs.com/package/vite-plugin-vue-layouts-next?activeTab=versions\n[monthly-downloads-badge]: https://img.shields.io/npm/dm/vite-plugin-vue-layouts-next\n[changelog]: ./CHANGELOG.md\n[changelog-badge]: https://img.shields.io/badge/changelog-Keep%20a%20Changelog%20v1.1.0-%23E05735\n[standard-readme]: https://github.com/RichardLitt/standard-readme\n[standard-readme-badge]: https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floicduong%2Fvite-plugin-vue-layouts-next","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floicduong%2Fvite-plugin-vue-layouts-next","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floicduong%2Fvite-plugin-vue-layouts-next/lists"}