IntegrationsFumadocs

Add Search Bar to Fumadocs

Enhance your Fumadocs documentation with Inkeep's intelligent search bar for fast, accurate content discovery and improved user experience.

What is Fumadocs

Fumadocs is an open source documentation framework, powered by Next.js App Router.

Get an API key

Follow these steps to create an API key for your web integration.

Option 1: Replace the built-in search dialog with Inkeep

This method allows you to replace the default Search Dialog with Inkeep, see here for more information.

Note
Note

You will need to replace REPLACE_WITH_YOUR_INKEEP_API_KEY with your actual Inkeep API key in the code below.

Create a search.tsx client component in your components directory.

components/search.tsx
'use client';
 
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
import { InkeepModalSearchAndChat, type InkeepModalSearchAndChatProps } from "@inkeep/cxkit-react";
import { useEffect, useState } from "react";
 
 
export default function CustomDialog(props: SharedProps) {
    const [syncTarget, setSyncTarget] = useState<HTMLElement | null> (null);
    const { open, onOpenChange } = props;
    // We do this because document is not available in the server
    useEffect(() => {
      setSyncTarget(document.documentElement);
    }, []);
 
    const config: InkeepModalSearchAndChatProps = {
      baseSettings: {
        apiKey: "REPLACE_WITH_YOUR_INKEEP_API_KEY", // required
        primaryBrandColor: "#26D6FF", // your brand color, widget color scheme is derived from this
        organizationDisplayName: "Inkeep",
        // ...optional settings
        colorMode: {
          sync: {
            target: syncTarget,
            attributes: ["class"],
            isDarkMode: (attributes) => !!attributes.class?.includes("dark"),
          },
        },
      },
      modalSettings: {
        isOpen: open,
        onOpenChange,
        // optional settings
      },
      searchSettings: {
        // optional settings
      },
      aiChatSettings: {
        // optional settings
        aiAssistantAvatar: "https://mydomain.com/mylogo", // use your own AI assistant avatar
        exampleQuestions: [
          "Example question 1?",
          "Example question 2?",
          "Example question 3?",
        ],
      },
    };
  return <InkeepModalSearchAndChat {...config} />;
}

To pass it to the Root Provider, you need a wrapper with use client directive. Create a provider.tsx file.

provider.tsx
'use client';
import { RootProvider } from 'fumadocs-ui/provider';
import dynamic from 'next/dynamic';
import type { ReactNode } from 'react';
 
const SearchDialog = dynamic(() => import('@/components/search')); // lazy load
 
export function Provider({ children }: { children: ReactNode }) {
  return (
    <RootProvider
      search={{
        SearchDialog,
      }}
    >
      {children}
    </RootProvider>
  );
}

Use it instead of your previous Root Provider in your root layout.tsx file.

layout.tsx
import { Provider } from './provider';
import type { ReactNode } from 'react';
 
export default function Layout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Provider>{children}</Provider>
      </body>
    </html>
  );
}

Option 2: Add the SearchBar to a custom nav or sidebar component

Use this option if you have created a custom nav or sidebar component.

Note
Note

You will need to replace REPLACE_WITH_YOUR_INKEEP_API_KEY with your actual Inkeep API key in the code below.

Create a searchbar.tsx client component in your Fumadocs project.

searchbar.tsx
"use client";
 
import { useEffect, useState } from "react";
import { InkeepSearchBar } from "@inkeep/cxkit-react";
 
export function SearchBar() {
  // color mode sync target
  const [syncTarget, setSyncTarget] = (useState < HTMLElement) | (null > null);
 
  // We do this because document is not available in the server
  useEffect(() => {
    setSyncTarget(document.documentElement);
  }, []);
 
  const config = {
    baseSettings: {
      apiKey: "REPLACE_WITH_YOUR_INKEEP_API_KEY", // required - replace with your own API key
      primaryBrandColor: "#26D6FF", // your brand color, widget color scheme is derived from this
      organizationDisplayName: "Inkeep",
      // ...optional settings
      colorMode: {
        sync: {
          target: syncTarget,
          attributes: ["class"],
          isDarkMode: (attributes) => !!attributes.class?.includes("dark"),
        },
      },
    },
    modalSettings: {
      // optional settings
    },
    searchSettings: {
      // optional settings
    },
    aiChatSettings: {
      // optional settings
      aiAssistantAvatar: "https://mydomain.com/mylogo", // use your own AI assistant avatar
      exampleQuestions: [
        "Example question 1?",
        "Example question 2?",
        "Example question 3?",
      ],
    },
  };
 
  return <InkeepSearchBar {...config} />;
}

Then import it into your navbar or sidebar component.

navbar.tsx
import { SearchBar } from "./searchbar";
 
export const Navbar = () => {
  return (
    <div>
      {/*  ...rest of your navbar */}
      <SearchBar />
    </div>
  );
};

For a full list of customizations, check out the Search Bar documentation.

On this page