{"_id":"@arijs/vite-ssg","_rev":"1-8033e8564b2191c107ce6f344664fcc3","name":"@arijs/vite-ssg","dist-tags":{"latest":"0.15.6-ari.1"},"versions":{"0.15.6-ari.1":{"name":"@arijs/vite-ssg","publishConfig":{"access":"public"},"description":"Server-side generation for Vite","version":"0.15.6-ari.1","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{"./":"./",".":{"require":"./dist/index.js","import":"./dist/index.mjs"},"./single-page":{"require":"./dist/client/single-page.js","import":"./dist/client/single-page.mjs"}},"license":"MIT","funding":"https://github.com/sponsors/rhengles","author":{"name":"Rafael Hengles","email":"rhengles@gmail.com"},"engines":{"node":">=14.0.0"},"repository":{"type":"git","url":"git+https://github.com/arijs/vite-ssg.git"},"homepage":"https://github.com/arijs/vite-ssg","bugs":{"url":"https://github.com/arijs/vite-ssg/issues"},"bin":{"vite-ssg":"bin/vite-ssg.js"},"keywords":["vite","vite-plugin","ssg","ssr"],"dependencies":{"chalk":"^4.1.2","fs-extra":"^10.0.0","html-minifier":"^4.0.0","jsdom":"^17.0.0","prettier":"^2.4.1","yargs":"^17.2.1"},"peerDependencies":{"@vue/compiler-sfc":"^3.0.4","@vue/server-renderer":"^3.0.4","@vueuse/head":"^0.5.1","critters":"^0.0.10","vite":"^2.0.0","vue":"^3.0.4","vue-router":"^4.0.1"},"peerDependenciesMeta":{"critters":{"optional":true}},"devDependencies":{"@antfu/eslint-config":"^0.10.0","@types/fs-extra":"^9.0.13","@types/jsdom":"^16.2.13","@types/yargs":"^17.0.4","@typescript-eslint/eslint-plugin":"^5.1.0","@vue/compiler-sfc":"^3.2.20","@vue/server-renderer":"^3.2.20","@vueuse/head":"^0.6.0","bumpp":"^7.1.1","critters":"^0.0.12","eslint":"^8.0.1","esno":"^0.10.1","rollup":"^2.58.0","standard-version":"^9.3.2","tsup":"^5.4.2","typescript":"^4.4.4","vite":"^2.6.10","vite-plugin-pwa":"^0.11.3","vue":"^3.2.20","vue-router":"^4.0.12"},"scripts":{"dev":"npm run build:module -- --watch src","copy-readme-files":"esno scripts/copy-readme-files.ts","copy-single-page-dts":"esno scripts/copy-single-page-dts.ts","example:dev":"npm run copy-readme-files && npm -C examples/multiple-pages run dev","example:build":"npm run copy-readme-files && npm -C examples/multiple-pages run build","example:serve":"npm run copy-readme-files && npm -C examples/multiple-pages run serve","example:store:dev":"npm run copy-readme-files && npm -C examples/multiple-pages-with-store run dev","example:store:build":"npm run copy-readme-files && npm -C examples/multiple-pages-with-store run build","example:store:serve":"npm run copy-readme-files && npm -C examples/multiple-pages-with-store run serve","example:single:dev":"npm -C examples/single-page run dev","example:single:build":"npm -C examples/single-page run build","example:single:serve":"npm -C examples/single-page run serve","build:module":"tsup src/index.ts src/client/single-page.ts src/node/cli.ts --dts --format cjs,esm --splitting","build":"rimraf dist && npm run build:module && npm run copy-single-page-dts","release":"npx bumpp --push --tag --commit"},"_resolved":"","_integrity":"","_from":"file:arijs-vite-ssg-0.15.6-ari.1.tgz","_id":"@arijs/vite-ssg@0.15.6-ari.1","_nodeVersion":"14.17.0","_npmVersion":"6.14.13","dist":{"integrity":"sha512-Fo852dSbVDMzwovqA6ktTBHBKrK8WoenWqDb3zWjVNl3GiTK1xbJCBL5PcixDB8/Rlbj7OI1w0uu7oqjWoI0dQ==","shasum":"f3ee6eb4b7eb2e06d381dedeaa9715508e60bab0","tarball":"https://registry.npmjs.org/@arijs/vite-ssg/-/vite-ssg-0.15.6-ari.1.tgz","fileCount":19,"unpackedSize":52616,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhlDy9CRA9TVsSAnZWagAAn+wP/iREwnyP5l4oA7Myv7il\nuwZFOcqVsQACLXpjJ72O7iw3PgOvQWo5FphWRBLnTdBWFEYozxbnQmw6CAok\nmocP+MAL7VmBWtEIHIUIO+OQamkLVpcAhvWTzXZIYYaK1jLh6Ea1KSPqN39E\nAoOYzDi3OAxLQ3w6mDqyti/SnGZomjAjGBLWaDVMiaaPv9fpuNxQKpBgUWJX\n2H2Vq/cDmrTIwNGvTPa8IzU1URHvRvHd56MBDxYbr+TZSCTOvXpKKrwxddZQ\nvMf9hhA+ywqVGaXC8BwPOo9Fkj3K43uDNIO9IYZbH0mO24PFbaaPuRui61uN\nVKfgSSXDKw4ZKHSHrtI83uZ3PRwtqwllt3QV9YjCYoFmpT1tgL9hAwzX3h8y\np3DWwlVtN3JhNb9BPIVMC8O1ZOywDk2OdqfWYASpGUFeF+SSc1Xdoq6Ii6/7\nuxQK0Yfhb4HaiAVMDkUkpLlFiU+Ji/qiiZzPklhd81Hjz7Of0b1QKpx1zcyD\nc/C7XwuHuOr0e+Tm4HaWsPJLNxwIObgDkXXny83L3sPQMyuzoFVB3Sb3/K2f\nchGCU2xdOu3+0pmR1ZUlaMJxDEtkBmYkWYnkbIZmZAGMkqNkyeJQKGWDakA4\n0VBmNHRMyJhCYKseNwpLXrZLkA2hF37zlKGm1iXJSbYQpgv9KcdWUjTxXsSl\n8K1I\r\n=C1OQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIESTLPy7/TztqYUAvcCAbYc8jz32n7QTPE34Uv2kY/20AiEA6/nKslpXZhOBuEVwYhiriZCdrutn+2H7qQNp9ZPDEv8="}]},"_npmUser":{"name":"arijs","email":"arijs@arijs.org"},"directories":{},"maintainers":[{"name":"arijs","email":"arijs@arijs.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/vite-ssg_0.15.6-ari.1_1637104828922_0.3280313800339403"},"_hasShrinkwrap":false}},"time":{"created":"2021-11-16T23:20:28.865Z","0.15.6-ari.1":"2021-11-16T23:20:29.116Z","modified":"2022-04-04T15:25:53.737Z"},"maintainers":[{"name":"arijs","email":"arijs@arijs.org"}],"description":"Server-side generation for Vite","homepage":"https://github.com/arijs/vite-ssg","keywords":["vite","vite-plugin","ssg","ssr"],"repository":{"type":"git","url":"git+https://github.com/arijs/vite-ssg.git"},"author":{"name":"Rafael Hengles","email":"rhengles@gmail.com"},"bugs":{"url":"https://github.com/arijs/vite-ssg/issues"},"license":"MIT","readme":"# Vite SSG\n\nServer-side generation for Vue 3 on Vite.\n\n[![NPM version](https://img.shields.io/npm/v/vite-ssg?color=a1b858)](https://www.npmjs.com/package/vite-ssg)\n\n> ℹ️ **Vite 2 is supported from `v0.2.x`, Vite 1's support is discontinued.**\n\n## Install\n\n> **This library requires Node.js version >= 14**\n\n<pre>\n<b>npm i -D vite-ssg</b> <em>@vue/server-renderer @vue/compiler-sfc vue-router@next @vueuse/head</em>\n</pre>\n\n```diff\n// package.json\n{\n  \"scripts\": {\n    \"dev\": \"vite\",\n-   \"build\": \"vite build\"\n+   \"build\": \"vite-ssg build\"\n  }\n}\n```\n\n```ts\n// src/main.ts\nimport { ViteSSG } from 'vite-ssg'\nimport App from './App.vue'\n\n// `export const createApp` is required\nexport const createApp = ViteSSG(\n  // the root component\n  App,\n  // vue-router options\n  { routes },\n  // function to have custom setups\n  ({ app, router, routes, isClient, initialState }) => {\n    // install plugins etc.\n  }\n)\n```\n\n### Single Page SSG\n\nTo have SSG for the index page only (without `vue-router`), import from `vite-ssg/single-page` instead.\n\n```ts\nimport { ViteSSG } from 'vite-ssg/single-page'\n\nexport const createApp = ViteSSG(App)\n```\n\n### `<ClientOnly/>`\n\nComponent `ClientOnly` is registered globally along with the app creation.\n\n```html\n<client-only>\n  <your-client-side-components />\n</client-only>\n```\n\n## Document head\n\nFrom `v0.4.0`, we ship [`@vueuse/head`](https://github.com/vueuse/head) to manage the document head out-of-box. You can directly use it in your pages/components, for example:\n\n```html\n<template>\n  <button @click=\"count++\">Click</button>\n</template>\n\n<script setup>\nimport { useHead } from '@vueuse/head'\n\nuseHead({\n  title: 'Website Title',\n  meta: [\n    {\n      name: `description`,\n      content: `Website description`,\n    },\n  ],\n})\n</script>\n```\n\nThat's all, no configuration is needed. Vite SSG will handle the server-side rendering and merging automatically.\n\nRefer to [`@vueuse/head`'s docs](https://github.com/vueuse/head) for more usage about `useHead`.\n\n## Critical CSS\n\nVite SSG has built-in support for generating [Critical CSS](https://web.dev/extract-critical-css/) inlined in the HTML via the [`critters`](https://github.com/GoogleChromeLabs/critters) package. Install it via:\n\n```bash\nnpm i -D critters\n```\n\nCritical CSS generation will be enabled automatically for you.\n\n## Initial State\n\nThe initial state comprises data that is serialized to your server-side generated HTML that is hydrated in\nthe browser when accessed. This data can be data fetched from a CDN, an API, etc, and is typically needed\nas soon as the application starts or is accessed for the first time.\n\nThe main advantage of setting the application's initial state is that the statically generated pages do not\nneed to fetch the data again as the data is fetched during build time and serialized into the page's HTML.\n\nThe initial state is a plain JavaScript object that can be set during SSR, i.e., when statically generating\nthe pages, like this:\n\n```ts\n// src/main.ts\n\n// ...\n\nexport const createApp = ViteSSG(\n  App,\n  { routes },\n  ({ app, router, routes, isClient, initialState }) => {\n    // ...\n\n    if (import.meta.env.SSR) {\n      // Set initial state during server side\n      initialState.data = { cats: 2, dogs: 3 }\n    } else {\n      // Restore or read the initial state on the client side in the browser\n      console.log(initialState.data) // => { cats: 2, dogs: 3 }\n    }\n\n    // ...\n  }\n)\n```\n\nTypically, you will use this with an application store, such as\n[Vuex](https://vuex.vuejs.org/) or [Pinia](https://pinia.esm.dev/).\nFor examples, see below:\n\n<details><summary>When using Pinia</summary>\n<p>\nFollowing [Pinia's guide](https://pinia.esm.dev/ssr), you will to adapt your `main.{ts,js}` file to look\nlike this:\n\n```ts\n// main.ts\nimport { ViteSSG } from 'vite-ssg'\nimport { createPinia } from 'pinia'\nimport routes from 'virtual:generated-pages'\n// use any store you configured that you need data from on start-up\nimport { useRootStore } from './store/root'\nimport App from './App.vue'\n\nexport const createApp = ViteSSG(\n  App,\n  { routes },\n  ({ app, router, initialState }) => {\n    const pinia = createPinia()\n    app.use(pinia)\n\n    if (import.meta.env.SSR) {\n      initialState.pinia = pinia.state.value\n    } else {\n      pinia.state.value = initialState.pinia || {}\n    }\n\n    router.beforeEach((to, from, next) => {\n      const store = useRootStore(pinia)\n      if (!store.ready)\n        // perform the (user-implemented) store action to fill the store's state\n        store.initialize()\n      next()\n    })\n  },\n)\n```\n</p></details>\n\n<details><summary>When using Vuex</summary>\n<p>\n\n```ts\n// main.ts\nimport { ViteSSG } from 'vite-ssg'\nimport routes from 'virtual:generated-pages'\nimport { createStore } from 'vuex'\nimport App from './App.vue'\n\n// Normally, you should definitely put this in a separate file\n// in order to be able to use it everywhere\nconst store = createStore({\n  // ...\n})\n\nexport const createApp = ViteSSG(\n  App,\n  { routes },\n  ({ app, router, initialState }) => {\n    app.use(store)\n\n    if (import.meta.env.SSR) {\n      initialState.store = store.state\n    } else {\n      store.replaceState(initialState.store)\n    }\n\n    router.beforeEach((to, from, next) => {\n      // perform the (user-implemented) store action to fill the store's state\n      if (!store.getters.ready)\n        store.dispatch('initialize')\n\n      next()\n    })\n  },\n)\n```\n</p></details>\n\nFor the example of how to use a store with an initial state in a single page app,\nsee [the single page example](./examples/single-page/src/main.ts).\n\n### State Serialization\n\nPer default, the state is deserialized and serialized by using `JSON.stringify` and `JSON.parse`.\nIf this approach works for you, you should definitely stick to it as it yields far better\nperformance.\n\nYou may use the option `transformState` in the `ViteSSGClientOptions` as displayed below.\nA valid approach besides `JSON.stringify` and `JSON.parse` is\n[`@nuxt/devalue`](https://github.com/nuxt-contrib/devalue) (which is used by Nuxt.js):\n\n```ts\nimport devalue from '@nuxt/devalue'\nimport { ViteSSG } from 'vite-ssg'\n// ...\nimport App from './App.vue'\n\nexport const createApp = ViteSSG(\n  App,\n  { routes },\n  ({ app, router, initialState }) => {\n    // ...\n  },\n  {\n    transformState(state) {\n      return import.meta.env.SSR ? devalue(state) : state\n    },\n  },\n)\n```\n\n**A minor remark when using `@nuxt/devalue`:** In case, you are getting an error because of a `require`\nwithin the package `@nuxt/devalue`, you have to add the following piece of config to your Vite config:\n\n```ts\n// vite.config.ts\n//...\n\nexport default defineConfig({\n  resolve: {\n    alias: {\n      '@nuxt/devalue': '@nuxt/devalue/dist/devalue.js',\n    },\n  },\n  // ...\n})\n```\n\n## Configuration\n\nYou can pass options to Vite SSG in the `ssgOptions` field of your `vite.config.js`\n\n```js\n// vite.config.js\n\nexport default {\n  plugins: [ /*...*/ ],\n  ssgOptions: {\n    script: 'async'\n  }\n}\n```\n\nSee [src/types.ts](./src/types.ts). for more options available.\n\n### Custom Routes to Render\n\nYou can use the `includedRoutes` hook to exclude/include route paths to render, or even provide some complete custom ones.\n\n```js\n// vite.config.js\n\nexport default {\n  plugins: [ /*...*/ ],\n  ssgOptions: {\n    includedRoutes(routes) {\n      // exclude all the route paths that contains 'foo'\n      return routes.filter(i => !i.includes('foo'))\n    }\n  }\n}\n```\n\n## Comparsion\n\n### Use [Vitepress](https://github.com/vuejs/vitepress) when you want:\n\n- Zero config, out-of-box\n- Single-purpose documentation site\n- Lightweight ([No double payload](https://twitter.com/youyuxi/status/1274834280091389955))\n\n### Use Vite SSG when you want\n\n- More controls on the build process and tooling\n- The flexible plugin systems\n- Multi-purpose application with some SSG to improve SEO and loading speed\n\nCons:\n\n- Double payload\n\n## Example\n\nSee [Vitesse](https://github.com/antfu/vitesse)\n\n## Thanks to the prior work\n\n- [vitepress](https://github.com/vuejs/vitepress/tree/master/src/node/build)\n- [vue3-vite-ssr-example](https://github.com/tbgse/vue3-vite-ssr-example)\n- [vite-ssr](https://github.com/frandiox/vite-ssr)\n\n## License\n\nMIT License © 2020 [Anthony Fu](https://github.com/antfu)\n","readmeFilename":"README.md"}