Config

Everything there is to know about configuring your Vike app.

For a list of configs, see:

+ files

You configure your Vike app by creating files that start with + such as +config.js.

For example, you can define the Page and Layout component of a page by creating a +config.js file like this:

// /pages/product/@id/+config.js
 
import Page from './Page'
import Layout from './Layout'
 
export default {
  Page,
  Layout
}
// /pages/product/@id/Page.js
 
export default /* ... */
// /pages/product/@id/Layout.js
 
export default /* ... */

For more convenience, you can also do that instead:

// /pages/product/@id/+config.js
 
import Page from './Page'
import Layout from './Layout'
 
export default {
  Page,
  Layout
}
// /pages/product/@id/Page.js
// /pages/product/@id/+Page.js
 
export default /* ... */
// /pages/product/@id/Layout.js
// /pages/product/@id/+Layout.js
 
export default /* ... */

Both achieve the same and it's just convenience: the latter allows you to skip creating the +config.js file.

Except of +config.js, the + files corresponds to a Vike setting or a Vike hook.

Inheritance

You can apply configurations to all your pages, a subset of pages, or one page only.

Example of configuring the Layout and ssr settings:

// /pages/+config.js
 
import Layout from '../layouts/LayoutDefault'
 
// Applies to all pages:
//   /pages/admin/income/+Page.js
//   /pages/admin/kpi/+Page.js
//   /pages/product/@id/+Page.js
 
export default {
  // Set <Layout> for all pages (as overridable default)
  Layout,
  // Disable SSR for all pages (as overridable default)
  ssr: false
}
// /pages/admin/+config.js
 
// Applies only to Admin Panel pages:
//   /pages/admin/income/+Page.js
//   /pages/admin/kpi/+Page.js
 
import Layout from '../../layouts/LayoutDashboard.jsx'
 
export default {
  // Set the <Layout> for all Admin Panel pages (overriding the default set by /pages/+config.js)
  Layout
}
// /pages/product/@id/+config.js
 
// Applies only to the product page:
//   /pages/product/@id/+Page.js
 
import Layout from './Layout'
 
export default {
  // Set the <Layout> of the product page (overriding the default set by /pages/+config.js)
  Layout,
  // Enable SSR (overriding the default set by /pages/+config.js)
  ssr: true
}

Technically:

  • /pages/+config.js applies to /pages/**
  • /pages/admin/+config.js applies to /pages/admin/**
  • /pages/product/@id/+config.js applies to /pages/product/@id/**

This means that /pages/+config.js doesn't necessarily apply to all pages, for example if a page is defined at /somewhere-else/+Page.js. But assuming that all pages are defined under /pages/** then /pages/+config.js does apply to all pages.

Likewise /pages/product/@id/+config.js may apply to more than one page, but assuming /pages/product/@id/+Page.js is the only page defined under /pages/product/@id/** then it applies only to that one page.

Domain-driven File Structure

For an improved organization of your pages and their configuration, you can use a domain-driven file structure.

Powerful

The config inheritance mechanism is a powerful way to configure your pages. For example, you can use two completely different rendering strategy: some pages can use Vue without SSR while other pages can use React with SSR.

// /pages/admin/+config.js
 
import vikeVue from 'vike-vue/config'
 
// Make all Admin Panel pages use Vue without SSR:
export default {
  ssr: false,
  extends: [vikeVue]
}
// /pages/product/@id/+config.js
 
import vikeReact from 'vike-react/config'
 
// Make the product page use React with SSR:
export default {
  ssr: true,
  extends: [vikeReact]
}

Pointer imports

Internally, Vike transforms this:

// /pages/+config.js
// Environment: config
 
import Layout from '../layouts/LayoutDefault.jsx'
 
export default {
  Layout
}

Into:

// /pages/+config.js
// Environment: config
 
import Layout from '../layouts/LayoutDefault.jsx'
const Layout = 'import:../layouts/LayoutDefault.jsx:default'
 
export default {
  Layout
}

This enables Vike to load the file /pages/+config.js without having to load LayoutDefault.jsx. 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.js files. Imports in other + files are normal imports as usual.

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) // Prints: /assets/logo.svg

Vike transforms an import inside +config.js to be a pointer import if and only if it resolve to a .jsx file, a .vue file, or any other file that doesn't end with .js or .ts (or .mjs/.mts/.cjs/.cts). For example:

// /pages/ssr.js
// Environment: config
 
export default false
// /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) // Prints: import:../layouts/LayoutDefault:default
console.log(ssr) // Prints: false
 
export default {
  Layout,
  ssr
}

A .jsx or .vue file is always meant to be client- / server-side runtime code. (I.e. it's never used for config logic.) That's why it makes sense that Vike always treats .jsx and .vue as pointer imports.

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) // Prints: import:./ssr:default
🚧
The with { type: 'pointer' } import attribute isn't implement yet, see workaround at #1500.

Config code isn't runtime code

The config code in 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.js 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")

See also