Navbar

No one ever got fired for starting a website with a horizontal navigation menu.

<script>
	import { Avatar } from '$lib/components/avatar';
	import {
		Dropdown,
		DropdownButton,
		DropdownDivider,
		DropdownItem,
		DropdownLabel,
		DropdownMenu
	} from '$lib/components/dropdown';
	import {
		Navbar,
		NavbarDivider,
		NavbarItem,
		NavbarLabel,
		NavbarSection,
		NavbarSpacer
	} from '$lib/components/navbar';
	import HeroiconsArrowRightStartOnRectangle16Solid from 'virtual:icons/heroicons/arrow-right-start-on-rectangle-16-solid';
	import HeroiconsChevronDown16Solid from 'virtual:icons/heroicons/chevron-down-16-solid';
	import HeroiconsCog8Tooth16Solid from 'virtual:icons/heroicons/cog8-tooth-16-solid';
	import HeroiconsLightBulb16Solid from 'virtual:icons/heroicons/light-bulb-16-solid';
	import HeroiconsPlus16Solid from 'virtual:icons/heroicons/plus-16-solid';
	import HeroiconsShieldCheck16Solid from 'virtual:icons/heroicons/shield-check-16-solid';
	import HeroiconsUser16Solid from 'virtual:icons/heroicons/user-16-solid';

	import HeroiconsInbox20Solid from 'virtual:icons/heroicons/inbox-20-solid';
	import HeroiconsMagnifyingGlass20Solid from 'virtual:icons/heroicons/magnifying-glass-20-solid';
</script>

<Navbar>
	<Dropdown>
		<DropdownButton as={NavbarItem}>
			<Avatar src="/tailwind-logo.svg" />
			<NavbarLabel>Tailwind Labs</NavbarLabel>
			<HeroiconsChevronDown16Solid />
		</DropdownButton>
		<DropdownMenu class="min-w-64" anchor="bottom start">
			<DropdownItem href="/teams/1/settings">
				<HeroiconsCog8Tooth16Solid />
				<DropdownLabel>Settings</DropdownLabel>
			</DropdownItem>
			<DropdownDivider />
			<DropdownItem href="/teams/1">
				<Avatar slot="icon" src="/tailwind-logo.svg" />
				<DropdownLabel>Tailwind Labs</DropdownLabel>
			</DropdownItem>
			<DropdownItem href="/teams/2">
				<Avatar slot="icon" initials="WC" class="bg-purple-500 text-white" />
				<DropdownLabel>Workcation</DropdownLabel>
			</DropdownItem>
			<DropdownDivider />
			<DropdownItem href="/teams/create">
				<HeroiconsPlus16Solid />
				<DropdownLabel>New team&hellip;</DropdownLabel>
			</DropdownItem>
		</DropdownMenu>
	</Dropdown>
	<NavbarDivider class="max-lg:hidden" />
	<NavbarSection class="max-lg:hidden">
		<NavbarItem href="/" current>Home</NavbarItem>
		<NavbarItem href="/events">Events</NavbarItem>
		<NavbarItem href="/orders">Orders</NavbarItem>
	</NavbarSection>
	<NavbarSpacer />
	<NavbarSection>
		<NavbarItem href="/search" aria-label="Search">
			<HeroiconsMagnifyingGlass20Solid />
		</NavbarItem>
		<NavbarItem href="/inbox" aria-label="Inbox">
			<HeroiconsInbox20Solid />
		</NavbarItem>
		<Dropdown>
			<DropdownButton as={NavbarItem}>
				<Avatar src="/profile-photo.jpg" square />
			</DropdownButton>
			<DropdownMenu class="min-w-64" anchor="bottom end">
				<DropdownItem href="/my-profile">
					<HeroiconsUser16Solid />
					<DropdownLabel>My profile</DropdownLabel>
				</DropdownItem>
				<DropdownItem href="/settings">
					<HeroiconsCog8Tooth16Solid />
					<DropdownLabel>Settings</DropdownLabel>
				</DropdownItem>
				<DropdownDivider />
				<DropdownItem href="/privacy-policy">
					<HeroiconsShieldCheck16Solid />
					<DropdownLabel>Privacy policy</DropdownLabel>
				</DropdownItem>
				<DropdownItem href="/share-feedback">
					<HeroiconsLightBulb16Solid />
					<DropdownLabel>Share feedback</DropdownLabel>
				</DropdownItem>
				<DropdownDivider />
				<DropdownItem href="/logout">
					<HeroiconsArrowRightStartOnRectangle16Solid />
					<DropdownLabel>Sign out</DropdownLabel>
				</DropdownItem>
			</DropdownMenu>
		</Dropdown>
	</NavbarSection>
</Navbar>

Component API

PropDefaultDescription
Navbar extends the JSX <div> element
This component does not expose any component-specific props.
NavbarDivider extends the JSX <div> element
This component does not expose any component-specific props.
NavbarSection extends the JSX <div> element
This component does not expose any component-specific props.
NavbarSpacer extends the JSX <div> element
This component does not expose any component-specific props.
NavbarItem extends the Headless UI Button component or the Link component
current-Whether or not it is the current navigation item.
href-The target URL when using the button as a link.
NavbarLabel extends the JSX <span> element
This component does not expose any component-specific props.

Examples

Basic example

Use the Navbar, NavbarSection and NavbarItem components to build a basic navbar with navigation links:

<script>
	import { Navbar, NavbarItem, NavbarSection } from '$lib/components/navbar';
</script>

<Navbar>
	<NavbarSection>
		<NavbarItem href="/">Home</NavbarItem>
		<NavbarItem href="/events">Events</NavbarItem>
		<NavbarItem href="/orders">Orders</NavbarItem>
	</NavbarSection>
</Navbar>

The NavbarItem component can be used either as a Link by providing an href prop or as a Button by omitting the href prop.

Add your own logo as an image or component at the beginning of your navbar:

<script>
	import { Navbar, NavbarItem, NavbarSection } from '$lib/components/navbar';
	import Logo from './logo.svelte';
</script>

<Navbar>
	<a href="/" aria-label="Home">
		<Logo class="size-10 sm:size-8" />
	</a>
	<NavbarSection>
		<NavbarItem href="/" current>Home</NavbarItem>
		<NavbarItem href="/events">Events</NavbarItem>
		<NavbarItem href="/orders">Orders</NavbarItem>
	</NavbarSection>
</Navbar>

To best fit the navbar design, we recommend making your logo 40px tall at mobile sizes, and 32px tall at the sm breakpoint above.

With active state

Use the current prop to specify which NavbarItem is the current navigation item:

<script>
	import { Navbar, NavbarItem, NavbarSection } from '$lib/components/navbar';
	import Logo from './logo.svelte';
</script>

<Navbar>
	<a href="/" aria-label="Home">
		<Logo class="size-10 sm:size-8" />
	</a>
	<NavbarSection>
		<NavbarItem href="/" current>Home</NavbarItem>
		<NavbarItem href="/events">Events</NavbarItem>
		<NavbarItem href="/orders">Orders</NavbarItem>
	</NavbarSection>
</Navbar>

Use an icon as the only child of a NavbarItem to create icon-only links:

<script>
	import { Navbar, NavbarItem, NavbarSection, NavbarSpacer } from '$lib/components/navbar';
	import HeroiconsInbox20Solid from 'virtual:icons/heroicons/inbox-20-solid';
	import HeroiconsMagnifyingGlass20Solid from 'virtual:icons/heroicons/magnifying-glass-20-solid';
	import Logo from './logo.svelte';
</script>

<Navbar>
	<a href="/" aria-label="Home">
		<Logo class="size-10 sm:size-8" />
	</a>
	<NavbarSpacer />
	<NavbarSection>
		<NavbarItem href="/search" aria-label="Search">
			<HeroiconsMagnifyingGlass20Solid />
		</NavbarItem>
		<NavbarItem href="/inbox" aria-label="Inbox">
			<HeroiconsInbox20Solid />
		</NavbarItem>
	</NavbarSection>
</Navbar>

When using icon-only links, make sure to provide an aria-label for assistive technology. The NavbarItem component is designed to work best with 20×20 icons.

With space between items

Use the NavbarSpacer component to add space between items in the navbar:

<script>
	import { Navbar, NavbarItem, NavbarSection, NavbarSpacer } from '$lib/components/navbar';
	import HeroiconsInbox20Solid from 'virtual:icons/heroicons/inbox-20-solid';
	import HeroiconsMagnifyingGlass20Solid from 'virtual:icons/heroicons/magnifying-glass-20-solid';
	import Logo from './logo.svelte';
</script>

<Navbar>
	<a href="/" aria-label="Home">
		<Logo class="size-10 sm:size-8" />
	</a>
	<NavbarSpacer />
	<NavbarSection>
		<NavbarItem href="/search" aria-label="Search">
			<HeroiconsMagnifyingGlass20Solid />
		</NavbarItem>
		<NavbarItem href="/inbox" aria-label="Inbox">
			<HeroiconsInbox20Solid />
		</NavbarItem>
	</NavbarSection>
</Navbar>

With divider

Use the NavbarDivider component to add a dividing line between items in the navbar:

<script>
	import { Navbar, NavbarDivider, NavbarItem, NavbarSection } from '$lib/components/navbar';
	import Logo from './logo.svelte';
</script>

<Navbar>
	<a href="/" aria-label="Home">
		<Logo class="size-10 sm:size-8" />
	</a>
	<NavbarDivider />
	<NavbarSection>
		<NavbarItem href="/">Home</NavbarItem>
		<NavbarItem href="/events">Events</NavbarItem>
		<NavbarItem href="/orders">Orders</NavbarItem>
	</NavbarSection>
</Navbar>

With dropdown

Use the Dropdown component add a dropdown menu to a navbar by rendering the DropdownButton as a NavbarItem:

<script>
	import { Avatar } from '$lib/components/avatar';
	import {
		Dropdown,
		DropdownButton,
		DropdownDivider,
		DropdownItem,
		DropdownLabel,
		DropdownMenu
	} from '$lib/components/dropdown';
	import {
		Navbar,
		NavbarItem,
		NavbarLabel,
		NavbarSection,
		NavbarSpacer
	} from '$lib/components/navbar';

	import HeroiconsChevronDown16Solid from 'virtual:icons/heroicons/chevron-down-16-solid';
	import HeroiconsCog8Tooth16Solid from 'virtual:icons/heroicons/cog8-tooth-16-solid';
	import HeroiconsPlus16Solid from 'virtual:icons/heroicons/plus-16-solid';

	import HeroiconsInbox20Solid from 'virtual:icons/heroicons/inbox-20-solid';
	import HeroiconsMagnifyingGlass20Solid from 'virtual:icons/heroicons/magnifying-glass-20-solid';
</script>

<Navbar>
	<Dropdown>
		<DropdownButton as={NavbarItem} aria-label="Account menu">
			<Avatar src="/tailwind-logo.svg" />
			<NavbarLabel>Tailwind Labs</NavbarLabel>
			<HeroiconsChevronDown16Solid />
		</DropdownButton>
		<DropdownMenu class="min-w-64" anchor="bottom start">
			<DropdownItem href="/teams/1/settings">
				<HeroiconsCog8Tooth16Solid />
				<DropdownLabel>Settings</DropdownLabel>
			</DropdownItem>
			<DropdownDivider />
			<DropdownItem href="/teams/1">
				<Avatar slot="icon" src="/tailwind-logo.svg" />
				<DropdownLabel>Tailwind Labs</DropdownLabel>
			</DropdownItem>
			<DropdownItem href="/teams/2">
				<Avatar slot="icon" initials="WC" class="bg-purple-500 text-white" />
				<DropdownLabel>Workcation</DropdownLabel>
			</DropdownItem>
			<DropdownDivider />
			<DropdownItem href="/teams/create">
				<HeroiconsPlus16Solid />
				<DropdownLabel>New team&hellip;</DropdownLabel>
			</DropdownItem>
		</DropdownMenu>
	</Dropdown>
	<NavbarSpacer />
	<NavbarSection>
		<NavbarItem href="/search" aria-label="Search">
			<HeroiconsMagnifyingGlass20Solid />
		</NavbarItem>
		<NavbarItem href="/inbox" aria-label="Inbox">
			<HeroiconsInbox20Solid />
		</NavbarItem>
	</NavbarSection>
</Navbar>

See the Dropdown docs for more information on building dropdown menus.

With avatar dropdown

Use the Dropdown component with an Avatar to add an avatar-only dropdown to a navbar:

<script>
	import { Avatar } from '$lib/components/avatar';
	import {
		Dropdown,
		DropdownDivider,
		DropdownItem,
		DropdownLabel,
		DropdownMenu
	} from '$lib/components/dropdown';
	import { Navbar, NavbarItem, NavbarSpacer } from '$lib/components/navbar';
	import HeroiconsArrowRightStartOnRectangle16Solid from 'virtual:icons/heroicons/arrow-right-start-on-rectangle-16-solid';
	import HeroiconsCog8Tooth16Solid from 'virtual:icons/heroicons/cog8-tooth-16-solid';
	import HeroiconsLightBulb16Solid from 'virtual:icons/heroicons/light-bulb-16-solid';
	import HeroiconsShieldCheck16Solid from 'virtual:icons/heroicons/shield-check-16-solid';
	import HeroiconsUser16Solid from 'virtual:icons/heroicons/user-16-solid';

	import Logo from './logo.svelte';
</script>

<Navbar>
	<a href="/" aria-label="Home">
		<Logo class="size-10 sm:size-8" />
	</a>
	<NavbarSpacer />
	<Dropdown>
		<DropdownButton as={NavbarItem} aria-label="Account menu">
			<Avatar src="/profile-photo.jpg" square />
		</DropdownButton>
		<DropdownMenu class="min-w-64" anchor="bottom end">
			<DropdownItem href="/my-profile">
				<HeroiconsUser16Solid />
				<DropdownLabel>My profile</DropdownLabel>
			</DropdownItem>
			<DropdownItem href="/settings">
				<HeroiconsCog8Tooth16Solid />
				<DropdownLabel>Settings</DropdownLabel>
			</DropdownItem>
			<DropdownDivider />
			<DropdownItem href="/privacy-policy">
				<HeroiconsShieldCheck16Solid />
				<DropdownLabel>Privacy policy</DropdownLabel>
			</DropdownItem>
			<DropdownItem href="/share-feedback">
				<HeroiconsLightBulb16Solid />
				<DropdownLabel>Share feedback</DropdownLabel>
			</DropdownItem>
			<DropdownDivider />
			<DropdownItem href="/logout">
				<HeroiconsArrowRightStartOnRectangle16Solid />
				<DropdownLabel>Sign out</DropdownLabel>
			</DropdownItem>
		</DropdownMenu>
	</Dropdown>
</Navbar>

Make sure to provide an aria-label for assistive technology when using avatar-only dropdowns. See the Dropdown docs for more information on how to build a dropdown menu.

With mobile menu

If you'd like to add a mobile menu to a navbar, use the StackedLayout component which includes a navbar and a sidebar for mobile:

<script>
	import { Avatar } from '$lib/components/avatar';
	import {
		Dropdown,
		DropdownButton,
		DropdownDivider,
		DropdownItem,
		DropdownLabel,
		DropdownMenu
	} from '$lib/components/dropdown';
	import {
		Navbar,
		NavbarDivider,
		NavbarItem,
		NavbarLabel,
		NavbarSection,
		NavbarSpacer
	} from '$lib/components/navbar';
	import {
		Sidebar,
		SidebarBody,
		SidebarHeader,
		SidebarItem,
		SidebarLabel,
		SidebarSection
	} from '$lib/components/sidebar';
	import { StackedLayout } from '$lib/components/stacked-layout';

	import HeroiconsArrowRightStartOnRectangle16Solid from 'virtual:icons/heroicons/arrow-right-start-on-rectangle-16-solid';
	import HeroiconsChevronDown16Solid from 'virtual:icons/heroicons/chevron-down-16-solid';
	import HeroiconsCog8Tooth16Solid from 'virtual:icons/heroicons/cog8-tooth-16-solid';
	import HeroiconsLightBulb16Solid from 'virtual:icons/heroicons/light-bulb-16-solid';
	import HeroiconsPlus16Solid from 'virtual:icons/heroicons/plus-16-solid';
	import HeroiconsShieldCheck16Solid from 'virtual:icons/heroicons/shield-check-16-solid';
	import HeroiconsUser16Solid from 'virtual:icons/heroicons/user-16-solid';

	import HeroiconsInbox20Solid from 'virtual:icons/heroicons/inbox-20-solid';
	import HeroiconsMagnifyingGlass20Solid from 'virtual:icons/heroicons/magnifying-glass-20-solid';

	const navItems = [
		{ label: 'Home', url: '/' },
		{ label: 'Events', url: '/events' },
		{ label: 'Orders', url: '/orders' },
		{ label: 'Broadcasts', url: '/broadcasts' },
		{ label: 'Settings', url: '/settings' }
	];
</script>

{#snippet TeamDropdownMenu()}
	<DropdownMenu class="min-w-80 lg:min-w-64" anchor="bottom start">
		<DropdownItem href="/teams/1/settings">
			<HeroiconsCog8Tooth16Solid />
			<DropdownLabel>Settings</DropdownLabel>
		</DropdownItem>
		<DropdownDivider />
		<DropdownItem href="/teams/1">
			<Avatar slot="icon" src="/tailwind-logo.svg" />
			<DropdownLabel>Tailwind Labs</DropdownLabel>
		</DropdownItem>
		<DropdownItem href="/teams/2">
			<Avatar slot="icon" initials="WC" class="bg-purple-500 text-white" />
			<DropdownLabel>Workcation</DropdownLabel>
		</DropdownItem>
		<DropdownDivider />
		<DropdownItem href="/teams/create">
			<HeroiconsPlus16Solid />
			<DropdownLabel>New team&hellip;</DropdownLabel>
		</DropdownItem>
	</DropdownMenu>
{/snippet}

<StackedLayout>
	{#snippet navbar()}
		<Navbar>
			<Dropdown>
				<DropdownButton as={NavbarItem} class="max-lg:hidden">
					<Avatar src="/tailwind-logo.svg" />
					<NavbarLabel>Tailwind Labs</NavbarLabel>
					<HeroiconsChevronDown16Solid />
				</DropdownButton>
				<TeamDropdownMenu />
			</Dropdown>
			<NavbarDivider class="max-lg:hidden" />
			<NavbarSection class="max-lg:hidden">
				{#each navItems as { label, url } (label)}
					<NavbarItem href={url}>
						{label}
					</NavbarItem>
				{/each}
			</NavbarSection>
			<NavbarSpacer />
			<NavbarSection>
				<NavbarItem href="/search" aria-label="Search">
					<HeroiconsMagnifyingGlass20Solid />
				</NavbarItem>
				<NavbarItem href="/inbox" aria-label="Inbox">
					<HeroiconsInbox20Solid />
				</NavbarItem>
				<Dropdown>
					<DropdownButton as={NavbarItem}>
						<Avatar src="/profile-photo.jpg" square />
					</DropdownButton>
					<DropdownMenu class="min-w-64" anchor="bottom end">
						<DropdownItem href="/my-profile">
							<HeroiconsUser16Solid />
							<DropdownLabel>My profile</DropdownLabel>
						</DropdownItem>
						<DropdownItem href="/settings">
							<HeroiconsCog8Tooth16Solid />
							<DropdownLabel>Settings</DropdownLabel>
						</DropdownItem>
						<DropdownDivider />
						<DropdownItem href="/privacy-policy">
							<HeroiconsShieldCheck16Solid />
							<DropdownLabel>Privacy policy</DropdownLabel>
						</DropdownItem>
						<DropdownItem href="/share-feedback">
							<HeroiconsLightBulb16Solid />
							<DropdownLabel>Share feedback</DropdownLabel>
						</DropdownItem>
						<DropdownDivider />
						<DropdownItem href="/logout">
							<HeroiconsArrowRightStartOnRectangle16Solid />
							<DropdownLabel>Sign out</DropdownLabel>
						</DropdownItem>
					</DropdownMenu>
				</Dropdown>
			</NavbarSection>
		</Navbar>
	{/snippet}

	{#snippet sidebar()}
		<Sidebar>
			<SidebarHeader>
				<Dropdown>
					<DropdownButton as={SidebarItem} class="lg:mb-2.5">
						<Avatar src="/tailwind-logo.svg" />
						<SidebarLabel>Tailwind Labs</SidebarLabel>
						<HeroiconsChevronDown16Solid />
					</DropdownButton>
					<TeamDropdownMenu />
				</Dropdown>
			</SidebarHeader>
			<SidebarBody>
				<SidebarSection>
					{#each navItems as { label, url } (label)}
						<SidebarItem href={url}>
							{label}
						</SidebarItem>
					{/each}
				</SidebarSection>
			</SidebarBody>
		</Sidebar>
	{/snippet}

	{@render children?.()}
</StackedLayout>

The Navbar component itself isn't opinionated about how it should be rendered at different breakpoints, which gives you total control over how it should adapt to different viewport sizes.

Hiding items on mobile

Use utility classes like max-lg:hidden to hide certain navbar items at different screen sizes:

<script>
	import { Navbar, NavbarItem, NavbarSection } from '$lib/components/navbar';
	import Logo from './logo.svelte';
</script>

<Navbar>
	<a href="/" aria-label="Home">
		<Logo class="size-10 sm:size-8" />
	</a>
	<NavbarDivider class="max-lg:hidden" />
	<NavbarSection class="max-lg:hidden">
		<NavbarItem href="/">Home</NavbarItem>
		<NavbarItem href="/events">Events</NavbarItem>
		<NavbarItem href="/orders">Orders</NavbarItem>
	</NavbarSection>
</Navbar>