Config Files
Detailed information about Vike's config files.
For a list of configurations, see instead:
+ files
You configure your Vike app by creating + files.
For example, you can set the Page and Layout settings of a page by defining +config.js:
// /pages/product/@id/+config.js
import Page from './Page'
import Layout from './Layout'
export default {
Page,
Layout
}// /pages/product/@id/+config.ts
import type { Config } from 'vike/types'
import Page from './Page'
import Layout from './Layout'
export default {
Page,
Layout
} satisfies Config// /pages/product/@id/Page.js
export default /* ... */// /pages/product/@id/Page.ts
export default /* ... */// /pages/product/@id/Layout.js
export default /* ... */// /pages/product/@id/Layout.ts
export default /* ... */For more convenience, you can define following + files instead:
/pages/product/@id/+config.js
/pages/product/@id/Page.jsx
/pages/product/@id/Layout.jsx
/pages/product/@id/+Page.jsx
/pages/product/@id/+Layout.jsx/pages/product/@id/+config.ts
/pages/product/@id/Page.tsx
/pages/product/@id/Layout.tsx
/pages/product/@id/+Page.tsx
/pages/product/@id/+Layout.tsxVike automatically picks up + file — it doesn't make any difference whether you define Page/Layout via +Page.jsx/+Layout.jsx, or via +config.js > export default { Page, Layout }.
Except of
+config.js, any+file corresponds to a Vike setting or hook.
Inheritance
Vike comes with a powerful config inheritance system that enables great flexibility and control.
Basics
You can apply configurations to all pages, a group of pages, or only one page. For example:
pages/(marketing)/index/+Page.jsx # URL: /
pages/(marketing)/about/+Page.jsx # URL: /about
# Layout for marketing pages
pages/(marketing)/+Layout.jsx
pages/admin-panel/index/+Page.jsx # URL: /admin-panel
pages/admin-panel/users/+Page.jsx # URL: /admin-panel/users
# Layout for admin pages
pages/admin-panel/+Layout.jsx
pages/product/@id/+Page.jsx
# Layout for the product page
pages/product/@id/+Layout.jsxThe directory
(marketing)is ignored by Filesystem Routing, see Guides > Routing > Groups.
Where:
pages/(marketing)/+Layout.jsxapplies to all pages living atpages/(marketing)/**pages/admin-panel/+Layout.jsxapplies to all pages living atpages/admin-panel/**pages/product/@id/+Layout.jsxapplies to one pagepages/product/@id/+Page.jsxTechnically,
pages/product/@id/+Layout.jsxapplies to all pages at/pages/product/@id/**but there is only one page living there.
Defaults
You can set defaults and override them. For example:
// pages/+config.js
export default {
// Disable SSR by default
ssr: false
}// pages/+config.ts
import type { Config } from 'vike/types'
export default {
// Disable SSR by default
ssr: false
} satisfies Config// pages/(marketing)/+config.js
export default {
// Enable SSR for marketing pages
ssr: true
}// pages/(marketing)/+config.ts
import type { Config } from 'vike/types'
export default {
// Enable SSR for marketing pages
ssr: true
} satisfies ConfigCumulative configs don't get overridden but accumulate instead (unless the filename extension
.default.jsis used).
Cumulative
A configuration is called cumulative when it can be defined multiple times.
For example, the +Layout setting is cumulative — a page can be wrapped by multiple <Layout> components.
# Defines the outer layout
pages/+Layout.js
# Defines the inner layout (aka nested layout)
pages/(marketing)/+Layout.js<Layout> ⟸ pages/+Layout.js
<Layout> ⟸ pages/(marketing)/+Layout.js
<Page />
</Layout>
</Layout>The pages/(marketing)/+Layout.js file doesn't override pages/+Layout.js — instead, multiple <Layout> components nest within each other.
You can control how cumulative configs inherit from parent directories by using the filename suffixes
.clear.jsand.default.js.
In contrast, the +title setting isn't cumulative — a page can only have one title.
# Defines the default title
pages/+title.js
# Defines the title of the product page, overriding pages/+title.js
pages/product/@id/+title.js.clear.js
The .clear.js filename suffix resets the inheritance chain of cumulative configs, preventing configurations from parent directories from being inherited.
pages/+Layout.jsx
# Inherits pages/+Layout.jsx
pages/product/@id/+Page.jsx
# This layout clears inheritance and starts fresh
pages/admin/+Layout.clear.jsx
# This layout will be added to the admin layout
pages/admin/dashboard/+Layout.jsx
# Only inherits the two admin layouts above
pages/admin/dashboard/users/+Page.jsxSee also:
.default.js
The .default.js filename suffix makes a cumulative configuration act as a fallback — it's only used when no child directory defines the configuration.
# Default layout
pages/+Layout.default.jsx
# Inherits the default layout
pages/product/@id/+Page.jsx
# Overrides the default layout
pages/admin/+Layout.jsx
# Only inherits the admin layout
pages/admin/dashboard/+Page.jsxSee also:
Global
Some configurations are always global, while others can be per-page:
-
Global configuration — always applies to all pages.
For example, the Base URL setting is global: changing the Base URL affects your whole app (all your pages).
A global config cannot be applied to only a subset of pages.
There isn't any config inheritance for global configs:
# Defining +baseAssets for a single page doesn't make sense — Vike logs a warning # since this +baseAssets.js file applies to all pages, not just this one. /pages/about/+baseAssets.js /pages/about/+Page.js # No config inheritance — the +baseAssets.js file above also applies to this page. /pages/index/+Page.js -
Per-page configuration — can be defined on a per-page basis, as well as globally.
For example, the
+titlesetting is per-page: each page can have a different title.A per-page config can apply globally if defined at a global location:
// pages/+config.js import { Config } from 'vike/types' export default { // Defines the default title for all pages. Applies to all pages unless overridden. title: 'My App' }// pages/+config.ts import { Config } from 'vike/types' export default { // Defines the default title for all pages. Applies to all pages unless overridden. title: 'My App' } satisfies ConfigSee also: Inheritance.
Groups
You can use page groups to better organize configuration inheritance.
Powerful
You can use config inheritance for having multiple and completely different stacks within the same app. For example:
// pages/admin/+config.js
// Configuration that applies to all admin pages.
// pages/admin/income/+Page.vue
// pages/admin/kpi/+Page.vue
// ...
import vue from 'vike-vue/config'
import telefunc from 'vike-telefunc/config'
// Vue + SPA + RPC
export default {
ssr: false,
extends: [vue, telefunc]
}// pages/admin/+config.ts
// Configuration that applies to all admin pages.
// pages/admin/income/+Page.vue
// pages/admin/kpi/+Page.vue
// ...
import type { Config } from 'vike/types'
import vue from 'vike-vue/config'
import telefunc from 'vike-telefunc/config'
// Vue + SPA + RPC
export default {
ssr: false,
extends: [vue, telefunc]
} satisfies Config// pages/product/@id/+config.js
// Configuration that applies to the product page.
// pages/product/@id/+Page.jsx
import react from 'vike-react/config'
import graphql from 'vike-react-apollo/config'
// React + SSR + GraphQL
export default {
ssr: true,
extends: [react, graphql]
}// pages/product/@id/+config.ts
// Configuration that applies to the product page.
// pages/product/@id/+Page.tsx
import type { Config } from 'vike/types'
import react from 'vike-react/config'
import graphql from 'vike-react-apollo/config'
// React + SSR + GraphQL
export default {
ssr: true,
extends: [react, graphql]
} satisfies Config// pages/(marketing)/+config.js
// Configuration that applies to all marketing pages.
// pages/index/+Page.vue
// pages/about/+Page.vue
// pages/jobs/+Page.vue
// ...
import vue from 'vike-vue/config'
// Vue + SSR
export default {
ssr: true,
extends: [vue]
}// pages/(marketing)/+config.ts
// Configuration that applies to all marketing pages.
// pages/index/+Page.vue
// pages/about/+Page.vue
// pages/jobs/+Page.vue
// ...
import type { Config } from 'vike/types'
import vue from 'vike-vue/config'
// Vue + SSR
export default {
ssr: true,
extends: [vue]
} satisfies ConfigThis also enables you to experiment and/or progressively migrate your stack on a page-by-page basis.
There is currently a blocker for being able to use
vike-vueandvike-reactwithin the same app.
vike-telefuncdoesn't exist yet: it's the upcoming integration that will enable you to use RPC for fetching initial data (instead of using+data).
Pointer imports
Internally, Vike transforms this:
// /pages/+config.js
// Environment: config
import Layout from '../layouts/LayoutDefault.jsx'
export default {
Layout
}// /pages/+config.ts
// Environment: config
import type { Config } from 'vike/types'
import Layout from '../layouts/LayoutDefault.jsx'
export default {
Layout
} satisfies ConfigInto:
// /pages/+config.js
// Environment: config
import Layout from '../layouts/LayoutDefault.jsx'
const Layout = 'import:../layouts/LayoutDefault.jsx:default'
export default {
Layout
}// /pages/+config.ts
// Environment: config
import type { Config } from 'vike/types'
import Layout from '../layouts/LayoutDefault.jsx'
const Layout = 'import:../layouts/LayoutDefault.jsx:default'
export default {
Layout
} satisfies ConfigThis enables Vike to load the file /pages/+config.js without having to load LayoutDefault.jsx. This means that Vike can quickly load all your +config.js files without having to load any runtime code.
These fake imports, which we call pointer imports, apply only to
+config.jsfiles. Imports in other+files are normal imports.
It's similar to when you import images:
import logo from '../images/logo.svg'
// When you import an image, you don't actually load it: you get a URL instead.
console.log(logo) // /assets/logo.svgVike transforms an import inside +config.js to be a pointer import if and only if the import resolves to a file that doesn't end with .js/.ts/.mjs/.mts/.cjs/.cts.
For example, an import that resolves to a .jsx or .vue file is transformed to be a pointer import:
// /pages/+config.js
// Environment: config
// Resolves to the file LayoutDefault.jsx (a .jsx file) => pointer import
import Layout from '../layouts/LayoutDefault'
// Resolves to the file ssr.js (a .js file) => normal import
import ssr from './ssr'
console.log(Layout) // import:../layouts/LayoutDefault:default
console.log(ssr) // false
export default {
Layout,
ssr
}// /pages/+config.ts
// Environment: config
import type { Config } from 'vike/types'
// Resolves to the file LayoutDefault.jsx (a .jsx file) => pointer import
import Layout from '../layouts/LayoutDefault'
// Resolves to the file ssr.js (a .js file) => normal import
import ssr from './ssr'
console.log(Layout) // import:../layouts/LayoutDefault:default
console.log(ssr) // false
export default {
Layout,
ssr
} satisfies Config// /pages/ssr.js
// Environment: config
export default false// /pages/ssr.ts
// Environment: config
export default false
.jsxor.vuefiles are client/server runtime code (they usually aren't used for configuration). Thus Vike treats.jsxand.vueimports as pointer imports.
Config code isn't runtime code
The config code itself is never included in runtimes:
// /pages/some-page/+config.js
// A CSS import in a config file doesn't have any effect. CSS should
// be imported in runtime files such as +Page.jsx instead.
import './some.css'
// This log is printed only when Vike loads this +config.js file (at development and when
// building your app). This log isn't included in the client nor server runtime.
// Consequently, you won't see this log in production.
console.log('I will never be logged in production')// /pages/some-page/+config.ts
// A CSS import in a config file doesn't have any effect. CSS should
// be imported in runtime files such as +Page.jsx instead.
import './some.css'
// This log is printed only when Vike loads this +config.ts file (at development and when
// building your app). This log isn't included in the client nor server runtime.
// Consequently, you won't see this log in production.
console.log("I will never be logged in production")Manually mark pointer imports
You can manually mark an import to be a pointer import:
// /pages/+config.js
// Environment: config
import ssr from './ssr' with { type: 'pointer' }
console.log(ssr) // import:./ssr:default// /pages/+config.ts
// Environment: config
import ssr from './ssr' with { type: 'pointer' }
console.log(ssr) // import:./ssr:default🚧Thewith { type: 'pointer' }import attribute isn't implement yet, see workaround at #1500.