Header

A responsive header component.

Usage

The Header component renders a <header> element. Its height is defined through a --ui-header-height CSS variable, which you can customize by overriding it in your CSS:

:root {
  --ui-header-height: calc(var(--spacing) * 16);
}

Use the left, default and right slots to customize the header.

<script setup lang="ts">
const route = useRoute()

const items = computed(() => [
  {
    label: 'Docs',
    to: '/getting-started',
    active: route.path.startsWith('/getting-started')
  },
  {
    label: 'Components',
    to: '/components',
    active: route.path.startsWith('/components')
  },
  {
    label: 'Roadmap',
    to: '/roadmap'
  },
  {
    label: 'Figma',
    to: 'https://www.figma.com/community/file/1288455405058138934',
    target: '_blank'
  },
  {
    label: 'Releases',
    to: 'https://github.com/nuxt/ui/releases',
    target: '_blank'
  }
])
</script>

<template>
  <UHeader>
    <template #title>
      <Logo class="h-6 w-auto" />
    </template>

    <UNavigationMenu :items="items" />

    <template #right>
      <UColorModeButton />

      <UTooltip text="Open on GitHub" :kbds="['meta', 'G']">
        <UButton
          color="neutral"
          variant="ghost"
          to="https://github.com/nuxt/ui"
          target="_blank"
          icon="i-simple-icons-github"
          aria-label="GitHub"
        />
      </UTooltip>
    </template>
  </UHeader>
</template>
In this example, we use the NavigationMenu component to render the header links in the center.

Title

Use the title prop to change the title of the header. Defaults to Nuxt UI Pro.

<template>
  <UHeader title="Nuxt UI Pro" />
</template>

You can also use the title slot to add your own logo.

<template>
  <UHeader>
    <template #title>
      <Logo class="h-6 w-auto" />
    </template>
  </UHeader>
</template>

To

Use the to prop to change the link of the title. Defaults to /.

<template>
  <UHeader to="/getting-started" />
</template>

You can also use the left slot to override the link entirely.

<template>
  <UHeader>
    <template #left>
      <NuxtLink to="/getting-started">
        <Logo class="h-6 w-auto" />
      </NuxtLink>
    </template>
  </UHeader>
</template>

Mode

Use the mode prop to change the mode of the header menu. Defaults to modal.

Use the content slot to fill the menu with your own content.

<script setup lang="ts">
const route = useRoute()

const items = computed(() => [{
  label: 'Docs',
  to: '/getting-started',
  icon: 'i-lucide-book-open',
  active: route.path.startsWith('/getting-started')
}, {
  label: 'Components',
  to: '/components',
  icon: 'i-lucide-box',
  active: route.path.startsWith('/components')
}, {
  label: 'Roadmap',
  icon: 'i-lucide-map',
  to: '/roadmap'
}, {
  label: 'Figma',
  icon: 'i-simple-icons-figma',
  to: 'https://www.figma.com/community/file/1288455405058138934',
  target: '_blank'
}, {
  label: 'Releases',
  icon: 'i-lucide-rocket',
  to: 'https://github.com/nuxt/ui/releases',
  target: '_blank'
}])
</script>

<template>
  <UHeader>
    <template #title>
      <Logo class="h-6 w-auto" />
    </template>

    <UNavigationMenu :items="items" />

    <template #right>
      <UColorModeButton />

      <UTooltip text="Open on GitHub" :kbds="['meta', 'G']">
        <UButton
          color="neutral"
          variant="ghost"
          to="https://github.com/nuxt/ui"
          target="_blank"
          icon="i-simple-icons-github"
          aria-label="GitHub"
        />
      </UTooltip>
    </template>

    <template #content>
      <UNavigationMenu :items="items" orientation="vertical" class="-mx-2.5" />
    </template>
  </UHeader>
</template>

Toggle

Use the toggle prop to customize the toggle button displayed on mobile.

You can pass any property from the Button component to customize it.

<script setup lang="ts">
const route = useRoute()

const items = computed(() => [{
  label: 'Docs',
  to: '/getting-started',
  icon: 'i-lucide-book-open',
  active: route.path.startsWith('/getting-started')
}, {
  label: 'Components',
  to: '/components',
  icon: 'i-lucide-box',
  active: route.path.startsWith('/components')
}, {
  label: 'Roadmap',
  icon: 'i-lucide-map',
  to: '/roadmap'
}, {
  label: 'Figma',
  icon: 'i-simple-icons-figma',
  to: 'https://www.figma.com/community/file/1288455405058138934',
  target: '_blank'
}, {
  label: 'Releases',
  icon: 'i-lucide-rocket',
  to: 'https://github.com/nuxt/ui/releases',
  target: '_blank'
}])
</script>

<template>
  <UHeader
    :toggle="{
      color: 'primary',
      variant: 'subtle',
      class: 'rounded-full'
    }"
  >
    <template #title>
      <Logo class="h-6 w-auto" />
    </template>

    <UNavigationMenu :items="items" />

    <template #right>
      <UColorModeButton />

      <UTooltip text="Open on GitHub" :kbds="['meta', 'G']">
        <UButton
          color="neutral"
          variant="ghost"
          to="https://github.com/nuxt/ui"
          target="_blank"
          icon="i-simple-icons-github"
          aria-label="GitHub"
        />
      </UTooltip>
    </template>

    <template #content>
      <UNavigationMenu :items="items" orientation="vertical" class="-mx-2.5" />
    </template>
  </UHeader>
</template>
The toggle button will only be visible when you provide a content slot.

Toggle Side

Use the toggle-side prop to change the side of the toggle button. Defaults to right.

<script setup lang="ts">
const route = useRoute()

const items = computed(() => [{
  label: 'Docs',
  to: '/getting-started',
  icon: 'i-lucide-book-open',
  active: route.path.startsWith('/getting-started')
}, {
  label: 'Components',
  to: '/components',
  icon: 'i-lucide-box',
  active: route.path.startsWith('/components')
}, {
  label: 'Roadmap',
  icon: 'i-lucide-map',
  to: '/roadmap'
}, {
  label: 'Figma',
  icon: 'i-simple-icons-figma',
  to: 'https://www.figma.com/community/file/1288455405058138934',
  target: '_blank'
}, {
  label: 'Releases',
  icon: 'i-lucide-rocket',
  to: 'https://github.com/nuxt/ui/releases',
  target: '_blank'
}])
</script>

<template>
  <UHeader toggle-side="left">
    <template #title>
      <Logo class="h-6 w-auto" />
    </template>

    <UNavigationMenu :items="items" />

    <template #right>
      <UColorModeButton />

      <UTooltip text="Open on GitHub" :kbds="['meta', 'G']">
        <UButton
          color="neutral"
          variant="ghost"
          to="https://github.com/nuxt/ui"
          target="_blank"
          icon="i-simple-icons-github"
          aria-label="GitHub"
        />
      </UTooltip>
    </template>

    <template #content>
      <UNavigationMenu :items="items" orientation="vertical" class="-mx-2.5" />
    </template>
  </UHeader>
</template>

Examples

Within app.vue

Use the Header component in your app.vue or in a layout:

app.vue
<script setup lang="ts">
const route = useRoute()

const items = computed(() => [{
  label: 'Docs',
  to: '/getting-started',
  active: route.path.startsWith('/getting-started')
}, {
  label: 'Components',
  to: '/components',
  active: route.path.startsWith('/components')
}, {
  label: 'Roadmap',
  to: '/roadmap'
}, {
  label: 'Figma',
  to: 'https://www.figma.com/community/file/1288455405058138934',
  target: '_blank'
}, {
  label: 'Releases',
  to: 'https://github.com/nuxt/ui/releases',
  target: '_blank'
}])
</script>

<template>
  <UApp>
    <UHeader>
      <template #title>
        <Logo class="h-6 w-auto" />
      </template>

      <UNavigationMenu :items="items" />

      <template #right>
        <UColorModeButton />

        <UButton
          color="neutral"
          variant="ghost"
          to="https://github.com/nuxt/ui"
          target="_blank"
          icon="i-simple-icons-github"
          aria-label="GitHub"
        />
      </template>

      <template #content>
        <UNavigationMenu :items="items" orientation="vertical" class="-mx-2.5" />
      </template>
    </UHeader>

    <UMain>
      <NuxtLayout>
        <NuxtPage />
      </NuxtLayout>
    </UMain>

    <UFooter />
  </UApp>
</template>

API

Props

Prop Default Type
as

'header'

any

The element or component this component should render as.

open

boolean

title

'Nuxt UI Pro'

string

to

'/'

string

mode

'modal'

"modal" | "slideover" | "drawer"

The mode of the header menu.

menu

DrawerProps | ModalProps | SlideoverProps

The props for the header menu component.

toggle

ButtonProps

Customize the toggle button to open the header menu displayed when the content slot is used. { color: 'neutral', variant: 'ghost' }

toggleSide

'right'

"left" | "right"

The side to render the toggle button on.

ui

Partial<{ root: string; container: string; left: string; center: string; right: string; title: string; toggle: string; content: string; overlay: string; header: string; body: string; }>

Slots

Slot Type
title

{}

left

{}

default

{}

right

{}

toggle

{}

top

{}

bottom

{}

content

{}

Emits

Event Type
update:open

[value: boolean]

Theme

app.config.ts
export default defineAppConfig({
  uiPro: {
    header: {
      slots: {
        root: 'bg-[var(--ui-bg)]/75 backdrop-blur border-b border-[var(--ui-border)] sticky top-0 z-50',
        container: 'flex items-center justify-between gap-3 h-[var(--ui-header-height)]',
        left: 'lg:flex-1 flex items-center gap-1.5',
        center: 'hidden lg:flex',
        right: 'flex items-center justify-end lg:flex-1 gap-1.5',
        title: 'shrink-0 font-bold text-xl text-[var(--ui-text-highlighted)] flex items-end gap-1.5',
        toggle: 'lg:hidden',
        content: 'lg:hidden',
        overlay: 'lg:hidden',
        header: '',
        body: 'p-4 sm:p-6 overflow-y-auto'
      },
      variants: {
        toggleSide: {
          left: {
            toggle: '-ms-1.5'
          },
          right: {
            toggle: '-me-1.5'
          }
        }
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      uiPro: {
        header: {
          slots: {
            root: 'bg-[var(--ui-bg)]/75 backdrop-blur border-b border-[var(--ui-border)] sticky top-0 z-50',
            container: 'flex items-center justify-between gap-3 h-[var(--ui-header-height)]',
            left: 'lg:flex-1 flex items-center gap-1.5',
            center: 'hidden lg:flex',
            right: 'flex items-center justify-end lg:flex-1 gap-1.5',
            title: 'shrink-0 font-bold text-xl text-[var(--ui-text-highlighted)] flex items-end gap-1.5',
            toggle: 'lg:hidden',
            content: 'lg:hidden',
            overlay: 'lg:hidden',
            header: '',
            body: 'p-4 sm:p-6 overflow-y-auto'
          },
          variants: {
            toggleSide: {
              left: {
                toggle: '-ms-1.5'
              },
              right: {
                toggle: '-me-1.5'
              }
            }
          }
        }
      }
    })
  ]
})