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 the following props. This is a general overview, refer to JSDoc for full details.

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 <>{/* ... */}</>
})