diff --git a/docs/content/3.docs/2.directory-structure/10.pages.md b/docs/content/3.docs/2.directory-structure/10.pages.md index 920424dfd5..924e3bf397 100644 --- a/docs/content/3.docs/2.directory-structure/10.pages.md +++ b/docs/content/3.docs/2.directory-structure/10.pages.md @@ -262,3 +262,34 @@ A simple link to the `index.vue` page in your `pages` folder: ::alert{type="info"} Learn more about [``](/docs/usage/nuxt-link) usage. :: + +## Router options + +It is possible to set default [vue-router options](https://router.vuejs.org/api/#routeroptions). + +**Note:** `history` and `routes` options will be always overriden by Nuxt. + +### Using `app/router.options` + +This is the recommaned way to specify router options. + +```js [app/router.options.ts] +import type { RouterOptions } from 'vue-router' + +// https://router.vuejs.org/api/#routeroptions +export default { +} +``` + +### Using `nuxt.config` + +**Note:** Only JSON serializable options shall be passed. Non serializable options including `parseQuery`, `scrollBehavior` and `stringifyQuery` should be set using `app/router.options` file. + +```js [nuxt.config] +export default defineNuxtConfig({ + router: { + // https://router.vuejs.org/api/#routeroptions + options: {} + } +}) +``` diff --git a/packages/kit/src/resolve.ts b/packages/kit/src/resolve.ts index 06af993c4d..01b9410976 100644 --- a/packages/kit/src/resolve.ts +++ b/packages/kit/src/resolve.ts @@ -59,7 +59,7 @@ export async function resolvePath (path: string, opts: ResolvePathOptions = {}): for (const ext of extensions) { // path.[ext] const pathWithExt = path + ext - if (!isDirectory && existsSync(pathWithExt)) { + if (existsSync(pathWithExt)) { return pathWithExt } // path/index.[ext] @@ -82,11 +82,17 @@ export async function resolvePath (path: string, opts: ResolvePathOptions = {}): /** * Try to resolve first existing file in paths */ -export async function findPath (paths: string[], opts?: ResolvePathOptions): Promise { +export async function findPath (paths: string|string[], opts?: ResolvePathOptions, pathType: 'file' | 'dir' = 'file'): Promise { + if (!Array.isArray(paths)) { + paths = [paths] + } for (const path of paths) { const rPath = await resolvePath(path, opts) if (await existsSensitive(rPath)) { - return rPath + const isDirectory = (await fsp.lstat(rPath)).isDirectory() + if (!pathType || (pathType === 'file' && !isDirectory) || (pathType === 'dir' && isDirectory)) { + return rPath + } } } return null diff --git a/packages/nuxt3/src/pages/module.ts b/packages/nuxt3/src/pages/module.ts index cfdbadd47b..9d49959da7 100644 --- a/packages/nuxt3/src/pages/module.ts +++ b/packages/nuxt3/src/pages/module.ts @@ -1,5 +1,5 @@ import { existsSync } from 'fs' -import { defineNuxtModule, addTemplate, addPlugin, addVitePlugin, addWebpackPlugin } from '@nuxt/kit' +import { defineNuxtModule, addTemplate, addPlugin, addVitePlugin, addWebpackPlugin, findPath } from '@nuxt/kit' import { resolve } from 'pathe' import { genDynamicImport, genString, genArrayFromRaw, genImport, genObjectFromRawEntries } from 'knitwork' import escapeRE from 'escape-string-regexp' @@ -75,6 +75,25 @@ export default defineNuxtModule({ } }) + // Add router options template + addTemplate({ + filename: 'router.options.mjs', + getContents: async () => { + // Check for router options + const routerOptionsFile = await findPath('~/app/router.options') + const configRouterOptions = genObjectFromRawEntries(Object.entries(nuxt.options.router.options) + .map(([key, value]) => [key, genString(value as string)])) + return [ + routerOptionsFile ? genImport(routerOptionsFile, 'routerOptions') : '', + `const configRouterOptions = ${configRouterOptions}`, + 'export default {', + '...configRouterOptions,', + routerOptionsFile ? '...routerOptions' : '', + '}' + ].join('\n') + } + }) + // Add middleware template addTemplate({ filename: 'middleware.mjs', diff --git a/packages/nuxt3/src/pages/runtime/router.ts b/packages/nuxt3/src/pages/runtime/router.ts index 2777c9b8e8..729f85fff1 100644 --- a/packages/nuxt3/src/pages/runtime/router.ts +++ b/packages/nuxt3/src/pages/runtime/router.ts @@ -11,6 +11,8 @@ import { callWithNuxt, defineNuxtPlugin, useRuntimeConfig, NuxtApp, throwError, // @ts-ignore import routes from '#build/routes' // @ts-ignore +import routerOptions from '#build/router.options' +// @ts-ignore import { globalMiddleware, namedMiddleware } from '#build/middleware' declare module 'vue' { @@ -35,6 +37,7 @@ export default defineNuxtPlugin((nuxtApp) => { : createMemoryHistory(baseURL) const router = createRouter({ + ...routerOptions, history: routerHistory, routes }) diff --git a/packages/schema/src/config/router.ts b/packages/schema/src/config/router.ts index 2cb4baa91e..badc8a5db0 100644 --- a/packages/schema/src/config/router.ts +++ b/packages/schema/src/config/router.ts @@ -1,6 +1,21 @@ import { normalizeURL, withTrailingSlash } from 'ufo' export default { + /** + * Additional options passed to vue-router + * + * Note: Only JSON serializable options should be passed by nuxt config. + * + * For more control, you can use `app/router.optionts.ts` file. + * + * @see [documentation](https://router.vuejs.org/api/#routeroptions) + * @type {import('vue-router').RouterOptions} + * + * @version 3 + */ + options: {}, + + /** * Configure the router mode. *