Installation

You can use Markdown by adding one of the following Vite plugins.

Vue

Markdown plugins compatible with Vue:

Example:

React

Markdown plugins compatible with React:

Example:

Metadata

There are several techniques for defining markdown metadata such as publishing date and author.

The preferred technique depends on whether you want to define global or local metadata.

Global metadata

What is global metadata? For example, you want to show a list of all your blog posts always on the left side of your website.

2024-01-01 New Year 2024 Resolution
2023-12-20 Wrapping up 2023
2023-06-15 My summer 2023

Because this list is shown on the left of every page, the publishing date and title of all blog posts is needed for rendering any page: the metadata needs to be accessible globally.

For global metadata, we recommend:

⚠️

You may be tempted to use import.meta.glob() to retrieve the metadata of all pages, but we discourage this approach: loading all markdown files at once contradicts Vite's lazy-transpiling approach and it would, therefore, significantly slow down development speed.

Local metadata

What is local metadata? For example, you want to show detailed information below a blog post, such as the author's name. This metadata is shown only for that page and, therefore, needs to be accessible only locally.

For local metadata, we recommend:

With a metadata.js file

A simple way to define metadata is to define a metadata.js file that contains global metadata.

// /pages/metadata.js
 
// This metadata is available to every page
export const metadata = [
  {
    url: '/blog/introducing-vike',
    title: 'Introducing Vike',
    date: new Date('2024-01-01')
  },
  {
    url: '/blog/v1',
    title: 'v1.0.0 release',
    date: new Date('2025-07-01')
  }
]
// /pages/+Layout.jsx
 
import { metadata } from './metadata'
 
export function Layout({ children }) {
  // Current URL
  const { urlPathname } = usePageContext()
  // The page's metadata
  const { title } = metadata.find(({ url }) => url === pageContext.urlPathname)
 
  return <>
    {/* Show the list of blog posts */}
    <LeftSidebar>
      <p>Blog posts:</p>
      <ul>{
        metadata.map(({ title, url, date }) =>
          <li>
            <a href={url}>{data + title}</a>
          </li>
        )
      }</ul>
    </LeftSidebar>
 
    {/* The page's content */}
    <Content>
      <h1>{ title }</h1>
      { /* children is pageContext.Page which is the component defined by +Page.md */ }
      { children }
    </Content>
  </>
}

See also:

// /pages/blog/introducing-vike/+Page.md
 
We're thrilled to officially introduce Vike.
// /pages/blog/v1/+Page.md
 
The `v1.0.0` release signals that Vike is ready for prime time: it now includes
all essentials you'd expect from a frontend framework with a robust design.

With a custom setting (eager)

You can use meta to create a custom setting for defining global metadata.

/pages/+config.js
/pages/+onCreateGlobalContext.server.ts
/pages/+Layout.jsx
/pages/2024-new-year/+Page.mdx
/pages/2024-new-year/+metadata.js
// /pages/+config.js
 
export default {
  meta: {
    // Create +metadata setting
    metadata: {
      // Make +metadata available to all pages
      eager: true,
      env: {
        server: true,
        // Instead of `client: true`, we use onCreateGlobalContext() with passToClient to
        // be able to determine exactly what metadata is sent to the client-side.
        client: false
      }
    }
  },
  passToClient: [
    // Make globalContext.posts available on the client-side
    'posts'
  ]
}

When setting eager: true the setting is available globally to all pages.

// /pages/2024-new-year/+metadata.js
 
export const metadata = {
  title: 'New Year 2024 Resolution'
}

Unlike in the example below, you cannot define +metadata inside +Page.mdx files because each +Page.mdx is loaded lazily when rendering the page. Consequently, the content of +Page.mdx isn't available to other pages — it's available only locally.

// /pages/+onCreateGlobalContext.server.ts
// Environment: server
 
import type { GlobalContextServer } from 'vike/types'
 
export async function onCreateGlobalContext(globalContext: GlobalContextServer) {
  const pages = globalContext.pages
  const posts = Object.values(pages)
    .map((page) => {
      const { metadata } = page.config
      const post = {
        url: page.route,
        title: metadata.title
      }
      return post
    })
  globalContext.posts = posts
}
 
declare global {
  namespace Vike {
    interface GlobalContext {
      posts: {
        url: string,
        title: string,
      }[]
    }
  }
}

See also:

// /pages/+Layout.jsx
// Environment: server & client
 
import { usePageContext } from 'vike-react/usePageContext' // or vike-{vue,solid}
 
export function Layout({ children }) {
  const pageContext = usePageContext()
  const { posts } = pageContext.globalContext
  return <>
    {/* Show the list of blog posts */}
    <LeftSidebar>
      <p>Blog posts:</p>
      <ul>{
        posts.map((post) =>
          <li>
            <a href={post.url}>{post.title}</a>
          </li>
        )
      }</ul>
    </LeftSidebar>
 
    {/* The page's content */}
    <Content>
      <h1>{ title }</h1>
      { /* children is pageContext.Page which is the component defined by +Page.mdx */ }
      { children }
    </Content>
  </>
}

See also:

With a custom setting

You can use meta to create a custom setting for defining local metadata.

// /pages/2024-new-year/+Page.mdx
 
export const metadata = {
  author: {
    firstName: 'John',
    lastName: 'Smith',
    country: 'England'
  }
}
 
## Some Markdown
 
This page uses [markdown](https://en.wikipedia.org/wiki/Markdown).

MDX allows you to export JavaScript values in .mdx files.

Usually, Vike forbids +Page.js files to have "side exports": the +Page.js should only export the value of the Page setting. But, for improved DX, Vike allows markdown files (such as +Page.mdx) to export the value of other settings.

// /pages/+config.js
 
// Create +metadata setting
export default {
  meta: {
    metadata: {
      env: { server: true, client: true }
    }
  }
}

With frontmatter

Some markdown processors have support for a so-called frontmatter:

---
title: A Markdown Page
author: John Smith
---
 
## Some Markdown
 
This page uses [markdown](https://en.wikipedia.org/wiki/Markdown).

You can use such frontmatter to define local metadata.

The markdown processor exposes the data defined by the frontmatter as an export, for example export { frontmatter }. You can access it by using meta to define a +frontmatter setting (or whatever the name of the export is).

// pages/+config.js
 
export default {
  meta: {
    // Create new setting +frontmatter
    frontmatter: {
      env: { server: true, client: true }
    }
  }
}

You can then use pageContext.config to access it:

// /pages/+Layout.jsx
 
import { usePageContext } from 'vike-react/usePageContext' // or vike-{vue,solid}
 
export function Layout({ children }) {
   const pageContext = usePageContext()
   const { frontmatter } = pageContext.config
   return <>
     <h1>{frontmatter.title}</h1>
     {children}
     <footer>
       <p>Written by {frontmatter.author}.</p>
     </footer>
   </>
}

See also:

See also