Ask0 logoAsk0
Integrations

Fumadocs Integration

Add AI search and chat to your Fumadocs documentation. Integrate Ask0 with Fumadocs using React components or script tags.

Add Ask0 AI assistant to your Fumadocs documentation site to help users find information instantly.

Quick Setup

Get Your Project ID

Sign in to Ask0 and copy your project ID from the dashboard.

Add Script to Root Layout

In your Fumadocs project, add the Ask0 script to your root layout:

app/layout.tsx
import Script from 'next/script';

export default function RootLayout({
  children
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        {children}
        <Script
          id="ask0-widget"
          src="https://assets.ask0.ai/scripts/ask.js"
          strategy="afterInteractive"
          data-project-id="YOUR_PROJECT_ID"
        />
      </body>
    </html>
  );
}

Configure Widget (Optional)

Add configuration options:

<Script
  id="ask0-widget"
  src="https://assets.ask0.ai/scripts/ask.js"
  strategy="afterInteractive"
  data-project-id="YOUR_PROJECT_ID"
  data-position="bottom-right"
  data-theme="auto"
  data-primary-color="#6366f1"
  data-greeting="Need help finding something in the docs?"
/>

Advanced Integration

Custom Component

Create a custom Ask0 component for more control:

components/ask0-widget.tsx
'use client';

import { useEffect } from 'react';
import { useTheme } from 'next-themes';

export function Ask0Widget() {
  const { theme } = useTheme();

  useEffect(() => {
    // Load Ask0 script
    const script = document.createElement('script');
    script.src = 'https://assets.ask0.ai/scripts/ask.js';
    script.async = true;
    script.dataset.projectId = process.env.NEXT_PUBLIC_ASK0_PROJECT_ID!;
    script.dataset.theme = theme === 'dark' ? 'dark' : 'light';
    script.dataset.position = 'bottom-right';

    document.body.appendChild(script);

    return () => {
      // Cleanup
      document.body.removeChild(script);
      if (window.ask0) {
        window.ask0.destroy();
      }
    };
  }, [theme]);

  return null;
}

Use in your layout:

app/layout.tsx
import { Ask0Widget } from '@/components/ask0-widget';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Ask0Widget />
      </body>
    </html>
  );
}

Theme Synchronization

Sync Ask0 with Fumadocs theme:

components/ask0-theme-sync.tsx
'use client';

import { useEffect } from 'react';
import { useTheme } from 'fumadocs-ui/provider';

export function Ask0ThemeSync() {
  const { theme } = useTheme();

  useEffect(() => {
    if (window.ask0) {
      // Sync theme
      window.ask0.setTheme(theme);

      // Sync colors from Fumadocs
      const styles = getComputedStyle(document.documentElement);
      const primaryColor = styles.getPropertyValue('--primary');

      window.ask0.setColors({
        primary: `hsl(${primaryColor})`,
      });
    }
  }, [theme]);

  return null;
}

Configuration Options

Widget Positioning

Position the widget to avoid conflicts with Fumadocs UI:

// Avoid collision with Fumadocs sidebar
window.ask0.config = {
  position: 'bottom-right',
  offset: {
    bottom: '20px',
    right: '20px',  // Ensure it doesn't overlap TOC
  }
};

Search Integration

Replace or complement Fumadocs search:

// Option 1: Replace default search
export function SearchToggle() {
  return (
    <button
      onClick={() => window.ask0.open()}
      className="flex items-center gap-2"
    >
      <Search className="w-4 h-4" />
      <span>Search</span>
      <kbd className="text-xs">⌘K</kbd>
    </button>
  );
}

// Option 2: Add as additional option
export function DocsSearch() {
  return (
    <div className="flex gap-2">
      <FumadocsSearch />
      <button
        onClick={() => window.ask0.open()}
        className="px-3 py-1 rounded-md bg-primary/10"
      >
        Ask AI
      </button>
    </div>
  );
}

Custom Trigger

Add a custom trigger button:

export function AskAIButton() {
  return (
    <button
      onClick={() => window.ask0.toggle()}
      className="fixed bottom-20 right-6 z-50 flex items-center gap-2
                 px-4 py-2 bg-primary text-primary-foreground
                 rounded-full shadow-lg hover:shadow-xl transition-shadow"
    >
      <Sparkles className="w-4 h-4" />
      Ask AI
    </button>
  );
}

Content Indexing

Configure Ask0 Sources

  1. Add Documentation URL

    • In Ask0 dashboard, add your docs URL
    • Example: https://docs.yoursite.com
  2. Set Crawl Patterns

    Include:
      - https://docs.yoursite.com/**
    Exclude:
      - **/api/raw/**
      - **/changelog/**
  3. Optimize for Fumadocs Structure

    • Ask0 automatically detects Fumadocs structure
    • Indexes page hierarchy and navigation

Best Practices

Fumadocs Integration Tips:

  1. Place widget to avoid UI conflicts
  2. Sync theme with Fumadocs theme system
  3. Consider replacing or augmenting search
  4. Index all documentation pages
  5. Test on mobile layouts
  6. Use environment variables for project ID

Performance

Optimize loading:

// Lazy load Ask0 on user interaction
export function LazyAsk0() {
  const [loaded, setLoaded] = useState(false);

  const loadWidget = () => {
    if (!loaded) {
      const script = document.createElement('script');
      script.src = 'https://assets.ask0.ai/scripts/ask.js';
      script.dataset.projectId = 'YOUR_PROJECT_ID';
      document.body.appendChild(script);
      setLoaded(true);
    }
  };

  return (
    <button onClick={loadWidget}>
      Need help? Ask AI
    </button>
  );
}

Styling

Match Fumadocs design:

/* Custom styles for Ask0 in Fumadocs */
.ask0-widget {
  --ask0-font-sans: var(--font-sans);
  --ask0-radius: var(--radius);
}

/* Match Fumadocs colors */
[data-theme="light"] .ask0-widget {
  --ask0-primary: hsl(var(--primary));
  --ask0-background: hsl(var(--background));
  --ask0-foreground: hsl(var(--foreground));
}

[data-theme="dark"] .ask0-widget {
  --ask0-primary: hsl(var(--primary));
  --ask0-background: hsl(var(--background));
  --ask0-foreground: hsl(var(--foreground));
}

TypeScript Support

Add type definitions:

types/ask0.d.ts
interface Ask0Widget {
  open: () => void;
  close: () => void;
  toggle: () => void;
  setTheme: (theme: 'light' | 'dark' | 'auto') => void;
  setLanguage: (lang: string) => void;
  identify: (user: {
    id: string;
    email?: string;
    name?: string;
  }) => void;
  on: (event: string, callback: Function) => void;
}

declare global {
  interface Window {
    ask0: Ask0Widget;
  }
}

Environment Variables

Configure in .env.local:

NEXT_PUBLIC_ASK0_PROJECT_ID=your_project_id
NEXT_PUBLIC_ASK0_POSITION=bottom-right
NEXT_PUBLIC_ASK0_THEME=auto

Use in your code:

<Script
  src="https://assets.ask0.ai/scripts/ask.js"
  data-project-id={process.env.NEXT_PUBLIC_ASK0_PROJECT_ID}
  data-position={process.env.NEXT_PUBLIC_ASK0_POSITION}
  data-theme={process.env.NEXT_PUBLIC_ASK0_THEME}
/>

Troubleshooting

Common Issues:

Widget not appearing

  • Check if project ID is correct
  • Verify script is loading (check Network tab)
  • Ensure no Content Security Policy blocks

Theme not syncing

  • Make sure to call ask0.setTheme() after widget loads
  • Listen for theme changes in Fumadocs

Position conflicts

  • Adjust offset values
  • Consider mobile responsiveness
  • Check z-index values

Example Implementation

Complete example for Fumadocs:

app/layout.tsx
import './global.css';
import { RootProvider } from 'fumadocs-ui/provider';
import { Inter } from 'next/font/google';
import type { ReactNode } from 'react';
import Script from 'next/script';

const inter = Inter({
  subsets: ['latin'],
});

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <html lang="en" className={inter.className} suppressHydrationWarning>
      <body>
        <RootProvider>
          {children}
        </RootProvider>

        {/* Ask0 Widget */}
        <Script
          id="ask0-widget"
          src="https://assets.ask0.ai/scripts/ask.js"
          strategy="afterInteractive"
          data-project-id={process.env.NEXT_PUBLIC_ASK0_PROJECT_ID}
          data-position="bottom-right"
          data-theme="auto"
          data-greeting="👋 Need help navigating the docs?"
          data-placeholder="Ask me anything about our documentation..."
        />
      </body>
    </html>
  );
}

Next Steps