diff --git a/docs/headingsDetached.ts b/docs/headingsDetached.ts index df12168542..2bc66368cb 100644 --- a/docs/headingsDetached.ts +++ b/docs/headingsDetached.ts @@ -272,6 +272,10 @@ function tools(): HeadingDetachedDefinition[] { function misc(): HeadingDetachedDefinition[] { return [ + { + title: "Warning: don't define global config locally", + url: '/warning/global-config' + }, { title: 'Consulting', url: '/consulting' diff --git a/docs/pages/warning/global-config/+Page.mdx b/docs/pages/warning/global-config/+Page.mdx new file mode 100644 index 0000000000..bae17663dd --- /dev/null +++ b/docs/pages/warning/global-config/+Page.mdx @@ -0,0 +1,55 @@ +import { CodeBlockTransformer, Link } from '@brillout/docpress' + +A config is called *global* when it always applies to all pages (it cannot be applied to only a subset of pages). + +For example, the Base URL settings are global: changing the Base URL affects your whole app (all your pages). + +> There isn't any config inheritance for global configs. + +Consequently, it doesn't make sense to define a global config in a local `+` file. + +```js +// /pages/tags/+config.js + +// This is a local config file: it applies only to a subset of pages. + +export default { + // ❌ Defining a global setting in a local +config.js + baseServer: '/blog/' +} +``` + +```js +// /pages/+config.js + +// This is a global config file: it applies to all pages. + +export default { + // ✅ Defining a global setting in a global +config.js + baseServer: '/blog/' +} +``` + +If you get the following warning then move your config to a global location. + + +``` +[vike][Warning] /pages/index/+config.js (which is a local config file) sets the config `baseServer` but it's a global config: define `baseServer` at a global config file such as /pages/+config.js instead. +``` + + + +> Some settings (e.g. `prerender`) are mixed: certains values can be defined only globally (e.g. `prerender.partial`) while other values can be defined locally (e.g. `false`). +> +> If you get the following warning, it's because you're defining a global value in a local `+` file. +> +> +> ``` +> [vike][Warning] /pages/about/+config.ts (which is a local config file) sets the config `prerender` to a value that is global: define global values at a global config file such as /pages/+config.ts instead. +> ``` +> + +## See also + +- +- diff --git a/vike/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.ts b/vike/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.ts index ac793b745b..bf750c2df3 100644 --- a/vike/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.ts +++ b/vike/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.ts @@ -526,13 +526,14 @@ function assertPageConfigGlobal( interfaceFilesAll: InterfaceFilesByLocationId ) { Object.entries(pageConfigGlobal.configValueSources).forEach(([configName, sources]) => { - assertGlobalConfigLocation(configName, sources, interfaceFilesAll) + assertGlobalConfigLocation(configName, sources, interfaceFilesAll, pageConfigGlobal.configDefinitions) }) } function assertGlobalConfigLocation( configName: string, sources: ConfigValueSource[], - interfaceFilesAll: InterfaceFilesByLocationId + interfaceFilesAll: InterfaceFilesByLocationId, + configDefinitionsGlobal: ConfigDefinitions ) { const locationIdsAll = objectKeys(interfaceFilesAll) @@ -563,16 +564,24 @@ function assertGlobalConfigLocation( if (!filePathAbsoluteUserRootDir) return assert(!interfaceFile.isConfigExtension) - assertWarning( - isGlobalLocation(source.locationId, locationIdsAll), - [ - `${filePathAbsoluteUserRootDir} sets the config ${pc.cyan(configName)} but it's a global config:`, + if (!isGlobalLocation(source.locationId, locationIdsAll)) { + const configDef = configDefinitionsGlobal[configName] + assert(configDef) + const isConditionallyGlobal = isCallable(configDef.global) + const errBeg = + `${filePathAbsoluteUserRootDir} (which is a local config file) sets the config ${pc.cyan(configName)}` as const + const errMid = !isConditionallyGlobal + ? ("but it's a global config" as const) + : ('to a value that is global' as const) + const what = isConditionallyGlobal ? ('global values' as const) : pc.cyan(configName) + const errEnd = configFilePathsGlobal.length > 0 - ? `define ${pc.cyan(configName)} at ${joinEnglish(configFilePathsGlobal, 'or')} instead.` - : `create a global config (e.g. /pages/+config.js) and define ${pc.cyan(configName)} there instead.` - ].join(' '), - { onlyOnce: true } - ) + ? (`define ${what} at a global config file such as ${joinEnglish(configFilePathsGlobal, 'or')} instead` as const) + : (`create a global config file (e.g. /pages/+config.js) and define ${what} there instead` as const) + // When updating this error message => also update error message at https://vike.dev/warning/global-config + const errMsg = `${errBeg} ${errMid}: ${errEnd} (https://vike.dev/warning/global-config).` as const + assertWarning(false, errMsg, { onlyOnce: true }) + } }) } function assertPageConfigs(pageConfigs: PageConfigBuildTime[]) {