Search code examples
next.jsnext.js14

Functions cannot be passed directly to Client Components


I am using next js 14.0.3, when i passed the icon from server component to client componet its gives my this error

'Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server".'

this is server component

import React from "react";
import { Layout, Compass } from "lucide-react";
import SidebarItem from "./SidebarItem";

const guestRoutes = [
  {
    label: "Home",
    path: "/",
    icon: Layout,
  },
  {
    label: "Browse",
    path: "/search",
    icon: Compass,
  },
];

function SidebarRoutes() {
  const routes = guestRoutes;

  return (
    <div className="flex mt-4 flex-col h-full">
      {routes.map((route) => {
        return (
          <SidebarItem
            key={route.path}
            icon={route.icon}
            label={route.label}
            path={route.path}
          />
        );
      })}
    </div>
  );
}

export default SidebarRoutes;

and this is clinet component

'use client';

import React from "react";
import { LucideIcon } from "lucide-react";
import { usePathname, useRouter } from "next/navigation";

interface SidebarItemProps {
  label: string;
  path: string;
  icon: LucideIcon;
}
const SidebarItem = ({ label, icon: Icon, path }: SidebarItemProps) => {
  const router = useRouter();
  const pathname = usePathname();

  return (
    <Icon/>
  );
};

export default SidebarItem;

anyone know how can i fix it

I have to check the path name for conidional rendering thats why i need to convert this component into client side, I tried but not fixing


Solution

  • I had same issue and I fix it. Solution is:

    1. icon must be string, like this:

      const guestRoutes = [
      

      { label: "Home", path: "/", icon: "Layout", }, { label: "Browse", path: "/search", icon: "Compass", }, ];

    2. You must be create new component like this:

      import * as LuIcon from 'lucide-react';
      

      interface IconCheckProps { icon: string; }

      const IconCheck = ({ icon }: IconCheckProps) => { const IconLibraries = { ...LuIcon }; const IconComponent = IconLibraries[icon as keyof typeof IconLibraries];

      if (!IconComponent) {
          return null;
      }
      
      return <IconComponent />;
      

      };

    export default IconCheck;

    1. you can call like that

      interface SidebarItemProps { label: string; path: string; icon: string; }

      const SidebarItem = ({ label, icon, path }: SidebarItemProps) => { const router = useRouter(); const pathname = usePathname();

      return ( ); };