From 09e50a4d9c905d36940b99801bb0c4ca264f015b Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 12 Jul 2022 16:50:03 +0100 Subject: [PATCH 01/15] feat(nuxt): config default keepalive, page & layout transitions --- .../2.guide/3.directory-structure/10.pages.md | 4 +++ packages/nuxt/src/app/components/layout.ts | 4 +-- packages/nuxt/src/core/templates.ts | 8 +++++ packages/nuxt/src/head/module.ts | 17 +--------- packages/nuxt/src/head/runtime/plugin.ts | 4 +-- packages/nuxt/src/pages/runtime/page.ts | 6 ++-- packages/schema/src/config/_app.ts | 31 +++++++++++++++++++ 7 files changed, 51 insertions(+), 23 deletions(-) diff --git a/docs/content/2.guide/3.directory-structure/10.pages.md b/docs/content/2.guide/3.directory-structure/10.pages.md index 60781036c94..f24440614d9 100644 --- a/docs/content/2.guide/3.directory-structure/10.pages.md +++ b/docs/content/2.guide/3.directory-structure/10.pages.md @@ -267,6 +267,8 @@ Of course, you are welcome to define metadata for your own use throughout your a Nuxt will automatically wrap your page in [the Vue `` component](https://vuejs.org/guide/built-ins/keep-alive.html#keepalive) if you set `keepalive: true` in your `definePageMeta`. This might be useful to do, for example, in a parent route that has dynamic child routes, if you want to preserve page state across route changes. You can also set props to be passed to `` (see a full list [here](https://vuejs.org/api/built-in-components.html#keepalive)). +You can set a default value for this property [in your `nuxt.config`](/api/configuration/nuxt.config#keepalive). + #### `key` [See above](#child-route-keys). @@ -283,6 +285,8 @@ You can define middleware to apply before loading this page. It will be merged w You can define transition properties for the `` component that wraps your pages and layouts, or pass `false` to disable the `` wrapper for that route. You can see a list of options that can be passed [here](https://vuejs.org/api/built-in-components.html#transition) or read [more about how transitions work](https://vuejs.org/guide/built-ins/transition.html#transition). +You can set default values for these properties [in your `nuxt.config`](/api/configuration/nuxt.config#layouttransition). + #### `alias` You can define page aliases. They allow you to access the same page from different paths. It can be either a string or an array of strings as defined [here](https://router.vuejs.org/guide/essentials/redirect-and-alias.html#alias) on vue-router documentation. diff --git a/packages/nuxt/src/app/components/layout.ts b/packages/nuxt/src/app/components/layout.ts index 4a307ca4636..33ca8b7f5f5 100644 --- a/packages/nuxt/src/app/components/layout.ts +++ b/packages/nuxt/src/app/components/layout.ts @@ -3,8 +3,8 @@ import { _wrapIf } from './utils' import { useRoute } from '#app' // @ts-ignore import layouts from '#build/layouts' - -const defaultLayoutTransition = { name: 'layout', mode: 'out-in' } +// @ts-ignore +import { layoutTransition as defaultLayoutTransition } from '#build/app.config.mjs' export default defineComponent({ props: { diff --git a/packages/nuxt/src/core/templates.ts b/packages/nuxt/src/core/templates.ts index 81a5e95b4e7..6774728625c 100644 --- a/packages/nuxt/src/core/templates.ts +++ b/packages/nuxt/src/core/templates.ts @@ -70,6 +70,14 @@ export const serverPluginTemplate = { } } +// Add app configuration +export const appConfigTemplate = { + filename: 'app.config.mjs', + getContents: (ctx: TemplateContext) => { + return Object.entries(ctx.nuxt.options.app).map(([k, v]) => `export const ${k} = ${JSON.stringify(v)}`).join('\n\n') + } +} + export const appViewTemplate = { filename: 'views/document.template.mjs', write: true, diff --git a/packages/nuxt/src/head/module.ts b/packages/nuxt/src/head/module.ts index a8dcccbdaec..9689b75b509 100644 --- a/packages/nuxt/src/head/module.ts +++ b/packages/nuxt/src/head/module.ts @@ -1,8 +1,6 @@ import { resolve } from 'pathe' -import { addPlugin, addTemplate, defineNuxtModule } from '@nuxt/kit' -import defu from 'defu' +import { addPlugin, defineNuxtModule } from '@nuxt/kit' import { distDir } from '../dirs' -import type { MetaObject } from './runtime' export default defineNuxtModule({ meta: { @@ -21,19 +19,6 @@ export default defineNuxtModule({ // Add #head alias nuxt.options.alias['#head'] = runtimeDir - // Global meta -for Bridge, this is necessary to repeat here - // and in packages/schema/src/config/_app.ts - const globalMeta: MetaObject = defu(nuxt.options.app.head, { - charset: options.charset, - viewport: options.viewport - }) - - // Add global meta configuration - addTemplate({ - filename: 'meta.config.mjs', - getContents: () => 'export default ' + JSON.stringify({ globalMeta }) - }) - // Add generic plugin addPlugin({ src: resolve(runtimeDir, 'plugin') }) diff --git a/packages/nuxt/src/head/runtime/plugin.ts b/packages/nuxt/src/head/runtime/plugin.ts index 476bba28803..f90f679797f 100644 --- a/packages/nuxt/src/head/runtime/plugin.ts +++ b/packages/nuxt/src/head/runtime/plugin.ts @@ -3,7 +3,7 @@ import * as Components from './components' import { useHead } from './composables' import { defineNuxtPlugin, useNuxtApp } from '#app' // @ts-ignore -import metaConfig from '#build/meta.config.mjs' +import { head as globalMeta } from '#build/app.config.mjs' type MetaComponents = typeof Components declare module 'vue' { @@ -28,7 +28,7 @@ const metaMixin = { } export default defineNuxtPlugin((nuxtApp) => { - useHead(markRaw({ title: '', ...metaConfig.globalMeta })) + useHead(markRaw({ title: '', ...globalMeta })) nuxtApp.vueApp.mixin(metaMixin) diff --git a/packages/nuxt/src/pages/runtime/page.ts b/packages/nuxt/src/pages/runtime/page.ts index a42c77c37ac..cedf609e31c 100644 --- a/packages/nuxt/src/pages/runtime/page.ts +++ b/packages/nuxt/src/pages/runtime/page.ts @@ -4,6 +4,8 @@ import { RouteLocationNormalized, RouteLocationNormalizedLoaded, RouterView } fr import { generateRouteKey, RouterViewSlotProps, wrapInKeepAlive } from './utils' import { useNuxtApp } from '#app' import { _wrapIf } from '#app/components/utils' +// @ts-ignore +import { pageTransition as defaultPageTransition, keepalive as defaultKeepaliveConfig } from '#build/app.config.mjs' const isNestedKey = Symbol('isNested') @@ -32,7 +34,7 @@ export default defineComponent({ return h(RouterView, { name: props.name, route: props.route, ...attrs }, { default: (routeProps: RouterViewSlotProps) => routeProps.Component && _wrapIf(Transition, routeProps.route.meta.pageTransition ?? defaultPageTransition, - wrapInKeepAlive(routeProps.route.meta.keepalive, + wrapInKeepAlive(routeProps.route.meta.keepalive ?? defaultKeepaliveConfig, isNested && nuxtApp.isHydrating // Include route children in parent suspense ? h(routeProps.Component, { key: generateRouteKey(props.pageKey, routeProps) } as {}) @@ -50,5 +52,3 @@ export default defineComponent({ pageKey?: string | ((route: RouteLocationNormalizedLoaded) => string) [key: string]: any }> - -const defaultPageTransition = { name: 'page', mode: 'out-in' } diff --git a/packages/schema/src/config/_app.ts b/packages/schema/src/config/_app.ts index 9a4ce871cba..62dd53d2b4e 100644 --- a/packages/schema/src/config/_app.ts +++ b/packages/schema/src/config/_app.ts @@ -111,6 +111,37 @@ export default { }) } }, + + /** + * Default values for layout transitions. + * + * This can be overridden with `definePageMeta` on an individual page. + * Only JSON-serializable values are allowed. + * + * @see https://vuejs.org/api/built-in-components.html#transition + * @type {boolean | typeof import('vue').TransitionProps} + */ + layoutTransition: { name: 'layout', mode: 'out-in' }, + /** + * Default values for page transitions. + * + * This can be overridden with `definePageMeta` on an individual page. + * Only JSON-serializable values are allowed. + * + * @see https://vuejs.org/api/built-in-components.html#transition + * @type {boolean | typeof import('vue').TransitionProps} + */ + pageTransition: { name: 'page', mode: 'out-in' }, + /** + * Default values for KeepAlive configuration between pages. + * + * This can be overridden with `definePageMeta` on an individual page. + * Only JSON-serializable values are allowed. + * + * @see https://vuejs.org/api/built-in-components.html#keepalive + * @type {boolean | typeof import('vue').KeepAliveProps} + */ + keepalive: false, }, /** * The path to a templated HTML file for rendering Nuxt responses. From fe376f5a893be3e062ef0d73162563d287d665ee Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 12 Jul 2022 16:54:24 +0100 Subject: [PATCH 02/15] fix: move head defaults to schema --- packages/nuxt/src/head/module.ts | 4 ---- packages/schema/src/config/_app.ts | 4 +++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/nuxt/src/head/module.ts b/packages/nuxt/src/head/module.ts index 9689b75b509..68c5cfec26e 100644 --- a/packages/nuxt/src/head/module.ts +++ b/packages/nuxt/src/head/module.ts @@ -6,10 +6,6 @@ export default defineNuxtModule({ meta: { name: 'meta' }, - defaults: { - charset: 'utf-8', - viewport: 'width=device-width, initial-scale=1' - }, setup (options, nuxt) { const runtimeDir = nuxt.options.alias['#head'] || resolve(distDir, 'head/runtime') diff --git a/packages/schema/src/config/_app.ts b/packages/schema/src/config/_app.ts index 62dd53d2b4e..e1e7b601f03 100644 --- a/packages/schema/src/config/_app.ts +++ b/packages/schema/src/config/_app.ts @@ -210,7 +210,9 @@ export default { /** Each item in the array maps to a newly-created `