I use tailwind sample template . A Navbar with mobile optimized.
//page.jsx
import Navbar from "./components/Navbar";
export default function Home() {
return (
<>
<Navbar />
</>
);
}
//Navbar.jsx
import { Fragment } from 'react'
import { Disclosure, Menu, Transition } from '@headlessui/react'
import { Bars3Icon, BellIcon, XMarkIcon } from '@heroicons/react/24/outline'
const navigation = [
{ name: 'Dashboard', href: '#', current: true },
{ name: 'Team', href: '#', current: false },
{ name: 'Projects', href: '#', current: false },
{ name: 'Calendar', href: '#', current: false },
]
function classNames(...classes) {
return classes.filter(Boolean).join(' ')
}
export default function Example() {
return (
<Disclosure as="nav" className="bg-gray-800">
{({ open }) => (
<>
<div className="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8">
<div className="relative flex h-16 items-center justify-between">
<div className="absolute inset-y-0 left-0 flex items-center sm:hidden">
{/* Mobile menu button*/}
<Disclosure.Button className="relative inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white">
<span className="absolute -inset-0.5" />
<span className="sr-only">Open main menu</span>
{open ? (
<XMarkIcon className="block h-6 w-6" aria-hidden="true" />
) : (
<Bars3Icon className="block h-6 w-6" aria-hidden="true" />
)}
</Disclosure.Button>
</div>
<div className="flex flex-1 items-center justify-center sm:items-stretch sm:justify-start">
<div className="flex flex-shrink-0 items-center">
<img
className="h-8 w-auto"
src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500"
alt="Your Company"
/>
</div>
<div className="hidden sm:ml-6 sm:block">
<div className="flex space-x-4">
{navigation.map((item) => (
<a
key={item.name}
href={item.href}
className={classNames(
item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
'rounded-md px-3 py-2 text-sm font-medium'
)}
aria-current={item.current ? 'page' : undefined}
>
{item.name}
</a>
))}
</div>
</div>
</div>
<div className="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0">
<button
type="button"
className="relative rounded-full bg-gray-800 p-1 text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800"
>
<span className="absolute -inset-1.5" />
<span className="sr-only">View notifications</span>
<BellIcon className="h-6 w-6" aria-hidden="true" />
</button>
{/* Profile dropdown */}
<Menu as="div" className="relative ml-3">
<div>
<Menu.Button className="relative flex rounded-full bg-gray-800 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800">
<span className="absolute -inset-1.5" />
<span className="sr-only">Open user menu</span>
<img
className="h-8 w-8 rounded-full"
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
alt=""
/>
</Menu.Button>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(active ? 'bg-gray-100' : '', 'block px-4 py-2 text-sm text-gray-700')}
>
Your Profile
</a>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(active ? 'bg-gray-100' : '', 'block px-4 py-2 text-sm text-gray-700')}
>
Settings
</a>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(active ? 'bg-gray-100' : '', 'block px-4 py-2 text-sm text-gray-700')}
>
Sign out
</a>
)}
</Menu.Item>
</Menu.Items>
</Transition>
</Menu>
</div>
</div>
</div>
<Disclosure.Panel className="sm:hidden">
<div className="space-y-1 px-2 pb-3 pt-2">
{navigation.map((item) => (
<Disclosure.Button
key={item.name}
as="a"
href={item.href}
className={classNames(
item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
'block rounded-md px-3 py-2 text-base font-medium'
)}
aria-current={item.current ? 'page' : undefined}
>
{item.name}
</Disclosure.Button>
))}
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
)
}
But gets warning :
Error: Functions are not valid as a child of Client Components. This may happen if you return children instead of from render. Or maybe you meant to call this function rather than return it.
<… as="nav" className=… children={function children}>
^^^^^^^^^^^^^^^^^^^
The code is just fine ,exactly from tailwind official website. It works in next.js 13 , but in 14.2 version . no work.
Does anyone know how to solve this problem? I really need a solution to make a navbar close in mobile small screen . I always use template. I cannot delete the {open} part.
2
Answers
I recently started using NextJS
14.3.0-canary.37
with Tailwind3.4.3
and also encountered this error when adding a navbar from the Tailwind UI components library (https://tailwindui.com/components/application-ui/navigation/navbars) inside my project.Somehow I seemed to solve this error by adding
"use client"
on top of the file where I added the Tailwind UI navbar.layout.tsx
page.tsx
header.tsx
Since I just started using NextJS I don’t understand yet why the above code fixes this error. But since I got it to work and I couldn’t find any answers yet, I thought it was worth sharing.
I hope someone can give feedback on why this error is caused and why it is solved by adding
"use client"
.I’m also curious if there may be a better way to solve this issue.
The issue will be fixed by using "use client" at the top of the Navbar component. Whenever you use any kind of hooks or buttons that related to states, you need to declare it as a client component.
Please let me know if you need any further assistance.