Environment: client, and server if ssr: true.

Implemented by: vike-react/vike-vue/vike-solid.

You need vike-react/vike-vue/vike-solid to be able to use the Layout setting. If you don't use vike-react/vike-vue/vike-solid then see Without vike-{react,vue,solid}.

What are layouts?

Your pages will usually share a common visual design.

Some pages may share a design while other pages share another design. (For example, two admin pages /admin/product/@id and /admin/user/@id sharing the same navigation sidebar, and two marketing pages / and /about-us not having any sidebar but sharing a sticky header instead.)

The Layout setting enables you to define such shared visual appearance.

The component defined by the Layout setting wraps the <Page> component.

<Layout>   ⟸ component defined by the setting "Layout"
  <Page /> ⟸ component defined by the setting "Page"
</Layout>

For integrating tools, we generally recommend using <Wrapper> instead.

Global layout

You can define a layout that applies to all your pages:

// /pages/+Layout.jsx
 
export { Layout }
 
// children includes <Page/>
function Layout({ children }) {
  return <>
    <Navigation/>
    <Content>{children}</Content>
  </>
}
function Navigation() { /* ... */ }
function Content() { /* ... */ }

Why /pages/+Layout.jsx applies to all pages is explained at API > Config Files > Inheritance.

Multiple layouts

You can define several layouts that apply to different groups of pages.

# Marketing pages share a layout
pages/(marketing)/+Layout.js
pages/(marketing)/index/+Page.js    # URL: /
pages/(marketing)/about/+Page.js    # URL: /about
 
# Admin pages share another layout
pages/admin-panel/+Layout.js
pages/admin-panel/index/+Page.js    # URL: /admin-panel
pages/admin-panel/users/+Page.js    # URL: /admin-panel/users

See API > Config Files > Inheritance.

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

Setting a default <Layout> that is overridable isn't currently supported, see #1692 - Add override and default options for cumulative configs.

Nested layouts

You can define layouts that nest into each other:

# Global outer layout that applies to all pages
pages/+Layout.js
# Inner layout nested into the global outer layout, for marketing pages
pages/(marketing)/+Layout.js
# Inner layout nested into the global outer layout, for admin pages
pages/admin-panel/+Layout.js

Here pages/+Layout.js applies to all pages, including the marketing and admin pages.

The Layout setting is cumulative: pages/(marketing)/+Layout.js doesn't override pages/+Layout.js. Instead, the <Layout> components nest within each other:

<Layout>      ⟸ pages/+Layout.js
  <Layout>    ⟸ pages/(marketing)/+Layout.js
    <Page />  ⟸ pages/(marketing)/about-us/+Page.js
  </Layout>
</Layout>

You can also implement same-page navigations such as tabs:

/product/42/pricing                   /product/42/reviews
+------------------+                  +-----------------+
| Macbook          |                  | Macbook         |
| ...              |                  | ...             |
| +--------------+ |                  | +-------------+ |
| | Pricing      | |  +------------>  | | Reviews     | |
| | ...          | |                  | | ...         | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+
pages/+Layout.js                      # Global layout (shared among all pages)
pages/product/@id/+Layout.js          # Outer content ("Macbook" ...)
pages/product/@id/pricing/+Page.js    # Inner content ("Pricing" ...)
pages/product/@id/reviews/+Page.js    # Inner content ("Reviews" ...)

If your nested layout isn't associated with a URL (if the pricing and reviews tabs share the same URL /product/42) then you can use a stateful component instead of <Layout>.

To avoid the page scrolling to the top, make sure to use:

Examples:

Data fetching

To fetch data for your layouts see:

Without vike-{react,vue,solid}

The following is for users that don't use a UI framework Vike extension vike-react/vike-vue/vike-solid.

The simple way

A simple way to implement layouts is to manually wrap your <Page> components:

// /pages/index/+Page.js
 
export { Page }
 
import { LayoutDefault } from '../layouts/LayoutDefault'
 
function Page() {
  return <>
    <LayoutDefault>
      {/* ... */}
    </LayoutDefault>
  </>
}
// /pages/admin/+Page.js
 
export { Page }
 
import { LayoutDashboard } from '../layouts/LayoutDashboard'
 
function Page() {
  return <>
    <LayoutDashboard>
      {/* ... */}
    </LayoutDashboard>
  </>
}

With a custom setting

You can implement the Layout setting yourself by using meta.

Examples:

Nested Layout

See the Nested layouts section above. For smooth nested layout navigation, we recommend using Client Routing. (Using Server Routing leads to full page reloads which usually isn't acceptable for same-page navigations.)

See also