Edit this page

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/Page.jsx
 
export default /* ... */
// /pages/product/@id/Layout.jsx
 
export default /* ... */

For more convenience, you can prepend + to the file names and do this:

/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

Vike automatically picks up any such + file, and it doesn't make any difference whether you define Page/Layout via +config.js > export default { Page, Layout } or +Page.jsx/+Layout.jsx

Except of +config.js, any + file corresponds to a Vike setting or Vike 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.jsx

The directory (marketing) is ignored by Filesystem Routing, see Guides > Routing > Groups.

Where:

  • pages/(marketing)/+Layout.jsx applies to all pages living at pages/(marketing)/**
  • pages/admin-panel/+Layout.jsx applies to all pages living at pages/admin-panel/**
  • pages/product/@id/+Layout.jsx applies to one page pages/product/@id/+Page.jsx

    Technically, pages/product/@id/+Layout.jsx applies 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/(marketing)/+config.js
 
export default {
  // Enable SSR for marketing pages
  ssr: true
}

To set defaults and override cumulative configurations, see: #1692 - New settings inherit and default for controlling inheritance of cumulative configs.

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.

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

Global

A configuration is called global when it always applies to all pages. Thus, config inheritance doesn't apply to global configs.

For example, Base URL settings apply globally to your app.

# 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 also applies to this page.
/pages/index/+Page.js

Domain-driven File Structure

You can use a domain-driven file structure to better organization 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.js
//   pages/admin/kpi/+Page.js
//   ...
 
import vue from 'vike-vue/config'
import telefunc from 'vike-telefunc/config'
 
// Vue + SPA + RPC
export default {
  ssr: false,
  extends: [vue, telefunc]
}
// pages/product/@id/+config.js
 
// Configuration that applies to the product page.
//   pages/product/@id/+Page.js
 
import react from 'vike-react/config'
import graphql from 'vike-react-apollo/config'
 
// React + SSR + GraphQL
export default {
  ssr: true,
  extends: [react, graphql]
}
// pages/(marketing)/+config.js
 
// Configuration that applies to all marketing pages.
//   pages/index/+Page.js
//   pages/about/+Page.js
//   pages/jobs/+Page.js
//   ...
 
import vue from 'vike-vue/config'
 
// Vue + SSR
export default {
  ssr: true,
  extends: [vue]
}

This 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-vue and vike-react within the same app.

vike-telefunc doesn'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
}

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

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

.jsx or .vue files are client/server runtime code (they usually aren't used for configuration). Thus Vike treats .jsx and .vue imports 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")

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.

See also