### Run Multi-Page Examples with Store Source: https://github.com/antfu-collective/vite-ssg/blob/main/examples/README.md Commands to develop, build, and serve the multi-page examples that include store functionality. ```bash pnpm example:store:dev pnpm example:store:build pnpm example:store:serve ``` -------------------------------- ### Run Multi-Page Examples Source: https://github.com/antfu-collective/vite-ssg/blob/main/examples/README.md Commands to develop, build, and serve the multi-page examples. ```bash pnpm example:dev pnpm example:build pnpm example:serve ``` -------------------------------- ### Run Single-Page Example Source: https://github.com/antfu-collective/vite-ssg/blob/main/examples/README.md Commands to develop, build, and serve the single-page example. ```bash pnpm example:single:dev pnpm example:single:build pnpm example:single:serve ``` -------------------------------- ### Install vite-ssg Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Install vite-ssg and its peer dependencies using npm. Vue-router and @unhead/vue are recommended for routing and head management. ```bash npm i -D vite-ssg vue-router @unhead/vue ``` -------------------------------- ### Clone and Build Vite-SSG Project Source: https://github.com/antfu-collective/vite-ssg/blob/main/examples/README.md Clone the repository, install dependencies, and build the entire project. ```bash git clone git@github.com:antfu/vite-ssg.git cd vite-ssg pnpm install pnpm build ``` -------------------------------- ### Install beasties for Critical CSS Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Install the 'beasties' package as a dev dependency to enable automatic critical CSS generation. ```bash npm i -D beasties ``` -------------------------------- ### Multi-page App Entry Point with ViteSSG Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Use this for multi-page applications with vue-router. It replaces the standard `createApp` export and handles both SSR and client-side hydration. The setup callback allows for custom logic like state management. ```typescript // src/main.ts import { ViteSSG } from 'vite-ssg' import { createPinia } from 'pinia' import routes from '~pages' // generated by vite-plugin-pages or unplugin-vue-router import App from './App.vue' export const createApp = ViteSSG( // Root Vue component App, // vue-router options (history is injected automatically) { routes, base: import.meta.env.BASE_URL }, // Setup callback — runs on both SSR and client ({ app, router, initialState, onSSRAppRendered }) => { const pinia = createPinia() app.use(pinia) if (import.meta.env.SSR) { // Capture Pinia state after async rendering completes onSSRAppRendered(() => { initialState.pinia = pinia.state.value }) } else { // Rehydrate from the serialized state injected into the HTML pinia.state.value = initialState.pinia ?? {} } router.beforeEach((to, _from, next) => { // Example: lazy-initialize a store before each navigation const store = useRootStore(pinia) if (!store.ready) store.initialize() next() }) }, // Client-side options { rootContainer: '#app', // Custom state deserializer (e.g. @nuxt/devalue) transformState(state) { return import.meta.env.SSR ? devalue(state) : state }, }, ) ``` -------------------------------- ### Single-page App Entry Point with ViteSSG Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Use this for single-page applications without vue-router. It simplifies the setup by omitting router options. The context object provides `app`, `head`, and `initialState`. ```typescript // src/main.ts import { ViteSSG } from 'vite-ssg/single-page' import { createPinia } from 'pinia' import App from './App.vue' import { useRootStore } from './store/root' export const createApp = ViteSSG( App, ({ app, initialState }) => { const pinia = createPinia() app.use(pinia) if (import.meta.env.SSR) { initialState.pinia = pinia.state.value } else { pinia.state.value = initialState.pinia ?? {} } // Initialize store immediately (no router guards needed) useRootStore(pinia).initialize() }, ) ``` -------------------------------- ### Post-Build Callback for Sitemap Generation Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Execute a function after all routes have been rendered and build artifacts cleaned up. This example generates a sitemap.xml file. ```typescript // vite.config.ts import { writeFile } from 'node:fs/promises' export default defineConfig({ ssgOptions: { async onFinished() { // Generate a simple sitemap after all pages are written const routes = ['/','/ about', '/blog', '/contact'] const sitemap = routes .map(r => `https://example.com${r}`) .join('\n') await writeFile( 'dist/sitemap.xml', ` ${sitemap} `, ) console.log('Sitemap written to dist/sitemap.xml') }, }, }) ``` -------------------------------- ### ViteSSG() — Multi-page app entry point Source: https://context7.com/antfu-collective/vite-ssg/llms.txt This function replaces the standard `createApp` export for applications using `vue-router`. It handles both SSR and client-side hydration, accepting the root component, router options, a setup callback, and client-side options. ```APIDOC ## ViteSSG() — Multi-page app entry point Replaces the standard `createApp` export in `src/main.ts` for applications using `vue-router`. Accepts the root component, router options, an optional setup callback receiving the full `ViteSSGContext`, and optional client-side options. The returned `createApp` factory is called by the build process for every route and by the browser for hydration. ```ts // src/main.ts import { ViteSSG } from 'vite-ssg' import { createPinia } from 'pinia' import routes from '~pages' // generated by vite-plugin-pages or unplugin-vue-router import App from './App.vue' export const createApp = ViteSSG( // Root Vue component App, // vue-router options (history is injected automatically) { routes, base: import.meta.env.BASE_URL }, // Setup callback — runs on both SSR and client ({ app, router, initialState, onSSRAppRendered }) => { const pinia = createPinia() app.use(pinia) if (import.meta.env.SSR) { // Capture Pinia state after async rendering completes onSSRAppRendered(() => { initialState.pinia = pinia.state.value }) } else { // Rehydrate from the serialized state injected into the HTML pinia.state.value = initialState.pinia ?? {} } router.beforeEach((to, _from, next) => { // Example: lazy-initialize a store before each navigation const store = useRootStore(pinia) if (!store.ready) store.initialize() next() }) }, // Client-side options { rootContainer: '#app', // Custom state deserializer (e.g. @nuxt/devalue) transformState(state) { return import.meta.env.SSR ? devalue(state) : state }, }, ) ``` ``` -------------------------------- ### Create Vue App with ViteSSG Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Use ViteSSG to create your Vue application. This setup is required for server-side rendering and static site generation. Ensure your main entry file exports createApp. ```typescript import { ViteSSG } from 'vite-ssg' import App from './App.vue' // `export const createApp` is required instead of the original `createApp(App).mount('#app')` export const createApp = ViteSSG( // the root component App, // vue-router options { routes }, // function to have custom setups ({ app, router, routes, isClient, initialState }) => { // install plugins etc. }, ) ``` -------------------------------- ### Single Page Application SSG Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md For single-page SSG without vue-router, import 'vite-ssg/single-page'. Ensure you have @unhead/vue installed. ```typescript import { ViteSSG } from 'vite-ssg/single-page' import App from './App.vue' // `export const createApp` is required instead of the original `createApp(App).mount('#app')` export const createApp = ViteSSG(App) ``` -------------------------------- ### Customizing State Serialization with @nuxt/devalue Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Use the `transformState` option to customize how state is serialized and deserialized, for example, with `@nuxt/devalue`. ```typescript import devalue from '@nuxt/devalue' import { ViteSSG } from 'vite-ssg' // ... import App from './App.vue' export const createApp = ViteSSG( App, { routes }, ({ app, router, initialState }) => { // ... }, { transformState(state) { return import.meta.env.SSR ? devalue(state) : state }, }, ) ``` -------------------------------- ### Build Project with `vite-ssg build` CLI Source: https://context7.com/antfu-collective/vite-ssg/llms.txt The `vite-ssg build` command replaces `vite build` and accepts flags that map directly to `ViteSSGOptions`. This allows for configuration of script loading, mocking, build modes, and alternative Vite config files directly from the command line. ```json // package.json { "scripts": { "dev": "vite", "build": "vite-ssg build", // With options "build:prod": "vite-ssg build --script async --mode production", "build:nested": "vite-ssg build --script defer", // Use an alternative Vite config file "build:staging": "vite-ssg build -c vite.staging.config.ts --base /staging/" } } ``` ```bash # Available CLI flags vite-ssg build [options] --script Script loading: sync | async | defer | "async defer" --mock Mock browser globals (window, document) during SSR build --mode Vite mode (default: production) -c, --config Path to an alternative vite.config file -b, --base Public base path for all assets and routes -h, --help Show help ``` -------------------------------- ### Integrating Pinia with Vite SSG Initial State Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Adapt your main file to use Pinia with Vite SSG. Initial state is serialized and restored via `initialState.pinia`. ```typescript import { createPinia } from 'pinia' import routes from 'virtual:generated-pages' // main.ts import { ViteSSG } from 'vite-ssg' import App from './App.vue' // use any store you configured that you need data from on start-up import { useRootStore } from './store/root' export const createApp = ViteSSG( App, { routes }, ({ app, router, initialState }) => { const pinia = createPinia() app.use(pinia) if (import.meta.env.SSR) initialState.pinia = pinia.state.value else pinia.state.value = initialState.pinia || {} router.beforeEach((to, from, next) => { const store = useRootStore(pinia) if (!store.ready) // perform the (user-implemented) store action to fill the store's state store.initialize() next() }) }, ) ``` -------------------------------- ### Integrating Vuex with Vite SSG Initial State Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Adapt your main file to use Vuex with Vite SSG. Initial state is serialized and restored via `initialState.store`. ```typescript import routes from 'virtual:generated-pages' // main.ts import { ViteSSG } from 'vite-ssg' import { createStore } from 'vuex' import App from './App.vue' // Normally, you should definitely put this in a separate file // in order to be able to use it everywhere const store = createStore({ // ... }) export const createApp = ViteSSG( App, { routes }, ({ app, router, initialState }) => { app.use(store) if (import.meta.env.SSR) initialState.store = store.state else store.replaceState(initialState.store) router.beforeEach((to, from, next) => { // perform the (user-implemented) store action to fill the store's state if (!store.getters.ready) store.dispatch('initialize') next() }) }, ) ``` -------------------------------- ### Configure build script in package.json Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Update the 'build' script in your package.json to use 'vite-ssg build' instead of 'vite build'. You can also specify a custom Vite config file. ```json { "scripts": { "dev": "vite", "build": "vite build" "build": "vite-ssg build" // OR if you want to use another vite config file "build": "vite-ssg build -c another-vite.config.ts" } } ``` -------------------------------- ### Configure Vite SSG Options Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Set global SSG behavior like script loading strategy, output directory style, HTML formatting, concurrency, and mock browser globals. ```typescript // vite.config.ts import { defineConfig } from 'vite' import Vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [Vue()], ssgOptions: { // Script tag loading strategy for generated HTML script: 'async', // 'sync' | 'async' | 'defer' | 'async defer' // Output filename style dirStyle: 'nested', // 'flat' (default): /foo.html | 'nested': /foo/index.html // Prettify or minify the generated HTML files formatting: 'prettify', // 'none' | 'minify' | 'prettify' // Number of routes rendered in parallel concurrency: 20, // Mock browser globals for libraries that need window/document at build time mock: false, // Disable critical CSS inlining (beasties) beastiesOptions: false, // Custom beasties options when critical CSS is enabled // beastiesOptions: { preload: 'media' }, // Custom entry file (defaults to src/main.ts detected from index.html) entry: 'src/main.ts', // Root container element id (default: 'app') rootContainerId: 'app', }, }) ``` -------------------------------- ### Configure beasties options in vite.config.ts Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Customize critical CSS generation by passing options to `ssgOptions.beastiesOptions` in your vite.config.ts file. Refer to the beasties documentation for available options. ```typescript // vite.config.ts export default defineConfig({ ssgOptions: { beastiesOptions: { // E.g., change the preload strategy preload: 'media', // Other options: https://github.com/danielroe/beasties#usage }, }, }) ``` -------------------------------- ### Serialize SSR State with `initialState` Source: https://context7.com/antfu-collective/vite-ssg/llms.txt The `initialState` option allows you to pass a plain object that is serialized into `window.__INITIAL_STATE__` in the HTML and deserialized on the client. This can eliminate redundant API calls on the first load by embedding fetched data directly into the initial HTML. ```typescript // src/main.ts — manual initialState usage (without a store) import { ViteSSG } from 'vite-ssg' import App from './App.vue' export const createApp = ViteSSG( App, { routes }, async ({ app, initialState }) => { if (import.meta.env.SSR) { // Fetch data at build time and embed it in the HTML const res = await fetch('https://api.example.com/config') initialState.config = await res.json() // → serialized as window.__INITIAL_STATE__ = '{"config":{...}}' } else { // Read from the hydrated state — no network request needed const config = initialState.config app.provide('appConfig', config) } }, ) ``` -------------------------------- ### Document Head Management with useHead Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Manage document head elements like titles and meta tags using the `useHead` composable from @unhead/vue. This is automatically handled by Vite SSG. ```html ``` -------------------------------- ### ViteSSG() — Single-page app entry point Source: https://context7.com/antfu-collective/vite-ssg/llms.txt This version of `ViteSSG` is imported from `vite-ssg/single-page` for applications that render only an index page without `vue-router`. The context object provides `app`, `head`, and `initialState` but omits router-related properties. ```APIDOC ## ViteSSG() — Single-page app entry point Imported from `vite-ssg/single-page` for applications that render only an index page without `vue-router`. The signature omits router options; the context object provides `app`, `head`, and `initialState` but no `router` or `routes`. ```ts // src/main.ts import { ViteSSG } from 'vite-ssg/single-page' import { createPinia } from 'pinia' import App from './App.vue' import { useRootStore } from './store/root' export const createApp = ViteSSG( App, ({ app, initialState }) => { const pinia = createPinia() app.use(pinia) if (import.meta.env.SSR) { initialState.pinia = pinia.state.value } else { pinia.state.value = initialState.pinia ?? {} } // Initialize store immediately (no router guards needed) useRootStore(pinia).initialize() }, ) ``` ``` -------------------------------- ### Configure beasties in vite.config.ts Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Optionally configure `beasties` within `vite.config.ts` to control critical CSS inlining behavior. Options include `preload`, `inlineFonts`, and `pruneSource`. Set `beastiesOptions` to `false` to disable critical CSS entirely. ```typescript export default defineConfig({ ssgOptions: { beastiesOptions: { // Preload remaining CSS non-blocking after the critical CSS is inlined preload: 'media', // 'body' | 'media' | 'swap' | 'js' | 'js-lazy' // Inline all fonts referenced in critical CSS inlineFonts: true, // Prune source CSS map references pruneSource: false, }, // Set to false to disable critical CSS entirely // beastiesOptions: false, }, }) ``` -------------------------------- ### Setting and Hydrating Initial State in Vite SSG Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Set initial state during SSR and access it on the client. This avoids refetching data on the client-side. ```typescript import { createApp } from 'vue' import App from './App.vue' import router from './router' // src/main.ts import { ViteSSG } from 'vite-ssg' export const createApp = ViteSSG( App, { routes }, ({ app, router, routes, isClient, initialState }) => { // ... if (import.meta.env.SSR) { // Set initial state during server side initialState.data = { cats: 2, dogs: 3 } } else { // Restore or read the initial state on the client side in the browser console.log(initialState.data) // => { cats: 2, dogs: 3 } } // ... }, ) ``` -------------------------------- ### Configure Vite SSG Script Option Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Configure the `script` option in `vite.config.js` to control how scripts are handled during the build. ```javascript // vite.config.js export default { plugins: [], ssgOptions: { script: 'async', }, } ``` -------------------------------- ### Dynamically Select Routes with Vite Env Access Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Fetch dynamic routes from an API and include them in the build. This method requires exporting `includedRoutes` from `src/main.ts` to access Vite's environment variables. ```typescript // src/main.ts — dynamic routes with Vite env access import { ViteSSG } from 'vite-ssg' import App from './App.vue' export const createApp = ViteSSG(App, { routes }) // Exported alongside createApp — vite-ssg picks it up automatically export async function includedRoutes(paths: string[], routes: RouteRecordRaw[]) { const api = new BlogApiClient(import.meta.env.VITE_API_KEY) const slugs = await api.fetchSlugs() return routes.flatMap((route) => { if (route.name === 'BlogPost') return slugs.map(slug => `/blog/${slug}`) return route.path }) } ``` -------------------------------- ### Document Head Management with @unhead/vue Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Use `useHead()` inside any component or page for automatic server-side injection and client-side merging of document head elements. Ensure `@unhead/vue` is bundled and initialized. ```vue ``` -------------------------------- ### Vite Configuration for @nuxt/devalue Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Add a resolve alias to your Vite config if you encounter `require` errors with `@nuxt/devalue`. ```typescript // vite.config.ts // ... export default defineConfig({ resolve: { alias: { '@nuxt/devalue': '@nuxt/devalue/dist/devalue.js', }, }, // ... }) ``` -------------------------------- ### PWA Integration with vite-plugin-pwa Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Integrate `vite-plugin-pwa` to automatically update the service worker precache manifest after all pages are rendered. This ensures the manifest reflects the final set of HTML files. ```typescript import { defineConfig } from 'vite' import Vue from '@vitejs/plugin-vue' import { VitePWA } from 'vite-plugin-pwa' export default defineConfig({ plugins: [ Vue(), VitePWA({ registerType: 'autoUpdate', workbox: { globPatterns: ['**/*.{js,css,html,ico,png,svg}'], }, manifest: { name: 'My App', short_name: 'App', theme_color: '#ffffff', }, }), ], ssgOptions: { script: 'async', formatting: 'minify', }, }) ``` -------------------------------- ### Conditional Code for Client/Server Builds Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Wrap code that should only run on the client or server within `import.meta.env.SSR` checks. This allows Rollup to tree-shake code effectively. ```typescript if (import.meta.env.SSR) { // your server code will be removed in the client build } else { // your client code will be removed in the server build } ``` -------------------------------- ### Export includedRoutes from Server Entry Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Export the `includedRoutes` hook from your server entry file (e.g., `main.ts`) to access Vite-managed environment variables for route generation. ```typescript // main.ts import { ViteSSG } from 'vite-ssg' import App from './App.vue' export const createApp = ViteSSG( App, { routes }, ({ app, router, initialState }) => { // ... }, ) export async function includedRoutes(paths, routes) { // Sensitive key is managed by Vite - this would not be available inside // vite.config.js as it runs before the environment has been populated. const apiClient = new MyApiClient(import.meta.env.MY_API_KEY) return Promise.all( routes.flatMap(async (route) => { return route.name === 'Blog' ? (await apiClient.fetchBlogSlugs()).map(slug => `/blog/${slug}`) : route.path }), ) } ``` -------------------------------- ### Render Components Only on Client with `` Source: https://context7.com/antfu-collective/vite-ssg/llms.txt The `` component prevents rendering its content during SSR. The default slot is rendered only after the app mounts in the browser, while the `#placeholder` slot is visible on the server and during hydration. ```vue ``` -------------------------------- ### ClientOnly Component Usage Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Use the ClientOnly component to render specific parts of your application only on the client-side. It supports a placeholder slot for server-side rendering. ```html ``` -------------------------------- ### Handle Async Components with onSSRAppRendered Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Use `onSSRAppRendered` to ensure all async operations are complete during the initial render when using features like Vue's Suspense. ```typescript const { app, router, initialState, isClient, onSSRAppRendered } = ctx const pinia = createPinia() app.use(pinia) if (import.meta.env.SSR) { onSSRAppRendered(() => { initialState.pinia = pinia.state.value }) } else { pinia.state.value = (initialState.pinia) || {} } ``` -------------------------------- ### Generate Custom Routes with includedRoutes Hook Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Use the `includedRoutes` hook in `vite.config.js` to dynamically generate route paths based on existing routes and data. ```javascript // vite.config.js export default { plugins: [], ssgOptions: { includedRoutes(paths, routes) { // use original route records return routes.flatMap((route) => { return route.name === 'Blog' ? myBlogSlugs.map(slug => `/blog/${slug}`) : route.path }) }, }, } ``` -------------------------------- ### Filter Routes Statically Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Control which routes are rendered to HTML by filtering paths directly in vite.config.ts. This method does not have access to Vite's environment variables. ```typescript // vite.config.ts — static filtering export default defineConfig({ ssgOptions: { includedRoutes(paths, routes) { // Exclude any path containing 'admin' return paths.filter(p => !p.includes('admin')) }, }, }) ``` -------------------------------- ### Capture Async State with `onSSRAppRendered` Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Use `onSSRAppRendered` to register a callback that executes after Vue has fully rendered the component tree, including resolved Suspense boundaries. This is crucial for capturing state populated by async components after the initial render, ensuring it's correctly serialized. ```typescript // src/main.ts import { ViteSSG } from 'vite-ssg' import { createPinia } from 'pinia' import App from './App.vue' export const createApp = ViteSSG(App, { routes }, ({ app, initialState, onSSRAppRendered }) => { const pinia = createPinia() app.use(pinia) if (import.meta.env.SSR) { // Wait until all async setup() / Suspense trees have settled onSSRAppRendered(() => { // Pinia stores populated by async components are now stable initialState.pinia = pinia.state.value }) } else { pinia.state.value = initialState.pinia ?? {} } }) ``` -------------------------------- ### Customize HTML Output Filename with `htmlFileName` Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Use `htmlFileName` to override the default HTML output filename for specific routes. This is particularly useful on Windows for handling catch-all routes generated by `unplugin-vue-router` that contain invalid filename characters. ```typescript // vite.config.ts export default defineConfig({ ssgOptions: { htmlFileName(filename) { // Rename the catch-all route file produced by unplugin-vue-router on Windows // Default: ":all(.*).html" → safe: "_catchall.html" if (filename.includes(':')) return filename.replace(/:[^/]+/g, '_catchall') return undefined // keep default for all other routes }, }, }) ``` -------------------------------- ### Transform HTML Before Page Rendering Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Modify the raw `index.html` before Vue renders the page for a specific route. Useful for injecting per-route meta tags or feature flags. ```typescript // vite.config.ts export default defineConfig({ ssgOptions: { async onBeforePageRender(route, indexHTML, appCtx) { // Inject a per-route CSP nonce into the HTML template const nonce = generateNonce() return indexHTML.replace( '', ``, ) }, }, }) ``` -------------------------------- ### Transform Final Rendered HTML Source: https://context7.com/antfu-collective/vite-ssg/llms.txt Modify the `renderedHTML` after Vue's SSR render and head injection for each route. The returned string replaces the output written to disk. ```typescript // vite.config.ts export default defineConfig({ ssgOptions: { async onPageRendered(route, renderedHTML, appCtx) { // Add a canonical link tag based on the current route const canonical = `https://example.com${route}` return renderedHTML.replace( '', ` `, ) }, }, }) ``` -------------------------------- ### Exclude Routes with includedRoutes Hook Source: https://github.com/antfu-collective/vite-ssg/blob/main/README.md Use the `includedRoutes` hook in `vite.config.js` to filter out specific route paths from being rendered. ```javascript // vite.config.js export default { plugins: [], ssgOptions: { includedRoutes(paths, routes) { // exclude all the route paths that contains 'foo' return paths.filter(i => !i.includes('foo')) }, }, } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.