React Navbar - Flowbite
Use the navbar component to show navigation menu items and links on the top side of your page based on multiple styles and options built with React and Tailwind CSS
The navbar component is an important section of any website as it is the first section that appears on any page and it serves the purpose of allowing your users to navigate throughout your website.
Generally, the navigation bar consists of the logo of your website, a list of menu items for navigation and other secondary elements such as buttons, dropdowns, and a hamburger menu for mobile devices.
All interactivity and options are handled by using React properties and you can customise the appearance of the navbar using the classes from Tailwind CSS.
To start using the navbar component you need to import it from Flowbite React:
'use client';
import { Navbar } from `flowbite-react`;
Table of Contents#
Default navbar#
Use the default navbar component to showcase the logo and a list of menu items with links to other pages of your website by adding the <Navbar.Brand>
and <Navbar.Link>
components inside the <Navbar>
component.
On mobile device the navigation bar will be collapsed and you will be able to use the hamburger menu to toggle the menu items by adding the <Navbar.Toggle>
component.
- React TypeScript
'use client';
import { Navbar } from 'flowbite-react';
export default function DefaultNavbar() {
return (
<Navbar
fluid
rounded
>
<Navbar.Brand
as={{
$$typeof: Symbol(react.forward_ref),
default: '[Circular]',
render: function LinkComponent(props, forwardedRef) {let children;const { href: hrefProp, as: asProp, children: childrenProp, prefetch: prefetchProp = null, passHref, replace, shallow, scroll, locale, onClick, onMouseEnter: onMouseEnterProp, onTouchStart: onTouchStartProp, legacyBehavior = true === false, ...restProps } = props;children = childrenProp;if (legacyBehavior && (typeof children === "string" || typeof children === "number")) {children = /*#__PURE__*/ _react.default.createElement("a", null, children);}const pagesRouter = _react.default.useContext(_routercontext.RouterContext);const appRouter = _react.default.useContext(_approutercontext.AppRouterContext);const router = pagesRouter != null ? pagesRouter : appRouter;// We're in the app directory if there is no pages router.const isAppRouter = !pagesRouter;const prefetchEnabled = prefetchProp !== false;/*** The possible states for prefetch are:* - null: this is the default "auto" mode, where we will prefetch partially if the link is in the viewport* - true: we will prefetch if the link is visible and prefetch the full page, not just partially* - false: we will not prefetch if in the viewport at all*/ const appPrefetchKind = prefetchProp === null ? _routerreducertypes.PrefetchKind.AUTO : _routerreducertypes.PrefetchKind.FULL;if (false) {}if (false) {}const { href, as } = _react.default.useMemo(()=>{if (!pagesRouter) {const resolvedHref = formatStringOrUrl(hrefProp);return {href: resolvedHref,as: asProp ? formatStringOrUrl(asProp) : resolvedHref};}const [resolvedHref, resolvedAs] = (0, _resolvehref.resolveHref)(pagesRouter, hrefProp, true);return {href: resolvedHref,as: asProp ? (0, _resolvehref.resolveHref)(pagesRouter, asProp) : resolvedAs || resolvedHref};}, [pagesRouter,hrefProp,asProp]);const previousHref = _react.default.useRef(href);const previousAs = _react.default.useRef(as);// This will return the first child, if multiple are provided it will throw an errorlet child;if (legacyBehavior) {if (false) {} else {child = _react.default.Children.only(children);}} else {if (false) {}}const childRef = legacyBehavior ? child && typeof child === "object" && child.ref : forwardedRef;const [setIntersectionRef, isVisible, resetVisible] = (0, _useintersection.useIntersection)({rootMargin: "200px"});const setRef = _react.default.useCallback((el)=>{// Before the link getting observed, check if visible state need to be resetif (previousAs.current !== as || previousHref.current !== href) {resetVisible();previousAs.current = as;previousHref.current = href;}setIntersectionRef(el);if (childRef) {if (typeof childRef === "function") childRef(el);else if (typeof childRef === "object") {childRef.current = el;}}}, [as,childRef,href,resetVisible,setIntersectionRef]);// Prefetch the URL if we haven't already and it's visible._react.default.useEffect(()=>{// in dev, we only prefetch on hover to avoid wasting resources as the prefetch will trigger compiling the page.if (false) {}if (!router) {return;}// If we don't need to prefetch the URL, don't do prefetch.if (!isVisible || !prefetchEnabled) {return;}// Prefetch the URL.prefetch(router, href, as, {locale}, {kind: appPrefetchKind}, isAppRouter);}, [as,href,isVisible,locale,prefetchEnabled,pagesRouter == null ? void 0 : pagesRouter.locale,router,isAppRouter,appPrefetchKind]);const childProps = {ref: setRef,onClick (e) {if (false) {}if (!legacyBehavior && typeof onClick === "function") {onClick(e);}if (legacyBehavior && child.props && typeof child.props.onClick === "function") {child.props.onClick(e);}if (!router) {return;}if (e.defaultPrevented) {return;}linkClicked(e, router, href, as, replace, shallow, scroll, locale, isAppRouter, prefetchEnabled);},onMouseEnter (e) {if (!legacyBehavior && typeof onMouseEnterProp === "function") {onMouseEnterProp(e);}if (legacyBehavior && child.props && typeof child.props.onMouseEnter === "function") {child.props.onMouseEnter(e);}if (!router) {return;}if ((!prefetchEnabled || "production" === "development") && isAppRouter) {return;}prefetch(router, href, as, {locale,priority: true,// @see {https://github.com/vercel/next.js/discussions/40268?sort=top#discussioncomment-3572642}bypassPrefetchedCheck: true}, {kind: appPrefetchKind}, isAppRouter);},onTouchStart (e) {if (!legacyBehavior && typeof onTouchStartProp === "function") {onTouchStartProp(e);}if (legacyBehavior && child.props && typeof child.props.onTouchStart === "function") {child.props.onTouchStart(e);}if (!router) {return;}if (!prefetchEnabled && isAppRouter) {return;}prefetch(router, href, as, {locale,priority: true,// @see {https://github.com/vercel/next.js/discussions/40268?sort=top#discussioncomment-3572642}bypassPrefetchedCheck: true}, {kind: appPrefetchKind}, isAppRouter);}};// If child is an <a> tag and doesn't have a href attribute, or if the 'passHref' property is// defined, we specify the current 'href', so that repetition is not needed by the user.// If the url is absolute, we can bypass the logic to prepend the domain and locale.if ((0, _utils.isAbsoluteUrl)(as)) {childProps.href = as;} else if (!legacyBehavior || passHref || child.type === "a" && !("href" in child.props)) {const curLocale = typeof locale !== "undefined" ? locale : pagesRouter == null ? void 0 : pagesRouter.locale;// we only render domain locales if we are currently on a domain locale// so that locale links are still visitable in development/preview envsconst localeDomain = (pagesRouter == null ? void 0 : pagesRouter.isLocaleDomain) && (0, _getdomainlocale.getDomainLocale)(as, curLocale, pagesRouter == null ? void 0 : pagesRouter.locales, pagesRouter == null ? void 0 : pagesRouter.domainLocales);childProps.href = localeDomain || (0, _addbasepath.addBasePath)((0, _addlocale.addLocale)(as, curLocale, pagesRouter == null ? void 0 : pagesRouter.defaultLocale));}return legacyBehavior ? /*#__PURE__*/ _react.default.cloneElement(child, childProps) : /*#__PURE__*/ _react.default.createElement("a", {...restProps,...childProps}, children);}
}}
href="https://flowbite-react.com"
>
<img
alt="Flowbite React Logo"
className="mr-3 h-6 sm:h-9"
src="/favicon.svg"
/>
<span className="self-center whitespace-nowrap text-xl font-semibold dark:text-white">
Flowbite React
</span>
</Navbar.Brand>
<Navbar.Toggle />
<Navbar.Collapse>
<Navbar.Link
active
href="#"
>
<p>
Home
</p>
</Navbar.Link>
<Navbar.Link
as={{
$$typeof: Symbol(react.forward_ref),
default: '[Circular]',
render: function LinkComponent(props, forwardedRef) {let children;const { href: hrefProp, as: asProp, children: childrenProp, prefetch: prefetchProp = null, passHref, replace, shallow, scroll, locale, onClick, onMouseEnter: onMouseEnterProp, onTouchStart: onTouchStartProp, legacyBehavior = true === false, ...restProps } = props;children = childrenProp;if (legacyBehavior && (typeof children === "string" || typeof children === "number")) {children = /*#__PURE__*/ _react.default.createElement("a", null, children);}const pagesRouter = _react.default.useContext(_routercontext.RouterContext);const appRouter = _react.default.useContext(_approutercontext.AppRouterContext);const router = pagesRouter != null ? pagesRouter : appRouter;// We're in the app directory if there is no pages router.const isAppRouter = !pagesRouter;const prefetchEnabled = prefetchProp !== false;/*** The possible states for prefetch are:* - null: this is the default "auto" mode, where we will prefetch partially if the link is in the viewport* - true: we will prefetch if the link is visible and prefetch the full page, not just partially* - false: we will not prefetch if in the viewport at all*/ const appPrefetchKind = prefetchProp === null ? _routerreducertypes.PrefetchKind.AUTO : _routerreducertypes.PrefetchKind.FULL;if (false) {}if (false) {}const { href, as } = _react.default.useMemo(()=>{if (!pagesRouter) {const resolvedHref = formatStringOrUrl(hrefProp);return {href: resolvedHref,as: asProp ? formatStringOrUrl(asProp) : resolvedHref};}const [resolvedHref, resolvedAs] = (0, _resolvehref.resolveHref)(pagesRouter, hrefProp, true);return {href: resolvedHref,as: asProp ? (0, _resolvehref.resolveHref)(pagesRouter, asProp) : resolvedAs || resolvedHref};}, [pagesRouter,hrefProp,asProp]);const previousHref = _react.default.useRef(href);const previousAs = _react.default.useRef(as);// This will return the first child, if multiple are provided it will throw an errorlet child;if (legacyBehavior) {if (false) {} else {child = _react.default.Children.only(children);}} else {if (false) {}}const childRef = legacyBehavior ? child && typeof child === "object" && child.ref : forwardedRef;const [setIntersectionRef, isVisible, resetVisible] = (0, _useintersection.useIntersection)({rootMargin: "200px"});const setRef = _react.default.useCallback((el)=>{// Before the link getting observed, check if visible state need to be resetif (previousAs.current !== as || previousHref.current !== href) {resetVisible();previousAs.current = as;previousHref.current = href;}setIntersectionRef(el);if (childRef) {if (typeof childRef === "function") childRef(el);else if (typeof childRef === "object") {childRef.current = el;}}}, [as,childRef,href,resetVisible,setIntersectionRef]);// Prefetch the URL if we haven't already and it's visible._react.default.useEffect(()=>{// in dev, we only prefetch on hover to avoid wasting resources as the prefetch will trigger compiling the page.if (false) {}if (!router) {return;}// If we don't need to prefetch the URL, don't do prefetch.if (!isVisible || !prefetchEnabled) {return;}// Prefetch the URL.prefetch(router, href, as, {locale}, {kind: appPrefetchKind}, isAppRouter);}, [as,href,isVisible,locale,prefetchEnabled,pagesRouter == null ? void 0 : pagesRouter.locale,router,isAppRouter,appPrefetchKind]);const childProps = {ref: setRef,onClick (e) {if (false) {}if (!legacyBehavior && typeof onClick === "function") {onClick(e);}if (legacyBehavior && child.props && typeof child.props.onClick === "function") {child.props.onClick(e);}if (!router) {return;}if (e.defaultPrevented) {return;}linkClicked(e, router, href, as, replace, shallow, scroll, locale, isAppRouter, prefetchEnabled);},onMouseEnter (e) {if (!legacyBehavior && typeof onMouseEnterProp === "function") {onMouseEnterProp(e);}if (legacyBehavior && child.props && typeof child.props.onMouseEnter === "function") {child.props.onMouseEnter(e);}if (!router) {return;}if ((!prefetchEnabled || "production" === "development") && isAppRouter) {return;}prefetch(router, href, as, {locale,priority: true,// @see {https://github.com/vercel/next.js/discussions/40268?sort=top#discussioncomment-3572642}bypassPrefetchedCheck: true}, {kind: appPrefetchKind}, isAppRouter);},onTouchStart (e) {if (!legacyBehavior && typeof onTouchStartProp === "function") {onTouchStartProp(e);}if (legacyBehavior && child.props && typeof child.props.onTouchStart === "function") {child.props.onTouchStart(e);}if (!router) {return;}if (!prefetchEnabled && isAppRouter) {return;}prefetch(router, href, as, {locale,priority: true,// @see {https://github.com/vercel/next.js/discussions/40268?sort=top#discussioncomment-3572642}bypassPrefetchedCheck: true}, {kind: appPrefetchKind}, isAppRouter);}};// If child is an <a> tag and doesn't have a href attribute, or if the 'passHref' property is// defined, we specify the current 'href', so that repetition is not needed by the user.// If the url is absolute, we can bypass the logic to prepend the domain and locale.if ((0, _utils.isAbsoluteUrl)(as)) {childProps.href = as;} else if (!legacyBehavior || passHref || child.type === "a" && !("href" in child.props)) {const curLocale = typeof locale !== "undefined" ? locale : pagesRouter == null ? void 0 : pagesRouter.locale;// we only render domain locales if we are currently on a domain locale// so that locale links are still visitable in development/preview envsconst localeDomain = (pagesRouter == null ? void 0 : pagesRouter.isLocaleDomain) && (0, _getdomainlocale.getDomainLocale)(as, curLocale, pagesRouter == null ? void 0 : pagesRouter.locales, pagesRouter == null ? void 0 : pagesRouter.domainLocales);childProps.href = localeDomain || (0, _addbasepath.addBasePath)((0, _addlocale.addLocale)(as, curLocale, pagesRouter == null ? void 0 : pagesRouter.defaultLocale));}return legacyBehavior ? /*#__PURE__*/ _react.default.cloneElement(child, childProps) : /*#__PURE__*/ _react.default.createElement("a", {...restProps,...childProps}, children);}
}}
href="#"
>
<p>
About
</p>
</Navbar.Link>
<Navbar.Link href="#">
Services
</Navbar.Link>
<Navbar.Link href="#">
Pricing
</Navbar.Link>
<Navbar.Link href="#">
Contact
</Navbar.Link>
</Navbar.Collapse>
</Navbar>
)
}
Navbar with CTA button#
Use this example to show a CTA button inside the navbar component for marketing advantages and to increase the conversion rate of your website.
- React TypeScript
'use client';
import { Button, Navbar } from 'flowbite-react';
export default function NavbarWithCTAButton() {
return (
<Navbar
fluid
rounded
>
<Navbar.Brand href="https://flowbite-react.com">
<img
alt="Flowbite React Logo"
className="mr-3 h-6 sm:h-9"
src="/favicon.svg"
/>
<span className="self-center whitespace-nowrap text-xl font-semibold dark:text-white">
Flowbite React
</span>
</Navbar.Brand>
<div className="flex md:order-2">
<Button>
Get started
</Button>
<Navbar.Toggle />
</div>
<Navbar.Collapse>
<Navbar.Link
active
href="#"
>
<p>
Home
</p>
</Navbar.Link>
<Navbar.Link href="#">
About
</Navbar.Link>
<Navbar.Link href="#">
Services
</Navbar.Link>
<Navbar.Link href="#">
Pricing
</Navbar.Link>
<Navbar.Link href="#">
Contact
</Navbar.Link>
</Navbar.Collapse>
</Navbar>
)
}
Navbar with dropdown#
Use this example to feature a dropdown menu when clicking on the user avatar inside the navbar by importing the <Avatar>
and <Dropdown>
components.
- React TypeScript
'use client';
import { Dropdown, Navbar } from 'flowbite-react';
export default function NavbarWithDropdown() {
return (
<Navbar
fluid
rounded
>
<Navbar.Brand href="https://flowbite-react.com">
<img
alt="Flowbite React Logo"
className="mr-3 h-6 sm:h-9"
src="/favicon.svg"
/>
<span className="self-center whitespace-nowrap text-xl font-semibold dark:text-white">
Flowbite React
</span>
</Navbar.Brand>
<div className="flex md:order-2">
<Dropdown
arrowIcon={false}
inline
label={<Avatar alt="User settings" img="https://flowbite.com/docs/images/people/profile-picture-5.jpg" rounded/>}
>
<Dropdown.Header>
<span className="block text-sm">
Bonnie Green
</span>
<span className="block truncate text-sm font-medium">
name@flowbite.com
</span>
</Dropdown.Header>
<DropdownItem>
Dashboard
</DropdownItem>
<DropdownItem>
Settings
</DropdownItem>
<DropdownItem>
Earnings
</DropdownItem>
<Dropdown.Divider />
<DropdownItem>
Sign out
</DropdownItem>
</Dropdown>
<Navbar.Toggle />
</div>
<Navbar.Collapse>
<Navbar.Link
active
href="#"
>
<p>
Home
</p>
</Navbar.Link>
<Navbar.Link href="#">
About
</Navbar.Link>
<Navbar.Link href="#">
Services
</Navbar.Link>
<Navbar.Link href="#">
Pricing
</Navbar.Link>
<Navbar.Link href="#">
Contact
</Navbar.Link>
</Navbar.Collapse>
</Navbar>
)
}
Theme#
To learn more about how to customize the appearance of components, please see the Theme docs.
{
"root": {
"base": "bg-white px-2 py-2.5 dark:border-gray-700 dark:bg-gray-800 sm:px-4",
"rounded": {
"on": "rounded",
"off": ""
},
"bordered": {
"on": "border",
"off": ""
},
"inner": {
"base": "mx-auto flex flex-wrap items-center justify-between",
"fluid": {
"on": "",
"off": "container"
}
}
},
"brand": {
"base": "flex items-center"
},
"collapse": {
"base": "w-full md:block md:w-auto",
"list": "mt-4 flex flex-col md:mt-0 md:flex-row md:space-x-8 md:text-sm md:font-medium",
"hidden": {
"on": "hidden",
"off": ""
}
},
"link": {
"base": "block py-2 pr-4 pl-3 md:p-0",
"active": {
"on": "bg-cyan-700 text-white dark:text-white md:bg-transparent md:text-cyan-700",
"off": "border-b border-gray-100 text-gray-700 hover:bg-gray-50 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white md:border-0 md:hover:bg-transparent md:hover:text-cyan-700 md:dark:hover:bg-transparent md:dark:hover:text-white"
},
"disabled": {
"on": "text-gray-400 hover:cursor-not-allowed dark:text-gray-600",
"off": ""
}
},
"toggle": {
"base": "inline-flex items-center rounded-lg p-2 text-sm text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600 md:hidden",
"icon": "h-6 w-6 shrink-0"
}
}