You can define meta tags inside <head> by using following settings.

You can set these settings dynamically:

See API > Settings > HTML for other HTML settings (most notably bodyAttributes, htmlAttributes, lang).

These settings are provided by vike-react/vike-vue/vike-solid. If you don't use vike-react/vike-vue/vike-solid then see <head> tags without vike-{react,vue,solid}.

You can create your own custom settings.

Defaults

You can set defaults (that pages can override).

// pages/+config.js
 
import image from './previewImage.jpg'
 
export default {
  // Default <title>
  title: 'Awesome Rockets',
  // Default <meta name="description">
  description: 'We deliver payload to space',
  // Default <meta property="og:image">
  image
}

Page-specific

You can set values for one page or a group of pages (potentially overriding defaults).

// pages/starship/+config.js
 
export default {
  title: 'Rocket: Starship',
  description: 'The Starship is the largest rocket ever built.'
}

See: API > Config Files > Inheritance

Head setting

For other <head> tags, you can use the Head setting:

// pages/+Head.jsx or
// pages/+Head.vue
 
import favicon from './favicon.svg'
 
// Applies to all pages (cannot be overridden)
export function Head() {
  // All pages share the same favicon
  return <>
    <link rel="icon" href={favicon} type="image/svg+xml">
  </>
}

Unlike title/description/image, the Head setting is cumulative which means that pages/+Head.js cannot be overridden, see API > Head > Cumulative.

Data

You can set <head> tags based on fetched data:

// pages/rocket/starship/+data.js
 
export async function data() {
  const data = await sql.run(
    'SELECT { title, description } FROM rockets WHERE name = "starship";'
  )
  return data
}
// pages/rocket/starship/+title.ts
 
import type { PageContext } from 'vike/types'
import type { Data } from './+data'
 
// Overrides the default <title>
export default (pageContext: PageContext<Data>) => pageContext.data.title

You can define the logic once and apply it to all pages:

// pages/+title.js
 
// Applies to all pages: if a page fetches data and data.title is defined then
// use it to set the page's title.
export default (pageContext) => pageContext.data?.title || 'Some Default Title'

You can use:

The settings description and image can also access the pageContext like this.

Custom settings

You can create your own custom settings.

For example, let's create a new setting dynamicFavicon that allows different favicons to be set for different pages.

Setting creation

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

See: API > meta

// pages/+Head.jsx
 
import { usePageContext } from 'vike-react/usePageContext' // or vike-vue / vike-solid
 
export default () => {
  const pageContext = usePageContext()
  const { dynamicFavicon } = pageContext.config
  return <>
    { dynamicFavicon && <link rel="icon" href={dynamicFavicon}> }
  <>
}
// pages/+onAfterRenderClient.js
 
export default (pageContext) => {
  if (!pageContext.isHydration) {
    const { dynamicFavicon } = pageContext.config
    updateFavicon(dynamicFavicon)
  }
}
 
// https://stackoverflow.com/questions/260857/changing-website-favicon-dynamically
function updateFavicon(dynamicFavicon) {
  let link = document.querySelector("link[rel~='icon']")
  if (!dynamicFavicon) {
    if (link) document.head.removeChild(link)
    return
  }
  if (!link) {
    link = document.createElement('link')
    link.rel = 'icon'
    document.head.appendChild(link)
  }
  link.href = dynamicFavicon
}

For TypeScript users:

// pages/+config.js
 
declare global {
  namespace Vike {
    interface Config {
      dynamicFavicon?: string
    }
  }
}

See: API > meta > Typescript

Setting usage

// pages/+config.js
 
import favicon from './favicon.svg'
 
export {
  // Default favicon
  dynamicFavicon: favicon
}
// pages/premium-members/+config.js
 
import favicon from './favicon.svg'
 
export {
  // Favicon for /premium-members
  dynamicFavicon: favicon
}

Internationalization

Example of internationalizing (i18n) <head> tags:

// pages/+Head.js
// Environment: server
 
export { Head }
 
import { usePageContext } from 'vike-react/usePageContext' // or 'vike-vue' / 'vike-solid'
 
function Head() {
  const pageContext = usePageContext()
  const description = pageContext.locale === 'de-DE' ?
    'Wir liefern zum Weltall.' :
    'We deliver payload to space.'
  return <>
    <meta name="description" content={description}>
  </>
}
// pages/+title.js
// Environment: server, client
 
export function title(pageContext) {
  const title = pageContext.locale === 'de-DE' ?
    'AwesomeRockets | Das Weltall Unternehmen' :
    'AwesomeRockets | The space company'
  return title
}

See also:

Markdown

See Integration > Markdown > Metadata.

See also