Search

Search documentation

Documentation Framework Guide

Understanding the Evolphin UI documentation framework - architecture, configuration, and how to contribute.

This page explains how the Evolphin UI documentation framework is built, how its parts fit together, and how you can extend or contribute to it.

Overview

Evolphin UI uses Fumadocs as its documentation engine, built on top of Next.js 16+ with MDX support. The framework provides:

  • πŸ“ MDX-based content with live component previews
  • πŸ” Full-text search powered by Orama
  • 🎨 Custom theming with dark/light mode
  • 🧩 Registry components from shadcn/ui
  • πŸ’‘ TypeScript Twoslash for type annotations

Project Structure

Project Structure
evolphin-ui
contentDocumentation content
docsAll doc pages (.mdx)
registryUI component library
default/uiAll components
src
appNext.js routes
componentsCustom components
libUtilities & config
source.config.tsFumadocs MDX config
mdx-components.tsxGlobal MDX components
next.config.mtsNext.js configuration

Key Configuration Files

source.config.ts

This file configures how Fumadocs processes your MDX content. It defines:

  • Content directory (content/docs)
  • Code highlighting with Shiki themes
  • Twoslash for TypeScript annotations
import { defineDocs, defineConfig } from 'fumadocs-mdx/config';
import { transformerTwoslash } from 'fumadocs-twoslash';

export const docs = defineDocs({
  dir: 'content/docs',
});

export default defineConfig({
  mdxOptions: {
    rehypeCodeOptions: {
      themes: { light: 'github-light', dark: 'github-dark' },
      transformers: [..., transformerTwoslash({ explicitTrigger: true })],
    },
  },
});

mdx-components.tsx

Registers components available in all MDX files. Any component added here can be used without imports.

import { ComponentPreview } from "./registry/default/ui/component-preview";
import { FileTree } from "./registry/default/ui/file-tree";

export function getMDXComponents() {
  return {
    ...defaultMdxComponents,
    ComponentPreview,
    FileTree,
  };
}

src/lib/layout.shared.tsx

Shared layout configuration for the documentation. Here you can customize the navbar.

import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
import { Header } from "@/components/docs/header";

export function baseOptions(): BaseLayoutProps {
  return {
    nav: {
      component: <Header />, // Custom navbar
    },
  };
}

Custom Components

Header Component

Located at src/components/docs/header.tsx. A shared header used on both the homepage and documentation pages.

Features:

  • Logo and navigation links
  • Search button (triggers Ctrl+K)
  • Theme toggle
  • GitHub link
ComponentLocationPurpose
SidebarBannersrc/components/docs/sidebar-banner.tsxLogo and branding at top
SidebarFootersrc/components/docs/sidebar-footer.tsxFooter with links

ComponentPreview

Located at registry/default/ui/component-preview.tsx. Displays live component previews with code tabs.

<ComponentPreview code={`<Button>Click me</Button>`}>
  <Button>Click me</Button>
</ComponentPreview>

Adding New Documentation Pages

1. Create an MDX file

Add a new .mdx file in content/docs/:

content/docs/
β”œβ”€β”€ getting-started.mdx    # /docs/getting-started
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ button.mdx         # /docs/components/button
β”‚   └── card.mdx           # /docs/components/card

2. Add frontmatter

Every page needs a title and description:

---
title: Getting Started
description: Learn how to set up Evolphin UI
---

Your content here...

3. Update meta.json (optional)

Control page order in the sidebar:

{
  "pages": ["index", "getting-started", "components"]
}

Adding New Components to Registry

1. Create the component

Add your component in registry/default/ui/:

// registry/default/ui/my-component.tsx
export function MyComponent({ children }) {
  return <div className="...">{children}</div>;
}

2. Register for MDX (optional)

If you want to use it in MDX without imports, add to mdx-components.tsx:

import { MyComponent } from "./registry/default/ui/my-component";

export function getMDXComponents() {
  return {
    ...defaultMdxComponents,
    MyComponent, // Now available in all MDX files
  };
}

Configuring the Sidebar

The sidebar is configured in src/app/docs/layout.tsx:

<DocsLayout
  {...baseOptions()}
  tree={source.pageTree}
  sidebar={{
    collapsible: false,      // Disable folder collapse
    tabs: false,             // Disable tab dropdown
    defaultOpenLevel: 10,    // All folders open
    banner: <SidebarBanner />,
    footer: <SidebarFooter />,
  }}
  themeSwitch={{ enabled: false }}
  searchToggle={{ enabled: false }}
>

Search Configuration

Search is powered by Orama and requires an API route.

API Route

Located at src/app/api/search/route.ts:

import { source } from "@/lib/source";
import { createSearchAPI } from "fumadocs-core/search/server";

export const { GET } = createSearchAPI("advanced", {
  indexes: source.getPages().map((page) => ({
    title: page.data.title,
    description: page.data.description,
    url: page.url,
    id: page.url,
    structuredData: page.data.structuredData,
  })),
});

The search dialog opens with Ctrl+K or ⌘K and is customized in src/components/search-dialog.tsx.


Styling

Global Styles

Located at src/app/globals.css. Key customizations:

/* Fumadocs imports */
@import "fumadocs-ui/css/neutral.css";
@import "fumadocs-ui/css/preset.css";
@import "fumadocs-twoslash/twoslash.css";

/* Custom navbar height */
:root {
  --fd-nav-height: 56px !important;
}

/* Sidebar background */
#nd-sidebar {
  background-color: hsl(var(--muted) / 0.3);
}

Contributing

Guidelines

  1. Use registry components - Import from @/registry/default/ui/
  2. Follow naming conventions - kebab-case for files, PascalCase for components
  3. Add frontmatter - Every MDX page needs title and description
  4. Test locally - Run pnpm dev before committing

Quick Commands

bash pnpm dev
bash pnpm build
bash pnpm lint

Resources

On this page