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:
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:
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:
<Item item={navbarItem} index={0} />
Logo
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:
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:
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:
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:
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:
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:
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 <>{/* ... */}</>
})