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"

See also <Wrapper> which also wraps <Page>, but for different use cases.

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 <>
function Navigation() { /* ... */ }
function Content() { /* ... */ }

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

Multiple layouts

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

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

See API > Config > 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 - [Cumulative configs] New settings override and default.

Nested Layouts

You can define layouts that nest into each other:

# Global outer layout that applies to all pages
# Inner layout nested into the global outer layout, for marketing pages
# Inner layout nested into the global outer layout, for admin pages

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

The Layout setting is cumulative: pages/(marketing)/+Layout.js doesn't override pages/+Layout.js but nests into it.

The <Layout> components wrap into each other:

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

You can also define 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" ...)

Make sure to use <a href="/product/42/reviews" keep-scroll-position /> to avoid scrolling to the top.

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

Caching the data of the outer layout is work-in-progress, see #1689 - [Nested Layouts] Cache data of outer layout.


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 <>
      {/* ... */}
// /pages/admin/+Page.js
export { Page }
import { LayoutDashboard } from '../layouts/LayoutDashboard'
function Page() {
  return <>
      {/* ... */}

With a custom setting

You can implement the Layout setting yourself by using meta.


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