Skip to content

Navbar

Polen allows you to customize the navigation bar by providing your own React component through a hooks.tsx file in your project root.

Overview

By default, Polen automatically generates navbar items from:

  • Your pages (from the pages/ directory)
  • Schema reference link (when a GraphQL schema is present)
  • Changelog link (when multiple schema versions exist)

You can extend, modify, or completely replace this navbar with your own implementation.

Quick Facts

  • The hooks.tsx file must be in your project root
  • You can also use hooks.ts if you don't need JSX
  • If no navbar export is found, Polen uses its default navbar
  • Your navbar component has complete control over the layout and styling
  • The navbar is rendered on every page of your developer portal

Basic Usage

Create a hooks.tsx file in your project root:

tsx
import { Polen } from 'polen'

export const navbar = Polen.Hooks.navbar(
  ({ items, Item, Logo, ThemeToggle }) => {
    return (
      <>
        <Logo />
        <div style={{ flex: 1, display: 'flex', gap: '1rem' }}>
          {items.map((item, i) => <Item key={i} item={item} index={i} />)}
        </div>
        <ThemeToggle />
      </>
    )
  },
)

Props

Your navbar component receives these props:

items

An array of NavbarItem objects generated by Polen:

typescript
interface NavbarItem {
  pathExp: string // The URL path
  title: string // Display text
  position?: 'left' | 'right' // Item alignment
}

Item

A component to render individual navbar items with Polen's default styling:

tsx
<Item item={navbarItem} index={0} />

The logo component that links to your home page.

ThemeToggle

The theme toggle button for light/dark mode switching.

Examples

Append Custom Items

Add custom items after Polen's generated items:

tsx
export const navbar = Polen.Hooks.navbar(
  ({ items, Item, Logo, ThemeToggle }) => {
    return (
      <>
        <Logo />
        <div style={{ flex: 1, display: 'flex', gap: '1rem' }}>
          {items.filter(item => item.position !== 'right').map((item, i) => (
            <Item key={i} item={item} index={i} />
          ))}
          <button>Custom Action</button>
        </div>
        <div style={{ display: 'flex', gap: '1rem' }}>
          {items.filter(item => item.position === 'right').map((item, i) => (
            <Item key={i} item={item} index={i} />
          ))}
        </div>
        <ThemeToggle />
      </>
    )
  },
)

Prepend Custom Items

Add custom items before Polen's generated items:

tsx
export const navbar = Polen.Hooks.navbar(
  ({ items, Item, Logo, ThemeToggle }) => {
    return (
      <>
        <Logo />
        <div style={{ flex: 1, display: 'flex', gap: '1rem' }}>
          <span
            style={{
              padding: '0.5rem 1rem',
              background: 'orange',
              borderRadius: '4px',
            }}
          >
            Beta
          </span>
          {items.map((item, i) => <Item key={i} item={item} index={i} />)}
        </div>
        <ThemeToggle />
      </>
    )
  },
)

Filter Items

Hide specific navbar items:

tsx
export const navbar = Polen.Hooks.navbar(
  ({ items, Item, Logo, ThemeToggle }) => {
    // Hide the changelog from navbar
    const filteredItems = items.filter(item => item.title !== 'Changelog')

    return (
      <>
        <Logo />
        <div style={{ flex: 1, display: 'flex', gap: '1rem' }}>
          {filteredItems.map((item, i) => (
            <Item
              key={i}
              item={item}
              index={i}
            />
          ))}
        </div>
        <ThemeToggle />
      </>
    )
  },
)

Complete Custom Navbar

Replace the entire navbar with your own design:

tsx
export const navbar = Polen.Hooks.navbar(({ items, Logo, ThemeToggle }) => {
  return (
    <nav
      style={{
        display: 'flex',
        alignItems: 'center',
        padding: '1rem',
        background: 'linear-gradient(to right, #667eea, #764ba2)',
      }}
    >
      <Logo />
      <div
        style={{
          flex: 1,
          display: 'flex',
          justifyContent: 'center',
          gap: '2rem',
        }}
      >
        {items.map(item => (
          <a
            key={item.pathExp}
            href={item.pathExp}
            style={{ color: 'white', textDecoration: 'none' }}
          >
            {item.title}
          </a>
        ))}
      </div>
      <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
        <button
          style={{
            background: 'white',
            color: '#667eea',
            border: 'none',
            padding: '0.5rem 1rem',
            borderRadius: '4px',
            cursor: 'pointer',
          }}
        >
          Sign In
        </button>
        <ThemeToggle />
      </div>
    </nav>
  )
})

Using UI Libraries

You can use any React UI library in your navbar. Polen bundles Radix UI Themes, which you can import directly without installing it:

tsx
import { Polen } from 'polen'
import { GitHubLogoIcon } from 'polen/radix-ui/react-icons'
import { Badge, Button, DropdownMenu } from 'polen/radix-ui/themes'

export const navbar = Polen.Hooks.navbar(
  ({ items, Item, Logo, ThemeToggle }) => {
    return (
      <>
        <Logo />
        <div
          style={{
            flex: 1,
            display: 'flex',
            gap: '1rem',
            alignItems: 'center',
          }}
        >
          {items.filter(item => item.position !== 'right').map((item, i) => (
            <Item key={i} item={item} index={i} />
          ))}
          <Badge color='orange'>Beta</Badge>
        </div>
        <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
          {items.filter(item => item.position === 'right').map((item, i) => (
            <Item key={i} item={item} index={i} />
          ))}
          <DropdownMenu.Root>
            <DropdownMenu.Trigger>
              <Button variant='ghost' size='2'>
                <GitHubLogoIcon />
              </Button>
            </DropdownMenu.Trigger>
            <DropdownMenu.Content>
              <DropdownMenu.Item>View on GitHub</DropdownMenu.Item>
              <DropdownMenu.Item>Report Issue</DropdownMenu.Item>
            </DropdownMenu.Content>
          </DropdownMenu.Root>
        </div>
        <ThemeToggle />
      </>
    )
  },
)

Note: Polen bundles Radix UI for convenience. If you prefer managing your own dependencies for better IDE support, see the Package guide.

TypeScript Support

The Polen.Hooks.navbar helper provides full TypeScript support with auto-completion for all props:

tsx
export const navbar = Polen.Hooks.navbar(({
  items, // NavbarItem[]
  Item, // React.ComponentType<{ item: NavbarItem; index: number }>
  Logo, // React.ComponentType
  ThemeToggle, // React.ComponentType
}) => {
  // Full type inference here
  return <>{/* ... */}</>
})