---
title: "Header"
description: "A responsive header for your site navigation."
canonical_url: "https://vinicunca.dev/pohon/components/header"
---
# Header

> A responsive header for your site navigation.

## Usage

The Header component renders a `<header>` element.

> [!TIP]
> See: /pohon/getting-started/theme/css-variables#header
> 
> Its height is defined through a `--ui-header-height` CSS variable.

Use the `left`, `default` and `right` slots to customize the header and the `body` or `content` slots to customize the header menu.

```vue [HeaderExample.vue]
<script setup lang="ts">
import type { NavigationMenuItem } from 'pohon-ui';

const route = useRoute();

const items = computed<Array<NavigationMenuItem>>(() => [{
  label: 'Docs',
  to: '/pohon/getting-started',
  active: route.path.startsWith('/pohon/getting-started'),
}, {
  label: 'Components',
  to: '/pohon/components',
  active: route.path.startsWith('/pohon/components'),
}, {
  label: 'Theme',
  to: '/theme',
  target: '_blank',
}, {
  label: 'Releases',
  to: 'https://github.com/vinicunca/pohon/releases',
  target: '_blank',
}]);
</script>

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

    <PNavigationMenu :items="items" />

    <template #right>
      <PColorModeButton />

      <PTooltip
        text="Open on GitHub"
        :kbds="['meta', 'G']"
      >
        <PButton
          color="neutral"
          variant="ghost"
          to="https://github.com/vinicunca/pohon"
          target="_blank"
          icon="i-simple-icons-github"
          aria-label="GitHub"
        />
      </PTooltip>
    </template>
  </PHeader>
</template>
```

> [!NOTE]
> 
> In this example, we use the [NavigationMenu](https://vinicunca.dev/pohon/components/navigation-menu) component to render the header links in the center.

### Title

Use the `title` prop to change the title of the header. Defaults to `Pohon UI`.

```vue
<template>
  <PHeader title="Pohon UI" />
</template>
```

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

> [!TIP]
> See: #props
> 
> You should still add the `title` prop to replace the default `aria-label` of the link.

```vue
<template>
  <PHeader>
    <template #title>
      <Logo class="h-6 w-auto" />
    </template></PHeader>
</template>
```

### To

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

```vue
<template>
  <PHeader to="/pohon/getting-started" />
</template>
```

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

```vue
<template>
  <PHeader>
    <template #left>
      <NuxtLink to="/pohon/getting-started">
        <Logo class="h-6 w-auto" />
      </NuxtLink>
    </template></PHeader>
</template>
```

### Mode

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

Use the `body` slot to fill the menu body (under the header) or the `content` slot to fill the entire menu.

> [!TIP]
> See: #props
> 
> You can use the `menu` prop to customize the menu of the header, it will adapt depending on the mode you choose.

```vue [HeaderMenuExample.vue]
<script setup lang="ts">
import type { NavigationMenuItem } from 'pohon-ui';

const route = useRoute();

const items = computed<Array<NavigationMenuItem>>(() => [{
  label: 'Docs',
  to: '/pohon/getting-started',
  icon: 'i-lucide-book-open',
  active: route.path.startsWith('/pohon/getting-started'),
}, {
  label: 'Components',
  to: '/pohon/components',
  icon: 'i-lucide-box',
  active: route.path.startsWith('/pohon/components'),
}, {
  label: 'Theme',
  icon: 'i-lucide-palette',
  to: '/theme',
  target: '_blank',
}, {
  label: 'Releases',
  icon: 'i-lucide-rocket',
  to: 'https://github.com/vinicunca/pohon/releases',
  target: '_blank',
}]);
</script>

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

    <PNavigationMenu :items="items" />

    <template #right>
      <PColorModeButton />

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

    <template #body>
      <PNavigationMenu
        :items="items"
        orientation="vertical"
        class="-mx-2.5"
      />
    </template>
  </PHeader>
</template>
```

### Toggle

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

You can pass any property from the [Button](https://vinicunca.dev/pohon/components/button) component to customize it.

```vue [HeaderToggleExample.vue]
<script setup lang="ts">
import type { NavigationMenuItem } from 'pohon-ui';

const route = useRoute();

const items = computed<Array<NavigationMenuItem>>(() => [{
  label: 'Docs',
  to: '/pohon/getting-started',
  icon: 'i-lucide-book-open',
  active: route.path.startsWith('/pohon/getting-started'),
}, {
  label: 'Components',
  to: '/pohon/components',
  icon: 'i-lucide-box',
  active: route.path.startsWith('/pohon/components'),
}, {
  label: 'Theme',
  icon: 'i-lucide-palette',
  to: '/theme',
  target: '_blank',
}, {
  label: 'Releases',
  icon: 'i-lucide-rocket',
  to: 'https://github.com/vinicunca/pohon/releases',
  target: '_blank',
}]);
</script>

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

    <PNavigationMenu :items="items" />

    <template #right>
      <PColorModeButton />

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

    <template #body>
      <PNavigationMenu
        :items="items"
        orientation="vertical"
        class="-mx-2.5"
      />
    </template>
  </PHeader>
</template>
```

### Toggle Side

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

```vue [HeaderToggleSideExample.vue]
<script setup lang="ts">
import type { NavigationMenuItem } from 'pohon-ui';

const route = useRoute();

const items = computed<Array<NavigationMenuItem>>(() => [{
  label: 'Docs',
  to: '/pohon/getting-started',
  icon: 'i-lucide-book-open',
  active: route.path.startsWith('/pohon/getting-started'),
}, {
  label: 'Components',
  to: '/pohon/components',
  icon: 'i-lucide-box',
  active: route.path.startsWith('/pohon/components'),
}, {
  label: 'Theme',
  icon: 'i-lucide-palette',
  to: '/theme',
  target: '_blank',
}, {
  label: 'Releases',
  icon: 'i-lucide-rocket',
  to: 'https://github.com/vinicunca/pohon/releases',
  target: '_blank',
}]);
</script>

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

    <PNavigationMenu :items="items" />

    <template #right>
      <PColorModeButton />

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

    <template #body>
      <PNavigationMenu
        :items="items"
        orientation="vertical"
        class="-mx-2.5"
      />
    </template>
  </PHeader>
</template>
```

## Examples

### With animated toggle

Use the `#toggle` slot to replace the default toggle button with a custom animated hamburger icon using [Motion Vue](https://motion.dev/docs/vue/motion-component).

```vue [HeaderToggleAnimatedExample.vue]
<script setup lang="ts">
import type { VariantType } from 'motion-v';
import type { NavigationMenuItem } from 'pohon-ui';
import { motion } from 'motion-v';

const route = useRoute();

const items = computed<Array<NavigationMenuItem>>(() => [{
  label: 'Docs',
  to: '/pohon/getting-started',
  icon: 'i-lucide-book-open',
  active: route.path.startsWith('/pohon/getting-started'),
}, {
  label: 'Components',
  to: '/pohon/components',
  icon: 'i-lucide-box',
  active: route.path.startsWith('/pohon/components'),
}, {
  label: 'Theme',
  icon: 'i-lucide-palette',
  to: '/theme',
  target: '_blank',
}, {
  label: 'Releases',
  icon: 'i-lucide-rocket',
  to: 'https://github.com/vinicunca/pohon/releases',
  target: '_blank',
}]);

const variants: { [k: string]: VariantType | ((custom: unknown) => VariantType) } = {
  normal: {
    rotate: 0,
    y: 0,
    opacity: 1,
  },
  close: (custom: unknown) => {
    const c = custom as number;
    return {
      rotate: c === 1 ? 45 : c === 3 ? -45 : 0,
      y: c === 1 ? 6 : c === 3 ? -6 : 0,
      opacity: c === 2 ? 0 : 1,
      transition: {
        type: 'spring',
        stiffness: 260,
        damping: 20,
      },
    };
  },
};
</script>

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

    <PNavigationMenu :items="items" />

    <template #right>
      <PColorModeButton />

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

    <template #toggle="{ open, toggle, ui }">
      <PButton
        size="sm"
        variant="ghost"
        color="neutral"
        square
        :class="ui.toggle({ toggleSide: 'right' })"
        @click="toggle"
      >
        <svg
          xmlns="http://www.w3.org/2000/svg"
          class="size-5"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
        >
          <motion.line
            x1="4"
            y1="6"
            x2="20"
            y2="6"
            :variants="variants"
            :animate="open ? 'close' : 'normal'"
            :custom="1"
            tabindex="-1"
          />
          <motion.line
            x1="4"
            y1="12"
            x2="20"
            y2="12"
            :variants="variants"
            :animate="open ? 'close' : 'normal'"
            :custom="2"
            tabindex="-1"
          />
          <motion.line
            x1="4"
            y1="18"
            x2="20"
            y2="18"
            :variants="variants"
            :animate="open ? 'close' : 'normal'"
            :custom="3"
            tabindex="-1"
          />
        </svg>
      </PButton>
    </template>

    <template #body>
      <PNavigationMenu
        :items="items"
        orientation="vertical"
        class="-mx-2.5"
      />
    </template>
  </PHeader>
</template>
```

### Within `app.vue`

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

```vue [app.vue]
<script setup lang="ts">
import type { NavigationMenuItem } from 'pohon-ui';

const route = useRoute();

const items = computed<Array<NavigationMenuItem>>(() => [
  {
    label: 'Docs',
    to: '/pohon/getting-started',
    active: route.path.startsWith('/pohon/getting-started')
  },
  {
    label: 'Components',
    to: '/pohon/components',
    active: route.path.startsWith('/pohon/components')
  },
  {
    label: 'Theme',
    to: '/theme',
    target: '_blank'
  },
  {
    label: 'Releases',
    to: 'https://github.com/vinicunca/pohon/releases',
    target: '_blank'
  }
]);
</script>

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

      <PNavigationMenu :items="items" />

      <template #right>
        <PColorModeButton />

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

      <template #body>
        <PNavigationMenu
          :items="items"
          orientation="vertical"
          class="-mx-2.5"
        />
      </template>
    </PHeader>

    <PMain>
      <NuxtLayout>
        <NuxtPage />
      </NuxtLayout>
    </PMain>

    <PFooter />
  </PApp>
</template>
```

## API

### Props

```ts
/**
 * Props for the Header component
 */
interface HeaderProps {
}
```

### Slots

```ts
/**
 * Slots for the Header component
 */
interface HeaderSlots {
}
```

### Emits

No events available for this component.

## Theme

```ts [app.config.ts]
export default defineAppConfig({
  ui: {
    header: {
      slots: {
        root: 'bg-background/75 border-border border-b h-$ui-header-height top-0 sticky z-50 backdrop-blur-sm',
        container: 'flex items-center justify-between gap-3 h-full',
        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-700 text-xl color-text-highlighted flex items-end gap-1.5',
        toggle: 'lg:hidden',
        content: 'lg:hidden',
        overlay: 'lg:hidden',
        header: 'px-4 flex shrink-0 gap-3 h-$ui-header-height items-center justify-between sm:px-6',
        body: 'p-4 sm:p-6 overflow-y-auto'
      },
      variants: {
        toggleSide: {
          left: {
            toggle: '-ms-1.5'
          },
          right: {
            toggle: '-me-1.5'
          }
        }
      }
    }
  }
})
```

## Changelog

See commit history for [component](https://github.com/vinicunca/pohon/commits/main/src/runtime/components/Header.vue) and [theme](https://github.com/vinicunca/pohon/commits/main/src/theme/header.ts).

---

- [GitHub](https://github.com/vinicunca/pohon/blob/main/src/runtime/components/Header.vue)


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
