rebrand: complete white-label — all packages @hanzo/docs-* (one brand)

Finish the fumadocs→Hanzo Docs rebrand: rename the remaining fuma-named
workspace packages and every reference so the framework is uniformly
@hanzo/docs-*. One brand, no Fuma in package names or product surface.

Package renames (name field + all refs: deps, imports, CSS @import,
configs, .changeset, next/vite build config):
  fumadocs-core        → @hanzo/docs-core
  fumadocs-mdx         → @hanzo/docs-mdx
  fumadocs-ui          → @hanzo/docs-ui          (packages/radix-ui)
  fumadocs-openapi     → @hanzo/docs-openapi
  fumadocs-preview     → @hanzo/docs-preview
  @fumadocs/base-ui    → @hanzo/docs-base-ui
  @fumadocs/basehub    → @hanzo/docs-basehub
  @fumadocs/language   → @hanzo/docs-language
  @fumadocs/local-md   → @hanzo/docs-local-md
  @fumadocs/sanity     → @hanzo/docs-sanity
  @fumadocs/shadcn     → @hanzo/docs-shadcn
  @fumadocs/vite       → @hanzo/docs-vite
  @fumari/stf          → @hanzo/docs-stf
  create-fumadocs-app  → @hanzo/create-docs
  create-fumadocs-versions → @hanzo/docs-create-versions

Stale @fumadocs/{cli,story,tailwind,mdx-remote,...} references collapsed to
their existing @hanzo/docs-* canonical packages (no dup created).

De-branded product strings: Fumadocs/Fuma prose → Hanzo Docs/Hanzo; site
branding, CLI output, doc copy, AI-assistant name, metadata. URLs
fumadocs.dev → docs.hanzo.ai, repo fuma-nama/fumadocs → hanzoai/docs.
Filesystem renames: packages/python/fumapy → hanzodocs_py, preview config,
what-is-fumadocs.mdx → what-is-hanzo-docs.mdx, api/fumadocs-ui route.

KEPT (real external npm deps / attribution — NOT renamed):
  fuma-cli, fuma-content, @fumari/json-schema-ts (published upstream pkgs),
  typesense-/trieve-fumadocs-adapter (3rd-party search adapters),
  LICENSE "Copyright (c) 2023 Fuma" (OSS attribution, all 7 LICENSE files
  untouched), CHANGELOG.md history (accurate release records, left as-is).

Build: node 24, pnpm install clean; all 4 target apps next build GREEN
(spec, gui-docs, zen-docs, base-docs) + full package closure (18/18 turbo).
Gate: zero @hanzo-package fumadocs-/@fumadocs/ references remain.
This commit is contained in:
zeekay
2026-06-24 23:21:42 -07:00
parent 7c54921cb3
commit 1de9961289
1036 changed files with 3442 additions and 3422 deletions
+2 -2
View File
@@ -3,8 +3,8 @@
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [
["fumadocs-core", "fumadocs-ui", "@fumadocs/base-ui"],
["create-fumadocs-app"]
["@hanzo/docs-core", "@hanzo/docs-ui", "@hanzo/docs-base-ui"],
["@hanzo/create-docs"]
],
"access": "public",
"baseBranch": "main",
+3 -3
View File
@@ -1,17 +1,17 @@
---
name: radix-base-ui-sync
description: Keep packages/radix-ui (fumadocs-ui) and packages/base-ui in sync. Use when editing either package, adding features, or fixing bugs so both UI variants stay consistent.
description: Keep packages/radix-ui (@hanzo/docs-ui) and packages/base-ui in sync. Use when editing either package, adding features, or fixing bugs so both UI variants stay consistent.
---
# Radix UI vs Base UI Package Sync
`packages/radix-ui` (fumadocs-ui) and `packages/base-ui` (@fumadocs/base-ui) are two variants of Fumadocs UI. They share the same layout structure, components, and public API; only the underlying primitives differ. When changing one package, consider the other.
`packages/radix-ui` (@hanzo/docs-ui) and `packages/base-ui` (@hanzo/docs-base-ui) are two variants of Hanzo Docs UI. They share the same layout structure, components, and public API; only the underlying primitives differ. When changing one package, consider the other.
## Package identity
| | radix-ui | base-ui |
| ---------------- | ----------------------- | ---------------------- |
| **Package name** | `fumadocs-ui` | `@fumadocs/base-ui` |
| **Package name** | `@hanzo/docs-ui` | `@hanzo/docs-base-ui` |
| **Primitives** | `@radix-ui/*` | `@base-ui/react` |
| **Config key** | `uiLibrary: 'radix-ui'` | `uiLibrary: 'base-ui'` |
+48 -32
View File
@@ -1,12 +1,12 @@
# LLM.md - Hanzo Docs Framework
Fork of [fumadocs](https://github.com/fuma-nama/fumadocs) with all packages renamed to `@hanzo/docs-*` namespace.
Fork of [Hanzo Docs](https://github.com/hanzoai/docs) with all packages renamed to `@hanzo/docs-*` namespace.
## Branch Convention
- **`main`** — Production branch. CF Pages deploys docs.hanzo.ai from here. All Hanzo work lands here.
- **`dev`** — Tracks upstream `fumadocs/dev`. Used for upstream sync merges only.
- **`upstream`** remote — points to `fuma-nama/fumadocs`
- **`dev`** — Tracks upstream `Hanzo Docs/dev`. Used for upstream sync merges only.
- **`upstream`** remote — points to `hanzoai/docs`
## Architecture
@@ -38,7 +38,7 @@ pnpm workspace monorepo with turbo. Two apps, 24 packages, 24 examples.
│ ├── create-app/ # @hanzo/docs-create-app - project scaffolding
│ ├── create-app-versions/ # version tracking for create-app
│ ├── shared/ # shared utilities
│ ├── stf/ # @fumari/stf (upstream dependency)
│ ├── stf/ # @hanzo/docs-stf (upstream dependency)
│ ├── mdx-runtime/ # @hanzo/mdx-runtime
│ ├── eslint-config-custom/ # shared ESLint config
│ └── tsconfig/ # shared TypeScript config
@@ -47,26 +47,50 @@ pnpm workspace monorepo with turbo. Two apps, 24 packages, 24 examples.
## Package Naming Convention
All upstream `fumadocs-*` and `@fumadocs/*` packages are renamed:
One brand: every workspace package publishes under `@hanzo/docs-*`. The
rename rule (applied when merging from the upstream fork) drops the upstream
prefix and re-scopes to `@hanzo/docs-`:
| Upstream | Hanzo Fork |
|----------|-----------|
| `fumadocs-core` | `@hanzo/docs-core` |
| `fumadocs-mdx` | `@hanzo/docs-mdx` |
| `fumadocs-ui` / `@fumadocs/radix-ui` | `@hanzo/docs-ui` (in packages/radix-ui) |
| `@fumadocs/base-ui` | `@hanzo/docs-base-ui` |
| `fumadocs-openapi` | `@hanzo/docs-openapi` |
| `fumadocs-typescript` | `@hanzo/docs-typescript` |
| `fumadocs-twoslash` | `@hanzo/docs-twoslash` |
| `@fumadocs/cli` | `@hanzo/docs-cli` |
| `@fumadocs/story` | `@hanzo/docs-story` |
| `@fumadocs/tailwind` | `@hanzo/docs-tailwind` |
- `<basename>` (unscoped upstream) → `@hanzo/docs-<basename>`
- `@<scope>/<basename>` (scoped upstream) → `@hanzo/docs-<basename>`
**Important**: `packages/radix-ui` publishes as `@hanzo/docs-ui` (drop-in replacement for the old `fumadocs-ui`). The `base-ui` variant uses `@base-ui/react` instead of Radix.
Canonical workspace packages and their paths:
| Hanzo name | Path |
|------------|------|
| `@hanzo/docs-core` | packages/core |
| `@hanzo/docs-mdx` | packages/mdx |
| `@hanzo/docs-ui` | packages/radix-ui |
| `@hanzo/docs-base-ui` | packages/base-ui |
| `@hanzo/docs-openapi` | packages/openapi |
| `@hanzo/docs-preview` | packages/preview |
| `@hanzo/docs-typescript` | packages/typescript |
| `@hanzo/docs-twoslash` | packages/twoslash |
| `@hanzo/docs-cli` | packages/cli |
| `@hanzo/docs-story` | packages/story |
| `@hanzo/docs-tailwind` | packages/tailwind |
| `@hanzo/docs-language` | packages/language |
| `@hanzo/docs-local-md` | packages/local-md |
| `@hanzo/docs-sanity` | packages/sanity |
| `@hanzo/docs-shadcn` | packages/shadcn |
| `@hanzo/docs-vite` | packages/vite |
| `@hanzo/docs-basehub` | packages/basehub |
| `@hanzo/docs-mdx-remote` | packages/mdx-remote |
| `@hanzo/docs-stf` | packages/stf |
| `@hanzo/create-docs` | packages/create-app |
| `@hanzo/docs-create-versions` | packages/create-app-versions |
**Important**: `packages/radix-ui` publishes as `@hanzo/docs-ui` (Radix
variant). The `base-ui` variant (`@hanzo/docs-base-ui`) uses `@base-ui/react`
instead of Radix.
**External deps kept verbatim** (real upstream npm packages, NOT renamed):
`fuma-cli`, `fuma-content`, `@fumari/json-schema-ts`, and the third-party
search adapters (typesense / trieve) documented under `apps/docs`.
## Upstream Sync
Remote `upstream` points to `fuma-nama/fumadocs`. Local `dev` tracks `upstream/dev`.
Remote `upstream` points to the upstream fork. Local `dev` tracks `upstream/dev`.
To merge upstream changes:
@@ -74,21 +98,13 @@ To merge upstream changes:
git checkout dev && git pull upstream dev
git checkout -b merge-upstream-YYYY-MM-DD main
git merge dev
# Resolve conflicts, then rename fumadocs-* → @hanzo/docs-*
# Resolve conflicts, then re-apply the package rename (table above)
# Merge into main when ready
```
After merge, do bulk rename:
```bash
find packages/ apps/ examples/ -type f \( -name '*.ts' -o -name '*.tsx' -o -name '*.json' -o -name '*.mdx' \) \
! -path '*/node_modules/*' ! -path '*/dist/*' \
-exec sed -i '' \
-e 's|fumadocs-core|@hanzo/docs-core|g' \
-e 's|fumadocs-ui|@hanzo/docs-ui|g' \
-e 's|@fumadocs/base-ui|@hanzo/docs-base-ui|g' \
# ... etc for all packages
{} +
```
After merge, re-apply the rename with the canonical script
(`scripts/rebrand-packages.mjs` — masks the external KEEP-list, then maps
each upstream name to its `@hanzo/docs-*` form).
## Key Patterns
@@ -104,7 +120,7 @@ import { loader } from '@hanzo/docs-core/source';
export const source = loader({
baseUrl: '/docs',
source: docs.toFumadocsSource(), // API name kept from upstream
source: docs.toHanzoDocsSource(), // API name kept from upstream
});
```
+6 -6
View File
@@ -1,13 +1,13 @@
import type { Metadata } from 'next';
import { type ComponentProps, type FC, type ReactNode } from 'react';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { TypeTable } from '@fumadocs/base-ui/components/type-table';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { TypeTable } from '@hanzo/docs-base-ui/components/type-table';
import { createMetadata } from '@/lib/metadata';
import { source } from '@/lib/source';
import { Card, Cards } from '@fumadocs/base-ui/components/card';
import Link from 'fumadocs-core/link';
import { findSiblings } from 'fumadocs-core/page-tree';
import { DocsBody, DocsPage, PageLastUpdate } from '@fumadocs/base-ui/layouts/docs/page';
import { Card, Cards } from '@hanzo/docs-base-ui/components/card';
import Link from '@hanzo/docs-core/link';
import { findSiblings } from '@hanzo/docs-core/page-tree';
import { DocsBody, DocsPage, PageLastUpdate } from '@hanzo/docs-base-ui/layouts/docs/page';
import { notFound } from 'next/navigation';
import { getMDXComponents } from '@/mdx-components';
+2 -2
View File
@@ -1,6 +1,6 @@
@import 'tailwindcss';
@import '@fumadocs/base-ui/css/neutral.css';
@import '@fumadocs/base-ui/css/preset.css';
@import '@hanzo/docs-base-ui/css/neutral.css';
@import '@hanzo/docs-base-ui/css/preset.css';
@plugin 'tailwindcss-animate';
@theme {
+4 -4
View File
@@ -1,14 +1,14 @@
// @ts-nocheck
import { browser } from 'fumadocs-mdx/runtime/browser';
import { browser } from '@hanzo/docs-mdx/runtime/browser';
import type * as Config from '../source.config';
const create = browser<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = browser<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
@@ -23,6 +23,6 @@ const create = browser<typeof Config, import("fumadocs-mdx/runtime/types").Inter
}
}>();
const browserCollections = {
docs: create.doc("docs", {"index.mdx": () => import("../content/docs/index.mdx?collection=docs"), "auth/index.mdx": () => import("../content/docs/auth/index.mdx?collection=docs"), "cloud-functions/index.mdx": () => import("../content/docs/cloud-functions/index.mdx?collection=docs"), "collections/index.mdx": () => import("../content/docs/collections/index.mdx?collection=docs"), "deployment/index.mdx": () => import("../content/docs/deployment/index.mdx?collection=docs"), "file-storage/index.mdx": () => import("../content/docs/file-storage/index.mdx?collection=docs"), "getting-started/index.mdx": () => import("../content/docs/getting-started/index.mdx?collection=docs"), "getting-started/installation.mdx": () => import("../content/docs/getting-started/installation.mdx?collection=docs"), "getting-started/project-structure.mdx": () => import("../content/docs/getting-started/project-structure.mdx?collection=docs"), "getting-started/quickstart.mdx": () => import("../content/docs/getting-started/quickstart.mdx?collection=docs"), "realtime/index.mdx": () => import("../content/docs/realtime/index.mdx?collection=docs"), "sdk/go.mdx": () => import("../content/docs/sdk/go.mdx?collection=docs"), "sdk/index.mdx": () => import("../content/docs/sdk/index.mdx?collection=docs"), "sdk/javascript.mdx": () => import("../content/docs/sdk/javascript.mdx?collection=docs"), }),
docs: create.doc("docs", {"index.mdx": () => import("../content/docs/index.mdx?collection=docs"), "partner-guide.mdx": () => import("../content/docs/partner-guide.mdx?collection=docs"), "auth/index.mdx": () => import("../content/docs/auth/index.mdx?collection=docs"), "cloud-functions/index.mdx": () => import("../content/docs/cloud-functions/index.mdx?collection=docs"), "collections/index.mdx": () => import("../content/docs/collections/index.mdx?collection=docs"), "getting-started/index.mdx": () => import("../content/docs/getting-started/index.mdx?collection=docs"), "getting-started/installation.mdx": () => import("../content/docs/getting-started/installation.mdx?collection=docs"), "getting-started/project-structure.mdx": () => import("../content/docs/getting-started/project-structure.mdx?collection=docs"), "getting-started/quickstart.mdx": () => import("../content/docs/getting-started/quickstart.mdx?collection=docs"), "file-storage/index.mdx": () => import("../content/docs/file-storage/index.mdx?collection=docs"), "realtime/index.mdx": () => import("../content/docs/realtime/index.mdx?collection=docs"), "deployment/index.mdx": () => import("../content/docs/deployment/index.mdx?collection=docs"), "sdk/go.mdx": () => import("../content/docs/sdk/go.mdx?collection=docs"), "sdk/index.mdx": () => import("../content/docs/sdk/index.mdx?collection=docs"), "sdk/javascript.mdx": () => import("../content/docs/sdk/javascript.mdx?collection=docs"), }),
};
export default browserCollections;
+3 -3
View File
@@ -1,14 +1,14 @@
// @ts-nocheck
import { dynamic } from 'fumadocs-mdx/runtime/dynamic';
import { dynamic } from '@hanzo/docs-mdx/runtime/dynamic';
import * as Config from '../source.config';
const create = await dynamic<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = await dynamic<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
+19 -18
View File
@@ -1,31 +1,32 @@
// @ts-nocheck
import { frontmatter as __fd_glob_16 } from "../content/docs/sdk/javascript.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_15 } from "../content/docs/sdk/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_14 } from "../content/docs/sdk/go.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_17 } from "../content/docs/sdk/javascript.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_16 } from "../content/docs/sdk/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_15 } from "../content/docs/sdk/go.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_14 } from "../content/docs/deployment/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_13 } from "../content/docs/realtime/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_12 } from "../content/docs/getting-started/quickstart.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_11 } from "../content/docs/getting-started/project-structure.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_10 } from "../content/docs/getting-started/installation.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_9 } from "../content/docs/getting-started/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_8 } from "../content/docs/file-storage/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_7 } from "../content/docs/deployment/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_6 } from "../content/docs/collections/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_5 } from "../content/docs/cloud-functions/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_4 } from "../content/docs/auth/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_12 } from "../content/docs/file-storage/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_11 } from "../content/docs/getting-started/quickstart.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_10 } from "../content/docs/getting-started/project-structure.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_9 } from "../content/docs/getting-started/installation.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_8 } from "../content/docs/getting-started/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_7 } from "../content/docs/collections/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_6 } from "../content/docs/cloud-functions/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_5 } from "../content/docs/auth/index.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_4 } from "../content/docs/partner-guide.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_3 } from "../content/docs/index.mdx?collection=docs&only=frontmatter"
import { default as __fd_glob_2 } from "../content/docs/sdk/meta.json?collection=docs"
import { default as __fd_glob_1 } from "../content/docs/getting-started/meta.json?collection=docs"
import { default as __fd_glob_2 } from "../content/docs/getting-started/meta.json?collection=docs"
import { default as __fd_glob_1 } from "../content/docs/sdk/meta.json?collection=docs"
import { default as __fd_glob_0 } from "../content/docs/meta.json?collection=docs"
import { server } from 'fumadocs-mdx/runtime/server';
import { server } from '@hanzo/docs-mdx/runtime/server';
import type * as Config from '../source.config';
const create = server<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = server<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
@@ -40,4 +41,4 @@ const create = server<typeof Config, import("fumadocs-mdx/runtime/types").Intern
}
}>({"doc":{"passthroughs":["extractedReferences","lastModified"]}});
export const docs = await create.docsLazy("docs", "content/docs", {"meta.json": __fd_glob_0, "getting-started/meta.json": __fd_glob_1, "sdk/meta.json": __fd_glob_2, }, {"index.mdx": __fd_glob_3, "auth/index.mdx": __fd_glob_4, "cloud-functions/index.mdx": __fd_glob_5, "collections/index.mdx": __fd_glob_6, "deployment/index.mdx": __fd_glob_7, "file-storage/index.mdx": __fd_glob_8, "getting-started/index.mdx": __fd_glob_9, "getting-started/installation.mdx": __fd_glob_10, "getting-started/project-structure.mdx": __fd_glob_11, "getting-started/quickstart.mdx": __fd_glob_12, "realtime/index.mdx": __fd_glob_13, "sdk/go.mdx": __fd_glob_14, "sdk/index.mdx": __fd_glob_15, "sdk/javascript.mdx": __fd_glob_16, }, {"index.mdx": () => import("../content/docs/index.mdx?collection=docs"), "auth/index.mdx": () => import("../content/docs/auth/index.mdx?collection=docs"), "cloud-functions/index.mdx": () => import("../content/docs/cloud-functions/index.mdx?collection=docs"), "collections/index.mdx": () => import("../content/docs/collections/index.mdx?collection=docs"), "deployment/index.mdx": () => import("../content/docs/deployment/index.mdx?collection=docs"), "file-storage/index.mdx": () => import("../content/docs/file-storage/index.mdx?collection=docs"), "getting-started/index.mdx": () => import("../content/docs/getting-started/index.mdx?collection=docs"), "getting-started/installation.mdx": () => import("../content/docs/getting-started/installation.mdx?collection=docs"), "getting-started/project-structure.mdx": () => import("../content/docs/getting-started/project-structure.mdx?collection=docs"), "getting-started/quickstart.mdx": () => import("../content/docs/getting-started/quickstart.mdx?collection=docs"), "realtime/index.mdx": () => import("../content/docs/realtime/index.mdx?collection=docs"), "sdk/go.mdx": () => import("../content/docs/sdk/go.mdx?collection=docs"), "sdk/index.mdx": () => import("../content/docs/sdk/index.mdx?collection=docs"), "sdk/javascript.mdx": () => import("../content/docs/sdk/javascript.mdx?collection=docs"), });
export const docs = await create.docsLazy("docs", "content/docs", {"meta.json": __fd_glob_0, "sdk/meta.json": __fd_glob_1, "getting-started/meta.json": __fd_glob_2, }, {"index.mdx": __fd_glob_3, "partner-guide.mdx": __fd_glob_4, "auth/index.mdx": __fd_glob_5, "cloud-functions/index.mdx": __fd_glob_6, "collections/index.mdx": __fd_glob_7, "getting-started/index.mdx": __fd_glob_8, "getting-started/installation.mdx": __fd_glob_9, "getting-started/project-structure.mdx": __fd_glob_10, "getting-started/quickstart.mdx": __fd_glob_11, "file-storage/index.mdx": __fd_glob_12, "realtime/index.mdx": __fd_glob_13, "deployment/index.mdx": __fd_glob_14, "sdk/go.mdx": __fd_glob_15, "sdk/index.mdx": __fd_glob_16, "sdk/javascript.mdx": __fd_glob_17, }, {"index.mdx": () => import("../content/docs/index.mdx?collection=docs"), "partner-guide.mdx": () => import("../content/docs/partner-guide.mdx?collection=docs"), "auth/index.mdx": () => import("../content/docs/auth/index.mdx?collection=docs"), "cloud-functions/index.mdx": () => import("../content/docs/cloud-functions/index.mdx?collection=docs"), "collections/index.mdx": () => import("../content/docs/collections/index.mdx?collection=docs"), "getting-started/index.mdx": () => import("../content/docs/getting-started/index.mdx?collection=docs"), "getting-started/installation.mdx": () => import("../content/docs/getting-started/installation.mdx?collection=docs"), "getting-started/project-structure.mdx": () => import("../content/docs/getting-started/project-structure.mdx?collection=docs"), "getting-started/quickstart.mdx": () => import("../content/docs/getting-started/quickstart.mdx?collection=docs"), "file-storage/index.mdx": () => import("../content/docs/file-storage/index.mdx?collection=docs"), "realtime/index.mdx": () => import("../content/docs/realtime/index.mdx?collection=docs"), "deployment/index.mdx": () => import("../content/docs/deployment/index.mdx?collection=docs"), "sdk/go.mdx": () => import("../content/docs/sdk/go.mdx?collection=docs"), "sdk/index.mdx": () => import("../content/docs/sdk/index.mdx?collection=docs"), "sdk/javascript.mdx": () => import("../content/docs/sdk/javascript.mdx?collection=docs"), });
+5 -5
View File
@@ -5,9 +5,9 @@ import {
defineDocs,
frontmatterSchema,
metaSchema
} from "fumadocs-mdx/config";
} from "@hanzo/docs-mdx/config";
import { z } from "zod";
import lastModified from "fumadocs-mdx/plugins/last-modified";
import lastModified from "@hanzo/docs-mdx/plugins/last-modified";
var docs = defineDocs({
docs: {
schema: frontmatterSchema.extend({
@@ -19,9 +19,9 @@ var docs = defineDocs({
},
async: true,
async mdxOptions(environment) {
const { rehypeCodeDefaultOptions } = await import("fumadocs-core/mdx-plugins/rehype-code");
const { remarkStructureDefaultOptions } = await import("fumadocs-core/mdx-plugins/remark-structure");
const { remarkSteps } = await import("fumadocs-core/mdx-plugins/remark-steps");
const { rehypeCodeDefaultOptions } = await import("@hanzo/docs-core/mdx-plugins/rehype-code");
const { remarkStructureDefaultOptions } = await import("@hanzo/docs-core/mdx-plugins/remark-structure");
const { remarkSteps } = await import("@hanzo/docs-core/mdx-plugins/remark-steps");
return applyMdxPreset({
remarkStructureOptions: {
types: [...remarkStructureDefaultOptions.types, "code"]
+6 -6
View File
@@ -1,10 +1,10 @@
import type { MDXComponents } from 'mdx/types';
import defaultMdxComponents from '@fumadocs/base-ui/mdx';
import { Tab, Tabs } from '@fumadocs/base-ui/components/tabs';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { Step, Steps } from '@fumadocs/base-ui/components/steps';
import { File, Folder, Files } from '@fumadocs/base-ui/components/files';
import { Accordion, Accordions } from '@fumadocs/base-ui/components/accordion';
import defaultMdxComponents from '@hanzo/docs-base-ui/mdx';
import { Tab, Tabs } from '@hanzo/docs-base-ui/components/tabs';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { Step, Steps } from '@hanzo/docs-base-ui/components/steps';
import { File, Folder, Files } from '@hanzo/docs-base-ui/components/files';
import { Accordion, Accordions } from '@hanzo/docs-base-ui/components/accordion';
export function getMDXComponents(components?: MDXComponents): MDXComponents {
return {
+5 -5
View File
@@ -6,18 +6,18 @@
"build": "pnpm build:pre && next build --webpack && pnpm build:post",
"build:pre": "bun ./scripts/pre-build.ts",
"build:post": "bun ./scripts/post-build.ts",
"types:check": "fumadocs-mdx && next typegen && tsc --noEmit",
"types:check": "@hanzo/docs-mdx && next typegen && tsc --noEmit",
"clean": "rimraf .next",
"dev": "next dev --port 3006",
"lint": "fumadocs-mdx && eslint .",
"lint": "@hanzo/docs-mdx && eslint .",
"start": "next start"
},
"dependencies": {
"@hanzo/mdx-runtime": "workspace:*",
"@hanzo/docs": "workspace:*",
"fumadocs-core": "workspace:*",
"fumadocs-mdx": "workspace:*",
"@fumadocs/base-ui": "workspace:*",
"@hanzo/docs-core": "workspace:*",
"@hanzo/docs-mdx": "workspace:*",
"@hanzo/docs-base-ui": "workspace:*",
"@radix-ui/react-tooltip": "^1.2.8",
"@shikijs/rehype": "^3.21.0",
"@shikijs/transformers": "^3.21.0",
+5 -5
View File
@@ -4,9 +4,9 @@ import {
defineDocs,
frontmatterSchema,
metaSchema,
} from 'fumadocs-mdx/config';
} from '@hanzo/docs-mdx/config';
import { z } from 'zod';
import lastModified from 'fumadocs-mdx/plugins/last-modified';
import lastModified from '@hanzo/docs-mdx/plugins/last-modified';
export const docs = defineDocs({
docs: {
@@ -19,10 +19,10 @@ export const docs = defineDocs({
},
async: true,
async mdxOptions(environment) {
const { rehypeCodeDefaultOptions } = await import('fumadocs-core/mdx-plugins/rehype-code');
const { rehypeCodeDefaultOptions } = await import('@hanzo/docs-core/mdx-plugins/rehype-code');
const { remarkStructureDefaultOptions } =
await import('fumadocs-core/mdx-plugins/remark-structure');
const { remarkSteps } = await import('fumadocs-core/mdx-plugins/remark-steps');
await import('@hanzo/docs-core/mdx-plugins/remark-structure');
const { remarkSteps } = await import('@hanzo/docs-core/mdx-plugins/remark-steps');
return applyMdxPreset({
remarkStructureOptions: {
+1 -1
View File
@@ -1,5 +1,5 @@
import type { ReactNode } from 'react';
import { HomeLayout } from '@fumadocs/base-ui/layouts/home';
import { HomeLayout } from '@hanzo/docs-base-ui/layouts/home';
import { baseOptions } from '@/lib/layout.shared';
import { linkItems } from '@/lib/layout.shared';
@@ -1,13 +1,13 @@
import type { Metadata } from 'next';
import { type ComponentProps, type FC, type ReactNode } from 'react';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { TypeTable } from '@fumadocs/base-ui/components/type-table';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { TypeTable } from '@hanzo/docs-base-ui/components/type-table';
import { createMetadata } from '@/lib/metadata';
import { source } from '@/lib/source';
import { Card, Cards } from '@fumadocs/base-ui/components/card';
import Link from 'fumadocs-core/link';
import { findSiblings } from 'fumadocs-core/page-tree';
import { DocsBody, DocsPage, PageLastUpdate } from '@fumadocs/base-ui/layouts/docs/page';
import { Card, Cards } from '@hanzo/docs-base-ui/components/card';
import Link from '@hanzo/docs-core/link';
import { findSiblings } from '@hanzo/docs-core/page-tree';
import { DocsBody, DocsPage, PageLastUpdate } from '@hanzo/docs-base-ui/layouts/docs/page';
import { notFound } from 'next/navigation';
import { getMDXComponents } from '@/mdx-components';
+2 -2
View File
@@ -1,6 +1,6 @@
@import 'tailwindcss';
@import '@fumadocs/base-ui/css/neutral.css';
@import '@fumadocs/base-ui/css/preset.css';
@import '@hanzo/docs-base-ui/css/neutral.css';
@import '@hanzo/docs-base-ui/css/preset.css';
@plugin 'tailwindcss-animate';
@theme {
+6 -6
View File
@@ -1,10 +1,10 @@
import type { MDXComponents } from 'mdx/types';
import defaultMdxComponents from '@fumadocs/base-ui/mdx';
import { Tab, Tabs } from '@fumadocs/base-ui/components/tabs';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { Step, Steps } from '@fumadocs/base-ui/components/steps';
import { File, Folder, Files } from '@fumadocs/base-ui/components/files';
import { Accordion, Accordions } from '@fumadocs/base-ui/components/accordion';
import defaultMdxComponents from '@hanzo/docs-base-ui/mdx';
import { Tab, Tabs } from '@hanzo/docs-base-ui/components/tabs';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { Step, Steps } from '@hanzo/docs-base-ui/components/steps';
import { File, Folder, Files } from '@hanzo/docs-base-ui/components/files';
import { Accordion, Accordions } from '@hanzo/docs-base-ui/components/accordion';
export function getMDXComponents(components?: MDXComponents): MDXComponents {
return {
+5 -5
View File
@@ -6,18 +6,18 @@
"build": "pnpm build:pre && next build --webpack && pnpm build:post",
"build:pre": "bun ./scripts/pre-build.ts",
"build:post": "bun ./scripts/post-build.ts",
"types:check": "fumadocs-mdx && next typegen && tsc --noEmit",
"types:check": "@hanzo/docs-mdx && next typegen && tsc --noEmit",
"clean": "rimraf .next",
"dev": "next dev --port 3005 --webpack",
"lint": "fumadocs-mdx && eslint .",
"lint": "@hanzo/docs-mdx && eslint .",
"start": "next start"
},
"dependencies": {
"@hanzo/mdx-runtime": "workspace:*",
"@hanzo/docs": "workspace:*",
"fumadocs-core": "workspace:*",
"fumadocs-mdx": "workspace:*",
"@fumadocs/base-ui": "workspace:*",
"@hanzo/docs-core": "workspace:*",
"@hanzo/docs-mdx": "workspace:*",
"@hanzo/docs-base-ui": "workspace:*",
"@radix-ui/react-tooltip": "^1.2.8",
"@shikijs/rehype": "^3.21.0",
"@shikijs/transformers": "^3.21.0",
+5 -5
View File
@@ -4,9 +4,9 @@ import {
defineDocs,
frontmatterSchema,
metaSchema,
} from 'fumadocs-mdx/config';
} from '@hanzo/docs-mdx/config';
import { z } from 'zod';
import lastModified from 'fumadocs-mdx/plugins/last-modified';
import lastModified from '@hanzo/docs-mdx/plugins/last-modified';
export const docs = defineDocs({
docs: {
@@ -19,10 +19,10 @@ export const docs = defineDocs({
},
async: true,
async mdxOptions(environment) {
const { rehypeCodeDefaultOptions } = await import('fumadocs-core/mdx-plugins/rehype-code');
const { rehypeCodeDefaultOptions } = await import('@hanzo/docs-core/mdx-plugins/rehype-code');
const { remarkStructureDefaultOptions } =
await import('fumadocs-core/mdx-plugins/remark-structure');
const { remarkSteps } = await import('fumadocs-core/mdx-plugins/remark-steps');
await import('@hanzo/docs-core/mdx-plugins/remark-structure');
const { remarkSteps } = await import('@hanzo/docs-core/mdx-plugins/remark-steps');
return applyMdxPreset({
remarkStructureOptions: {
+1 -1
View File
@@ -4,7 +4,7 @@ import { baseOptions, linkItems, logo, GithubIcon } from '@/lib/layout.shared';
import { AISearchPanel, AISearchTrigger } from '@/components/ai/search';
import { MessageCircleIcon } from 'lucide-react';
import { cn } from '@/lib/cn';
import { buttonVariants } from '@fumadocs/base-ui/components/ui/button';
import { buttonVariants } from '@hanzo/docs-base-ui/components/ui/button';
export default function Layout({ children }: { children: ReactNode }) {
return (
+6 -6
View File
@@ -1,13 +1,13 @@
import type { Metadata } from 'next';
import { type ComponentProps, type FC, type ReactNode } from 'react';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { TypeTable } from '@fumadocs/base-ui/components/type-table';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { TypeTable } from '@hanzo/docs-base-ui/components/type-table';
import { createMetadata } from '@/lib/metadata';
import { source } from '@/lib/source';
import { Card, Cards } from '@fumadocs/base-ui/components/card';
import Link from 'fumadocs-core/link';
import { findSiblings } from 'fumadocs-core/page-tree';
import { DocsBody, DocsPage, PageLastUpdate } from '@fumadocs/base-ui/layouts/docs/page';
import { Card, Cards } from '@hanzo/docs-base-ui/components/card';
import Link from '@hanzo/docs-core/link';
import { findSiblings } from '@hanzo/docs-core/page-tree';
import { DocsBody, DocsPage, PageLastUpdate } from '@hanzo/docs-base-ui/layouts/docs/page';
import { notFound } from 'next/navigation';
import { getMDXComponents } from '@/mdx-components';
+2 -2
View File
@@ -1,6 +1,6 @@
@import 'tailwindcss';
@import '@fumadocs/base-ui/css/neutral.css';
@import '@fumadocs/base-ui/css/preset.css';
@import '@hanzo/docs-base-ui/css/neutral.css';
@import '@hanzo/docs-base-ui/css/preset.css';
@plugin 'tailwindcss-animate';
@theme {
+2 -2
View File
@@ -13,8 +13,8 @@ import {
} from 'react';
import { Loader2, MessageCircleIcon, RefreshCw, Send, X } from 'lucide-react';
import { cn } from '@/lib/cn';
import { buttonVariants } from '@fumadocs/base-ui/components/ui/button';
import Link from 'fumadocs-core/link';
import { buttonVariants } from '@hanzo/docs-base-ui/components/ui/button';
import Link from '@hanzo/docs-core/link';
import { useChat, type UseChatHelpers } from '@ai-sdk/react';
import type { ProvideLinksToolSchema } from '@/lib/chat/inkeep-qa-schema';
import type { z } from 'zod';
+1 -1
View File
@@ -346,7 +346,7 @@
},
{
"id": "2011077782688985233",
"author": "Fuma Kotaro",
"author": "Hanzo Kotaro",
"quote": "Just built @Hanzo Bot integration for ralph-tui!\n\nRemote TUI via Tailscale + tmux\n\nTelegram inline status updates\n\nScreenshots on completion",
"category": "developer",
"likes": 2
+1 -1
View File
@@ -41,7 +41,7 @@
},
{
"quote": "This mf called @hanzoai has achieved AGI with @hanzobot",
"author": "Fuma Kotaro",
"author": "Hanzo Kotaro",
"url": "https://hanzo.bot"
},
{
+1 -1
View File
@@ -41,7 +41,7 @@
},
{
"quote": "My clan operated in shadow for generations. Now we operate in the cloud. The principle is identical — be everywhere, be invisible, leave no trace.",
"author": "Fuma Kotaro",
"author": "Hanzo Kotaro",
"url": "https://hanzo.bot"
},
{
+3 -3
View File
@@ -1,14 +1,14 @@
// @ts-nocheck
import { browser } from 'fumadocs-mdx/runtime/browser';
import { browser } from '@hanzo/docs-mdx/runtime/browser';
import type * as Config from '../source.config';
const create = browser<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = browser<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
+3 -3
View File
@@ -1,14 +1,14 @@
// @ts-nocheck
import { dynamic } from 'fumadocs-mdx/runtime/dynamic';
import { dynamic } from '@hanzo/docs-mdx/runtime/dynamic';
import * as Config from '../source.config';
const create = await dynamic<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = await dynamic<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
+3 -3
View File
@@ -280,16 +280,16 @@ import { default as __fd_glob_3 } from "../content/docs/concepts/meta.json?colle
import { default as __fd_glob_2 } from "../content/docs/channels/meta.json?collection=docs"
import { default as __fd_glob_1 } from "../content/docs/automation/meta.json?collection=docs"
import { default as __fd_glob_0 } from "../content/docs/meta.json?collection=docs"
import { server } from 'fumadocs-mdx/runtime/server';
import { server } from '@hanzo/docs-mdx/runtime/server';
import type * as Config from '../source.config';
const create = server<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = server<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
+6 -6
View File
@@ -5,10 +5,10 @@ import {
defineDocs,
frontmatterSchema,
metaSchema
} from "fumadocs-mdx/config";
} from "@hanzo/docs-mdx/config";
import { z } from "zod";
import jsonSchema from "fumadocs-mdx/plugins/json-schema";
import lastModified from "fumadocs-mdx/plugins/last-modified";
import jsonSchema from "@hanzo/docs-mdx/plugins/json-schema";
import lastModified from "@hanzo/docs-mdx/plugins/last-modified";
var docs = defineDocs({
docs: {
schema: frontmatterSchema.extend({
@@ -20,9 +20,9 @@ var docs = defineDocs({
},
async: true,
async mdxOptions(environment) {
const { rehypeCodeDefaultOptions } = await import("fumadocs-core/mdx-plugins/rehype-code");
const { remarkStructureDefaultOptions } = await import("fumadocs-core/mdx-plugins/remark-structure");
const { remarkSteps } = await import("fumadocs-core/mdx-plugins/remark-steps");
const { rehypeCodeDefaultOptions } = await import("@hanzo/docs-core/mdx-plugins/rehype-code");
const { remarkStructureDefaultOptions } = await import("@hanzo/docs-core/mdx-plugins/remark-structure");
const { remarkSteps } = await import("@hanzo/docs-core/mdx-plugins/remark-steps");
return applyMdxPreset({
remarkStructureOptions: {
types: [...remarkStructureDefaultOptions.types, "code"]
+7 -7
View File
@@ -1,12 +1,12 @@
import type { MDXComponents } from 'mdx/types';
import type { FC, ReactNode } from 'react';
import defaultMdxComponents from '@fumadocs/base-ui/mdx';
import { Tab, Tabs } from '@fumadocs/base-ui/components/tabs';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { Step, Steps } from '@fumadocs/base-ui/components/steps';
import { Card, Cards } from '@fumadocs/base-ui/components/card';
import { File, Folder, Files } from '@fumadocs/base-ui/components/files';
import { Accordion, Accordions } from '@fumadocs/base-ui/components/accordion';
import defaultMdxComponents from '@hanzo/docs-base-ui/mdx';
import { Tab, Tabs } from '@hanzo/docs-base-ui/components/tabs';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { Step, Steps } from '@hanzo/docs-base-ui/components/steps';
import { Card, Cards } from '@hanzo/docs-base-ui/components/card';
import { File, Folder, Files } from '@hanzo/docs-base-ui/components/files';
import { Accordion, Accordions } from '@hanzo/docs-base-ui/components/accordion';
// Mintlify compatibility wrappers
const CardGroup: FC<{ cols?: number; children?: ReactNode }> = ({ children }) => (
+5 -5
View File
@@ -6,18 +6,18 @@
"build": "pnpm build:pre && next build --webpack && pnpm build:post",
"build:pre": "bun ./scripts/pre-build.ts",
"build:post": "bun ./scripts/post-build.ts",
"types:check": "fumadocs-mdx && next typegen && tsc --noEmit",
"types:check": "@hanzo/docs-mdx && next typegen && tsc --noEmit",
"clean": "rimraf .next",
"dev": "next dev --port 3005 --webpack",
"lint": "fumadocs-mdx && eslint .",
"lint": "@hanzo/docs-mdx && eslint .",
"start": "next start"
},
"dependencies": {
"@ai-sdk/react": "^3.0.79",
"@hanzo/docs": "workspace:*",
"@fumadocs/base-ui": "workspace:*",
"fumadocs-core": "workspace:*",
"fumadocs-mdx": "workspace:*",
"@hanzo/docs-base-ui": "workspace:*",
"@hanzo/docs-core": "workspace:*",
"@hanzo/docs-mdx": "workspace:*",
"@hanzo/logo": "^1.0.5",
"@hanzo/mdx-runtime": "workspace:*",
"@radix-ui/react-presence": "^1.1.5",
+3 -3
View File
@@ -1,5 +1,5 @@
/**
* Convert OpenClaw/Bot docs from Mintlify .md fumadocs .mdx
* Convert OpenClaw/Bot docs from Mintlify .md Hanzo Docs .mdx
*
* - Copies all .md files preserving directory structure
* - Converts frontmatter (summary description, removes read_when)
@@ -138,7 +138,7 @@ function convertFrontmatter(content: string): string {
const headingMatch = body.match(/^#\s+(.+)$/m);
if (headingMatch) {
title = headingMatch[1];
// Remove the heading from body since fumadocs uses frontmatter title
// Remove the heading from body since Hanzo Docs uses frontmatter title
body = body.replace(/^#\s+.+\n+/, '');
}
}
@@ -308,7 +308,7 @@ async function createMetaFiles() {
}
async function main() {
console.log('Converting OpenClaw docs → Hanzo Bot fumadocs MDX\n');
console.log('Converting OpenClaw docs → Hanzo Bot Hanzo Docs MDX\n');
console.log(`Source: ${SRC}`);
console.log(`Dest: ${DEST}\n`);
+1 -1
View File
@@ -5,7 +5,7 @@ console.log('Running pre-build...');
try {
// Use node directly instead of npx — pnpm workspace links exist but bin
// symlinks may not be created if packages weren't built before pnpm install
execSync('node ./node_modules/fumadocs-mdx/dist/bin.js', { stdio: 'inherit' });
execSync('node ./node_modules/@hanzo/docs-mdx/dist/bin.js', { stdio: 'inherit' });
console.log('Pre-build complete');
} catch (error) {
console.error('Pre-build failed:', error);
+1 -1
View File
@@ -1,6 +1,6 @@
/**
* Strip duplicate H1 headings from MDX files.
* fumadocs renders title from frontmatter, so body H1s are redundant.
* Hanzo Docs renders title from frontmatter, so body H1s are redundant.
*/
import { readdir, readFile, writeFile } from 'fs/promises';
import { join } from 'path';
+6 -6
View File
@@ -4,10 +4,10 @@ import {
defineDocs,
frontmatterSchema,
metaSchema,
} from 'fumadocs-mdx/config';
} from '@hanzo/docs-mdx/config';
import { z } from 'zod';
import jsonSchema from 'fumadocs-mdx/plugins/json-schema';
import lastModified from 'fumadocs-mdx/plugins/last-modified';
import jsonSchema from '@hanzo/docs-mdx/plugins/json-schema';
import lastModified from '@hanzo/docs-mdx/plugins/last-modified';
export const docs = defineDocs({
docs: {
@@ -20,10 +20,10 @@ export const docs = defineDocs({
},
async: true,
async mdxOptions(environment) {
const { rehypeCodeDefaultOptions } = await import('fumadocs-core/mdx-plugins/rehype-code');
const { rehypeCodeDefaultOptions } = await import('@hanzo/docs-core/mdx-plugins/rehype-code');
const { remarkStructureDefaultOptions } =
await import('fumadocs-core/mdx-plugins/remark-structure');
const { remarkSteps } = await import('fumadocs-core/mdx-plugins/remark-steps');
await import('@hanzo/docs-core/mdx-plugins/remark-structure');
const { remarkSteps } = await import('@hanzo/docs-core/mdx-plugins/remark-steps');
return applyMdxPreset({
remarkStructureOptions: {
+6 -6
View File
@@ -1,13 +1,13 @@
import type { Metadata } from 'next';
import { type ComponentProps, type FC, type ReactNode } from 'react';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { TypeTable } from '@fumadocs/base-ui/components/type-table';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { TypeTable } from '@hanzo/docs-base-ui/components/type-table';
import { createMetadata } from '@/lib/metadata';
import { source } from '@/lib/source';
import { Card, Cards } from '@fumadocs/base-ui/components/card';
import Link from 'fumadocs-core/link';
import { findSiblings } from 'fumadocs-core/page-tree';
import { DocsBody, DocsPage, PageLastUpdate } from '@fumadocs/base-ui/layouts/docs/page';
import { Card, Cards } from '@hanzo/docs-base-ui/components/card';
import Link from '@hanzo/docs-core/link';
import { findSiblings } from '@hanzo/docs-core/page-tree';
import { DocsBody, DocsPage, PageLastUpdate } from '@hanzo/docs-base-ui/layouts/docs/page';
import { notFound } from 'next/navigation';
import { getMDXComponents } from '@/mdx-components';
+2 -2
View File
@@ -1,6 +1,6 @@
@import 'tailwindcss';
@import '@fumadocs/base-ui/css/neutral.css';
@import '@fumadocs/base-ui/css/preset.css';
@import '@hanzo/docs-base-ui/css/neutral.css';
@import '@hanzo/docs-base-ui/css/preset.css';
@plugin 'tailwindcss-animate';
@theme {
+3 -3
View File
@@ -1,14 +1,14 @@
// @ts-nocheck
import { browser } from 'fumadocs-mdx/runtime/browser';
import { browser } from '@hanzo/docs-mdx/runtime/browser';
import type * as Config from '../source.config';
const create = browser<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = browser<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
+3 -3
View File
@@ -1,14 +1,14 @@
// @ts-nocheck
import { dynamic } from 'fumadocs-mdx/runtime/dynamic';
import { dynamic } from '@hanzo/docs-mdx/runtime/dynamic';
import * as Config from '../source.config';
const create = await dynamic<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = await dynamic<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
+3 -3
View File
@@ -38,16 +38,16 @@ import { default as __fd_glob_3 } from "../content/docs/contributing/meta.json?c
import { default as __fd_glob_2 } from "../content/docs/configuration/meta.json?collection=docs"
import { default as __fd_glob_1 } from "../content/docs/architecture/meta.json?collection=docs"
import { default as __fd_glob_0 } from "../content/docs/meta.json?collection=docs"
import { server } from 'fumadocs-mdx/runtime/server';
import { server } from '@hanzo/docs-mdx/runtime/server';
import type * as Config from '../source.config';
const create = server<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = server<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
+5 -5
View File
@@ -5,9 +5,9 @@ import {
defineDocs,
frontmatterSchema,
metaSchema
} from "fumadocs-mdx/config";
} from "@hanzo/docs-mdx/config";
import { z } from "zod";
import lastModified from "fumadocs-mdx/plugins/last-modified";
import lastModified from "@hanzo/docs-mdx/plugins/last-modified";
var docs = defineDocs({
docs: {
schema: frontmatterSchema.extend({
@@ -19,9 +19,9 @@ var docs = defineDocs({
},
async: true,
async mdxOptions(environment) {
const { rehypeCodeDefaultOptions } = await import("fumadocs-core/mdx-plugins/rehype-code");
const { remarkStructureDefaultOptions } = await import("fumadocs-core/mdx-plugins/remark-structure");
const { remarkSteps } = await import("fumadocs-core/mdx-plugins/remark-steps");
const { rehypeCodeDefaultOptions } = await import("@hanzo/docs-core/mdx-plugins/rehype-code");
const { remarkStructureDefaultOptions } = await import("@hanzo/docs-core/mdx-plugins/remark-structure");
const { remarkSteps } = await import("@hanzo/docs-core/mdx-plugins/remark-steps");
return applyMdxPreset({
remarkStructureOptions: {
types: [...remarkStructureDefaultOptions.types, "code"]
+6 -6
View File
@@ -1,10 +1,10 @@
import type { MDXComponents } from 'mdx/types';
import defaultMdxComponents from '@fumadocs/base-ui/mdx';
import { Tab, Tabs } from '@fumadocs/base-ui/components/tabs';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { Step, Steps } from '@fumadocs/base-ui/components/steps';
import { File, Folder, Files } from '@fumadocs/base-ui/components/files';
import { Accordion, Accordions } from '@fumadocs/base-ui/components/accordion';
import defaultMdxComponents from '@hanzo/docs-base-ui/mdx';
import { Tab, Tabs } from '@hanzo/docs-base-ui/components/tabs';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { Step, Steps } from '@hanzo/docs-base-ui/components/steps';
import { File, Folder, Files } from '@hanzo/docs-base-ui/components/files';
import { Accordion, Accordions } from '@hanzo/docs-base-ui/components/accordion';
export function getMDXComponents(components?: MDXComponents): MDXComponents {
return {
+5 -5
View File
@@ -6,18 +6,18 @@
"build": "pnpm build:pre && next build --webpack && pnpm build:post",
"build:pre": "bun ./scripts/pre-build.ts",
"build:post": "bun ./scripts/post-build.ts",
"types:check": "fumadocs-mdx && next typegen && tsc --noEmit",
"types:check": "@hanzo/docs-mdx && next typegen && tsc --noEmit",
"clean": "rimraf .next",
"dev": "next dev --port 3003 --webpack",
"lint": "fumadocs-mdx && eslint .",
"lint": "@hanzo/docs-mdx && eslint .",
"start": "next start"
},
"dependencies": {
"@hanzo/mdx-runtime": "workspace:*",
"@hanzo/docs": "workspace:*",
"fumadocs-core": "workspace:*",
"fumadocs-mdx": "workspace:*",
"@fumadocs/base-ui": "workspace:*",
"@hanzo/docs-core": "workspace:*",
"@hanzo/docs-mdx": "workspace:*",
"@hanzo/docs-base-ui": "workspace:*",
"@radix-ui/react-tooltip": "^1.2.8",
"@shikijs/rehype": "^3.21.0",
"@shikijs/transformers": "^3.21.0",
+5 -5
View File
@@ -4,9 +4,9 @@ import {
defineDocs,
frontmatterSchema,
metaSchema,
} from 'fumadocs-mdx/config';
} from '@hanzo/docs-mdx/config';
import { z } from 'zod';
import lastModified from 'fumadocs-mdx/plugins/last-modified';
import lastModified from '@hanzo/docs-mdx/plugins/last-modified';
export const docs = defineDocs({
docs: {
@@ -19,10 +19,10 @@ export const docs = defineDocs({
},
async: true,
async mdxOptions(environment) {
const { rehypeCodeDefaultOptions } = await import('fumadocs-core/mdx-plugins/rehype-code');
const { rehypeCodeDefaultOptions } = await import('@hanzo/docs-core/mdx-plugins/rehype-code');
const { remarkStructureDefaultOptions } =
await import('fumadocs-core/mdx-plugins/remark-structure');
const { remarkSteps } = await import('fumadocs-core/mdx-plugins/remark-steps');
await import('@hanzo/docs-core/mdx-plugins/remark-structure');
const { remarkSteps } = await import('@hanzo/docs-core/mdx-plugins/remark-steps');
return applyMdxPreset({
remarkStructureOptions: {
+6 -6
View File
@@ -1,13 +1,13 @@
import type { Metadata } from 'next';
import { type ComponentProps, type FC, type ReactNode } from 'react';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { TypeTable } from '@fumadocs/base-ui/components/type-table';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { TypeTable } from '@hanzo/docs-base-ui/components/type-table';
import { createMetadata } from '@/lib/metadata';
import { source } from '@/lib/source';
import { Card, Cards } from '@fumadocs/base-ui/components/card';
import Link from 'fumadocs-core/link';
import { findSiblings } from 'fumadocs-core/page-tree';
import { DocsBody, DocsPage, PageLastUpdate } from '@fumadocs/base-ui/layouts/docs/page';
import { Card, Cards } from '@hanzo/docs-base-ui/components/card';
import Link from '@hanzo/docs-core/link';
import { findSiblings } from '@hanzo/docs-core/page-tree';
import { DocsBody, DocsPage, PageLastUpdate } from '@hanzo/docs-base-ui/layouts/docs/page';
import { notFound } from 'next/navigation';
import { getMDXComponents } from '@/mdx-components';
+1 -1
View File
@@ -1,2 +1,2 @@
@import 'tailwindcss';
@import '@fumadocs/base-ui/css/neutral.css';
@import '@hanzo/docs-base-ui/css/neutral.css';
+3 -3
View File
@@ -1,14 +1,14 @@
// @ts-nocheck
import { browser } from 'fumadocs-mdx/runtime/browser';
import { browser } from '@hanzo/docs-mdx/runtime/browser';
import type * as Config from '../source.config';
const create = browser<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = browser<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
+3 -3
View File
@@ -1,14 +1,14 @@
// @ts-nocheck
import { dynamic } from 'fumadocs-mdx/runtime/dynamic';
import { dynamic } from '@hanzo/docs-mdx/runtime/dynamic';
import * as Config from '../source.config';
const create = await dynamic<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = await dynamic<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
+3 -3
View File
@@ -7,16 +7,16 @@ import { frontmatter as __fd_glob_3 } from "../content/docs/cloudflare.mdx?colle
import { frontmatter as __fd_glob_2 } from "../content/docs/architecture.mdx?collection=docs&only=frontmatter"
import { frontmatter as __fd_glob_1 } from "../content/docs/api-reference.mdx?collection=docs&only=frontmatter"
import { default as __fd_glob_0 } from "../content/docs/meta.json?collection=docs"
import { server } from 'fumadocs-mdx/runtime/server';
import { server } from '@hanzo/docs-mdx/runtime/server';
import type * as Config from '../source.config';
const create = server<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
const create = server<typeof Config, import("@hanzo/docs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
docs: {
/**
* extracted references (e.g. hrefs, paths), useful for analyzing relationships between pages.
*/
extractedReferences: import("fumadocs-mdx").ExtractedReference[];
extractedReferences: import("@hanzo/docs-mdx").ExtractedReference[];
},
}
} & {
+5 -5
View File
@@ -5,9 +5,9 @@ import {
defineDocs,
frontmatterSchema,
metaSchema
} from "fumadocs-mdx/config";
} from "@hanzo/docs-mdx/config";
import { z } from "zod";
import lastModified from "fumadocs-mdx/plugins/last-modified";
import lastModified from "@hanzo/docs-mdx/plugins/last-modified";
var docs = defineDocs({
docs: {
schema: frontmatterSchema.extend({
@@ -19,9 +19,9 @@ var docs = defineDocs({
},
async: true,
async mdxOptions(environment) {
const { rehypeCodeDefaultOptions } = await import("fumadocs-core/mdx-plugins/rehype-code");
const { remarkStructureDefaultOptions } = await import("fumadocs-core/mdx-plugins/remark-structure");
const { remarkSteps } = await import("fumadocs-core/mdx-plugins/remark-steps");
const { rehypeCodeDefaultOptions } = await import("@hanzo/docs-core/mdx-plugins/rehype-code");
const { remarkStructureDefaultOptions } = await import("@hanzo/docs-core/mdx-plugins/remark-structure");
const { remarkSteps } = await import("@hanzo/docs-core/mdx-plugins/remark-steps");
return applyMdxPreset({
remarkStructureOptions: {
types: [...remarkStructureDefaultOptions.types, "code"]
+6 -6
View File
@@ -1,10 +1,10 @@
import type { MDXComponents } from 'mdx/types';
import defaultMdxComponents from '@fumadocs/base-ui/mdx';
import { Tab, Tabs } from '@fumadocs/base-ui/components/tabs';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { Step, Steps } from '@fumadocs/base-ui/components/steps';
import { File, Folder, Files } from '@fumadocs/base-ui/components/files';
import { Accordion, Accordions } from '@fumadocs/base-ui/components/accordion';
import defaultMdxComponents from '@hanzo/docs-base-ui/mdx';
import { Tab, Tabs } from '@hanzo/docs-base-ui/components/tabs';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { Step, Steps } from '@hanzo/docs-base-ui/components/steps';
import { File, Folder, Files } from '@hanzo/docs-base-ui/components/files';
import { Accordion, Accordions } from '@hanzo/docs-base-ui/components/accordion';
export function getMDXComponents(components?: MDXComponents): MDXComponents {
return {
+5 -5
View File
@@ -6,18 +6,18 @@
"build": "pnpm build:pre && next build --webpack && pnpm build:post",
"build:pre": "bun ./scripts/pre-build.ts",
"build:post": "bun ./scripts/post-build.ts",
"types:check": "fumadocs-mdx && next typegen && tsc --noEmit",
"types:check": "@hanzo/docs-mdx && next typegen && tsc --noEmit",
"clean": "rimraf .next",
"dev": "next dev --port 3006 --webpack",
"lint": "fumadocs-mdx && eslint .",
"lint": "@hanzo/docs-mdx && eslint .",
"start": "next start"
},
"dependencies": {
"@hanzo/mdx-runtime": "workspace:*",
"@hanzo/docs": "workspace:*",
"fumadocs-core": "workspace:*",
"fumadocs-mdx": "workspace:*",
"@fumadocs/base-ui": "workspace:*",
"@hanzo/docs-core": "workspace:*",
"@hanzo/docs-mdx": "workspace:*",
"@hanzo/docs-base-ui": "workspace:*",
"@radix-ui/react-tooltip": "^1.2.8",
"@shikijs/rehype": "^3.21.0",
"@shikijs/transformers": "^3.21.0",
+5 -5
View File
@@ -4,9 +4,9 @@ import {
defineDocs,
frontmatterSchema,
metaSchema,
} from 'fumadocs-mdx/config';
} from '@hanzo/docs-mdx/config';
import { z } from 'zod';
import lastModified from 'fumadocs-mdx/plugins/last-modified';
import lastModified from '@hanzo/docs-mdx/plugins/last-modified';
export const docs = defineDocs({
docs: {
@@ -19,10 +19,10 @@ export const docs = defineDocs({
},
async: true,
async mdxOptions(environment) {
const { rehypeCodeDefaultOptions } = await import('fumadocs-core/mdx-plugins/rehype-code');
const { rehypeCodeDefaultOptions } = await import('@hanzo/docs-core/mdx-plugins/rehype-code');
const { remarkStructureDefaultOptions } =
await import('fumadocs-core/mdx-plugins/remark-structure');
const { remarkSteps } = await import('fumadocs-core/mdx-plugins/remark-steps');
await import('@hanzo/docs-core/mdx-plugins/remark-structure');
const { remarkSteps } = await import('@hanzo/docs-core/mdx-plugins/remark-steps');
return applyMdxPreset({
remarkStructureOptions: {
+1 -1
View File
@@ -1,7 +1,7 @@
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import Link from 'next/link';
import type { TOCItemType } from 'fumadocs-core/toc';
import type { TOCItemType } from '@hanzo/docs-core/toc';
import { InlineTOC } from '@hanzo/docs/ui/components/inline-toc';
import { blog } from '@/lib/source';
import { createMetadata } from '@/lib/metadata';
+1 -1
View File
@@ -1,4 +1,4 @@
import { HomeLayout } from '@fumadocs/base-ui/layouts/home';
import { HomeLayout } from '@hanzo/docs-base-ui/layouts/home';
import { baseOptions, linkItems } from '@/components/layouts/shared';
import { TryHanzoDropdown } from '@/components/try-hanzo-dropdown';
import { Footer } from '@/components/footer';
+6 -6
View File
@@ -12,16 +12,16 @@ import ArkType from '@/public/showcases/arktype.png';
import AssistantUI from '@/public/showcases/assistant-ui.png';
import VisionUI from '@/public/showcases/vision-ui.png';
import Design from './design.png';
import Link from 'fumadocs-core/link';
import Link from '@hanzo/docs-core/link';
import MixSpace from '@/public/showcases/mix-space.png';
import TurboStarter from '@/public/showcases/turbostarter.png';
import HexaasBlog from '@/public/showcases/hexaas-blog.png';
export const metadata = createMetadata({
title: 'Showcase',
description: 'Some cool websites using Fumadocs',
description: 'Some cool websites using Hanzo Docs',
openGraph: {
url: 'https://fumadocs.dev/showcase',
url: 'https://docs.hanzo.ai/showcase',
},
});
@@ -328,7 +328,7 @@ export default function Showcase() {
<div className="relative overflow-hidden border border-dashed p-6">
<h1 className="mb-4 text-xl font-medium">The docs framework designed with care.</h1>
<p className="text-fd-muted-foreground">
A list of beautiful open-source projects with their docs powered by Fumadocs.
A list of beautiful open-source projects with their docs powered by Hanzo Docs.
</p>
<div className="mt-6">
<a
@@ -368,7 +368,7 @@ export default function Showcase() {
</svg>
<div>
<h2 className="text-sm font-medium mb-2">
Fumadocs powers the docs of Vercel open source SDKs.
Hanzo Docs powers the docs of Vercel open source SDKs.
</h2>
<div className="flex items-center gap-2 -mx-1.5">
{vercel.map((item) => (
@@ -407,7 +407,7 @@ export default function Showcase() {
</Link>
</div>
</div>
<h2 className="text-xl font-medium mt-12 px-4">Fumadocs can power your blog, too.</h2>
<h2 className="text-xl font-medium mt-12 px-4">Hanzo Docs can power your blog, too.</h2>
<div className="mt-6 grid gap-2.5 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
{blogs.map((showcase) => (
<ShowcaseItem key={showcase.url} {...showcase} />
+3 -3
View File
@@ -60,9 +60,9 @@ export default async function Page() {
height="536"
className="absolute top-16 z-[-1] w-full max-w-[1200px] opacity-0 dark:opacity-20"
/>
<h1 className="text-4xl font-semibold">Support Fumadocs</h1>
<h1 className="text-4xl font-semibold">Support Hanzo Docs</h1>
<p className="mt-4 text-sm">
Support the development work of Fumadocs. Fumadocs is fully open source, your sponsorship
Support the development work of Hanzo Docs. Hanzo Docs is fully open source, your sponsorship
means a lot.
</p>
<a
@@ -165,7 +165,7 @@ export default async function Page() {
}}
/>
<text dx="256" dy="147.793041" fontSize="18" fontWeight="400" fill="rgba(70,70,86,0.9)">
Fumadocs
Hanzo Docs
</text>
</svg>
<h2 className="mt-12 font-mono text-xs mb-7">Organization Sponsors</h2>
+2 -2
View File
@@ -10,7 +10,7 @@ export function UwuHero() {
<Image alt="logo" src={Logo} className="mb-6 w-full max-w-[400px] px-4" priority />
<p className="mb-6 h-fit p-2 text-lg text-fd-muted-foreground md:max-w-[80%] md:text-xl">
Fumadocs is the framework for building documentation with{' '}
Hanzo Docs is the framework for building documentation with{' '}
<b className="font-medium text-fd-foreground">anime and fuwa fuwa power</b>. Using the power
of weebs and waifus.
</p>
@@ -22,7 +22,7 @@ export function UwuHero() {
Getting Started
</Link>
<a
href="https://stackblitz.com/github/fuma-nama/fumadocs/tree/main/examples/stackblitz"
href="https://stackblitz.com/github/hanzoai/docs/tree/main/examples/stackblitz"
className={cn(
buttonVariants({
size: 'lg',
@@ -1,5 +1,5 @@
const owner = 'fuma-nama';
const repo = 'fumadocs';
const owner = 'hanzoai';
const repo = 'docs';
const versionPattern = /^16\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
interface GitObjectRef {
@@ -55,14 +55,14 @@ export async function GET(request: Request): Promise<Response> {
if (!versionPattern.test(version)) {
return Response.json(
{
error: 'Only fumadocs-ui versions around 16.x.x are supported',
error: 'Only @hanzo/docs-ui versions around 16.x.x are supported',
received: version,
},
{ status: 400 },
);
}
const tag = `fumadocs-ui@${version}`;
const tag = `@hanzo/docs-ui@${version}`;
try {
const commitSha = await resolveTagCommitSha(tag);
@@ -143,7 +143,7 @@ async function resolveTagCommitSha(tag: string): Promise<string | null> {
async function githubRequest<T>(path: string, options?: GitHubRequestOptions): Promise<T | null> {
const headers = new Headers({
Accept: 'application/vnd.github+json',
'User-Agent': 'fumadocs-docs-route',
'User-Agent': 'hanzo-docs-route',
'X-GitHub-Api-Version': '2022-11-28',
});
+1 -1
View File
@@ -1,4 +1,4 @@
import { source } from '@/lib/source';
import { flexsearchFromSource } from 'fumadocs-core/search/flexsearch';
import { flexsearchFromSource } from '@hanzo/docs-core/search/flexsearch';
export const { GET } = flexsearchFromSource(source);
+8 -8
View File
@@ -1,8 +1,8 @@
import type { Metadata } from 'next';
import { type ComponentProps, type FC, type ReactNode } from 'react';
import * as Twoslash from '@hanzo/docs-twoslash/ui';
import { Callout } from '@fumadocs/base-ui/components/callout';
import { TypeTable } from '@fumadocs/base-ui/components/type-table';
import { Callout } from '@hanzo/docs-base-ui/components/callout';
import { TypeTable } from '@hanzo/docs-base-ui/components/type-table';
import * as Preview from '@/components/preview';
import { createMetadata, getPageImage } from '@/lib/metadata';
import { source } from '@/lib/source';
@@ -11,11 +11,11 @@ import { Mermaid } from '@/components/mdx/mermaid';
import { PageFeedback, PageFeedbackBlock } from '@/components/feedback';
import { owner, repo } from '@/lib/github';
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card';
import Link from 'fumadocs-core/link';
import { findSiblings } from 'fumadocs-core/page-tree';
import { Card, Cards } from '@fumadocs/base-ui/components/card';
import Link from '@hanzo/docs-core/link';
import { findSiblings } from '@hanzo/docs-core/page-tree';
import { Card, Cards } from '@hanzo/docs-base-ui/components/card';
import { getMDXComponents } from '@/components/mdx';
import { Banner } from '@fumadocs/base-ui/components/banner';
import { Banner } from '@hanzo/docs-base-ui/components/banner';
import { Installation } from '@/components/preview/installation';
import { Customization } from '@/components/preview/customization';
import {
@@ -24,11 +24,11 @@ import {
PageLastUpdate,
MarkdownCopyButton,
ViewOptionsPopover,
} from '@fumadocs/base-ui/layouts/docs/page';
} from '@hanzo/docs-base-ui/layouts/docs/page';
import { NotFound } from '@/components/layouts/not-found';
import { MdxErrorBoundary } from '@/components/mdx-error-boundary';
import { getSuggestions } from './suggestions';
import { PathUtils } from 'fumadocs-core/source';
import { PathUtils } from '@hanzo/docs-core/source';
function PreviewRenderer({ preview }: { preview: string }): ReactNode {
if (preview && preview in Preview) {
+2 -2
View File
@@ -1,11 +1,11 @@
import { DocsLayout } from '@fumadocs/base-ui/layouts/docs';
import { DocsLayout } from '@hanzo/docs-base-ui/layouts/docs';
import { baseOptions, linkItems, logo } from '@/components/layouts/shared';
import { source } from '@/lib/source';
import { getSection } from '@/lib/source/navigation';
import { AISearch, AISearchPanel, AISearchTrigger } from '@/components/ai/search';
import { MessageCircleIcon } from 'lucide-react';
import { cn } from '@/lib/cn';
import { buttonVariants } from '@fumadocs/base-ui/components/ui/button';
import { buttonVariants } from '@hanzo/docs-base-ui/components/ui/button';
import { ProjectSwitcher } from '@/components/projects/project-switcher';
import { AuthButtons } from '@/components/auth-buttons';
import { TryHanzoDropdown } from '@/components/try-hanzo-dropdown';
+3 -3
View File
@@ -1,8 +1,8 @@
@import 'tailwindcss';
@import '@fumadocs/base-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
@import '@hanzo/docs-base-ui/css/neutral.css';
@import '@hanzo/docs-ui/css/preset.css';
@import '@hanzo/docs-twoslash/twoslash.css';
@import 'fumadocs-openapi/css/preset.css';
@import '@hanzo/docs-openapi/css/preset.css';
@import '@hanzo/docs-story/css/preset.css';
@plugin 'tailwindcss-animate';
+1 -1
View File
@@ -1,5 +1,5 @@
import { source } from '@/lib/source';
import { llms } from 'fumadocs-core/source';
import { llms } from '@hanzo/docs-core/source';
export const revalidate = false;
+1 -1
View File
@@ -28,7 +28,7 @@ export async function getImageResponseOptions(): Promise<ImageResponseOptions> {
}
export function generate({ title, description }: GenerateProps) {
const siteName = 'Fumadocs';
const siteName = 'Hanzo Docs';
const primaryTextColor = 'rgb(240,240,240)';
const logo = (
<svg width="60" height="60" viewBox="0 0 180 180" filter="url(#logo-shadow)">
+2 -2
View File
@@ -1,6 +1,6 @@
import { source } from '@/lib/source';
import type { OramaDocument } from 'fumadocs-core/search/orama-cloud';
import { getBreadcrumbItems } from 'fumadocs-core/breadcrumb';
import type { OramaDocument } from '@hanzo/docs-core/search/orama-cloud';
import { getBreadcrumbItems } from '@hanzo/docs-core/breadcrumb';
import { getSection } from '@/lib/source/navigation';
export const revalidate = false;
+2 -2
View File
@@ -13,7 +13,7 @@ import {
} from 'react';
import { Loader2, MessageCircleIcon, RefreshCw, SearchIcon, Send, X } from 'lucide-react';
import { cn } from '@/lib/cn';
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
import { buttonVariants } from '@hanzo/docs-ui/components/ui/button';
import { useChat, type UseChatHelpers } from '@ai-sdk/react';
import { DefaultChatTransport, type Tool, type UIMessage, type UIToolInvocation } from 'ai';
import { Markdown } from '../markdown';
@@ -261,7 +261,7 @@ function Input(props: ComponentProps<'textarea'>) {
const roleName: Record<string, string> = {
user: 'you',
assistant: 'fumadocs',
assistant: 'Hanzo Docs',
};
function Message({ message, ...props }: { message: ChatUIMessage } & ComponentProps<'div'>) {
+3 -3
View File
@@ -13,8 +13,8 @@ import {
} from 'react';
import { Loader2, MessageCircleIcon, RefreshCw, Send, X } from 'lucide-react';
import { cn } from '@/lib/cn';
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
import Link from 'fumadocs-core/link';
import { buttonVariants } from '@hanzo/docs-ui/components/ui/button';
import Link from '@hanzo/docs-core/link';
import { useChat, type UseChatHelpers } from '@ai-sdk/react';
import type { ProvideLinksToolSchema } from '@/lib/inkeep/inkeep-qa-schema';
import type { z } from 'zod';
@@ -257,7 +257,7 @@ function Input(props: ComponentProps<'textarea'>) {
const roleName: Record<string, string> = {
user: 'you',
assistant: 'fumadocs',
assistant: 'Hanzo Docs',
};
function Message({ message, ...props }: { message: InkeepUIMessage } & ComponentProps<'div'>) {
+1 -1
View File
@@ -1,6 +1,6 @@
import { openapi, hasSpecs } from '@/lib/openapi';
import { defaultShikiOptions } from '@/lib/shiki';
import { createAPIPage } from 'fumadocs-openapi/ui';
import { createAPIPage } from '@hanzo/docs-openapi/ui';
export const APIPage = hasSpecs
? createAPIPage(openapi, {
+2 -2
View File
@@ -1,6 +1,6 @@
import * as Base from '@fumadocs/base-ui/components/codeblock';
import * as Base from '@hanzo/docs-base-ui/components/codeblock';
import { cn } from '@/lib/cn';
import { highlight } from 'fumadocs-core/highlight';
import { highlight } from '@hanzo/docs-core/highlight';
import { shikiConfig } from '@/lib/shiki';
export interface CodeBlockProps {
+5 -5
View File
@@ -1,6 +1,6 @@
'use client';
import { cn } from '@/lib/cn';
import { buttonVariants } from '@fumadocs/base-ui/components/ui/button';
import { buttonVariants } from '@hanzo/docs-base-ui/components/ui/button';
import { CornerDownRightIcon, MessageSquare, ThumbsDown, ThumbsUp } from 'lucide-react';
import {
type HTMLAttributes,
@@ -12,11 +12,11 @@ import {
useState,
useTransition,
} from 'react';
import { Collapsible, CollapsibleContent } from '@fumadocs/base-ui/components/ui/collapsible';
import { Collapsible, CollapsibleContent } from '@hanzo/docs-base-ui/components/ui/collapsible';
import { cva } from 'class-variance-authority';
import { usePathname } from 'next/navigation';
import { Popover, PopoverContent, PopoverTrigger } from '@fumadocs/base-ui/components/ui/popover';
import type { FeedbackBlockProps } from 'fumadocs-core/mdx-plugins/remark-feedback-block';
import { Popover, PopoverContent, PopoverTrigger } from '@hanzo/docs-base-ui/components/ui/popover';
import type { FeedbackBlockProps } from '@hanzo/docs-core/mdx-plugins/remark-feedback-block';
import {
actionResponse,
blockFeedback,
@@ -26,7 +26,7 @@ import {
type PageFeedback,
} from './schema';
import { z } from 'zod/mini';
import { usePathname } from 'fumadocs-core/framework';
import { usePathname } from '@hanzo/docs-core/framework';
const rateButtonVariants = cva(
'inline-flex items-center gap-2 px-3 py-2 rounded-full font-medium border text-sm [&_svg]:size-4 disabled:cursor-not-allowed',
+1 -1
View File
@@ -1,7 +1,7 @@
'use client';
import type { ReactNode } from 'react';
import type { FeedbackBlockProps } from 'fumadocs-core/mdx-plugins/remark-feedback-block';
import type { FeedbackBlockProps } from '@hanzo/docs-core/mdx-plugins/remark-feedback-block';
import { Feedback as FeedbackInner, FeedbackBlock as FeedbackBlockInner } from './client';
import type { ActionResponse, BlockFeedback, PageFeedback } from './schema';
+3 -3
View File
@@ -5,7 +5,7 @@ import {
NavigationPanel,
NavigationPanelOverlay,
NavigationPanelProps,
} from '@fumadocs/base-ui/layouts/flux';
} from '@hanzo/docs-base-ui/layouts/flux';
import {
AISearch,
AISearchInput,
@@ -16,10 +16,10 @@ import {
useHotKey,
} from '@/components/ai/search';
import { MessageCircleIcon } from 'lucide-react';
import { buttonVariants } from '@fumadocs/base-ui/components/ui/button';
import { buttonVariants } from '@hanzo/docs-base-ui/components/ui/button';
import { cn } from '@/lib/cn';
import { AnimatePresence, motion } from 'motion/react';
import { useSidebar } from '@fumadocs/base-ui/components/sidebar/base';
import { useSidebar } from '@hanzo/docs-base-ui/components/sidebar/base';
import { useEffect, useState } from 'react';
export function LayoutClient(props: DocsLayoutProps) {
+2 -2
View File
@@ -1,10 +1,10 @@
import { baseOptions, linkItems, logo } from '@/components/layouts/shared';
import { source } from '@/lib/source';
import { getSection } from '@/lib/source/navigation';
import { getSidebarTabs } from '@fumadocs/base-ui/components/sidebar/tabs/index';
import { getSidebarTabs } from '@hanzo/docs-base-ui/components/sidebar/tabs/index';
import type { ReactNode } from 'react';
import { LayoutClient } from './client';
import { getLayoutTabs } from 'fumadocs-ui/layouts/shared';
import { getLayoutTabs } from '@hanzo/docs-ui/layouts/shared';
export function FluxLayout({ children }: { children: ReactNode }) {
const base = baseOptions();
+1 -1
View File
@@ -15,7 +15,7 @@ import {
} from '@hanzo/docs/ui/components/dialog/search';
import { useDocsSearch } from '@hanzo/docs/core/search/client';
import { useMemo, useState } from 'react';
import { Popover, PopoverContent, PopoverTrigger } from '@fumadocs/base-ui/components/ui/popover';
import { Popover, PopoverContent, PopoverTrigger } from '@hanzo/docs-base-ui/components/ui/popover';
import { ArrowRight, ChevronDown } from 'lucide-react';
import { buttonVariants } from '@hanzo/docs/ui/components/ui/button';
import { cn } from '@/lib/cn';
+5 -5
View File
@@ -1,9 +1,9 @@
import defaultMdxComponents from 'fumadocs-ui/mdx';
import { Files, File, Folder } from 'fumadocs-ui/components/files';
import { Tabs, Tab, TabsContent, TabsList, TabsTrigger } from 'fumadocs-ui/components/tabs';
import { Steps, Step } from 'fumadocs-ui/components/steps';
import defaultMdxComponents from '@hanzo/docs-ui/mdx';
import { Files, File, Folder } from '@hanzo/docs-ui/components/files';
import { Tabs, Tab, TabsContent, TabsList, TabsTrigger } from '@hanzo/docs-ui/components/tabs';
import { Steps, Step } from '@hanzo/docs-ui/components/steps';
import type { MDXComponents } from 'mdx/types';
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
import { Accordion, Accordions } from '@hanzo/docs-ui/components/accordion';
import * as icons from 'lucide-react';
export function getMDXComponents(components?: MDXComponents): MDXComponents {
@@ -1,4 +1,4 @@
import { ServerCodeBlock } from 'fumadocs-ui/components/codeblock.rsc';
import { ServerCodeBlock } from '@hanzo/docs-ui/components/codeblock.rsc';
export function Customization() {
return (
@@ -1,5 +1,5 @@
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@fumadocs/base-ui/components/ui/tabs';
import { ServerCodeBlock } from 'fumadocs-ui/components/codeblock.rsc';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@hanzo/docs-base-ui/components/ui/tabs';
import { ServerCodeBlock } from '@hanzo/docs-ui/components/codeblock.rsc';
export function Installation({ name }: { name: string }) {
const tabs = [{ name: 'Hanzo Docs CLI', value: 'hanzo-docs-cli' }];
+6 -6
View File
@@ -3,20 +3,20 @@ import dynamic from 'next/dynamic';
export const DynamicCodeBlock = dynamic(() => import('./dynamic-codeblock'));
export const Banner = dynamic(() =>
import('@fumadocs/base-ui/components/banner').then((res) => res.Banner),
import('@hanzo/docs-base-ui/components/banner').then((res) => res.Banner),
);
export const InlineTOC = dynamic(() =>
import('@fumadocs/base-ui/components/inline-toc').then((res) => res.InlineTOC),
import('@hanzo/docs-base-ui/components/inline-toc').then((res) => res.InlineTOC),
);
export const File = dynamic(() => import('@fumadocs/base-ui/components/files').then((res) => res.File));
export const Files = dynamic(() => import('@fumadocs/base-ui/components/files').then((res) => res.Files));
export const File = dynamic(() => import('@hanzo/docs-base-ui/components/files').then((res) => res.File));
export const Files = dynamic(() => import('@hanzo/docs-base-ui/components/files').then((res) => res.Files));
export const Folder = dynamic(() =>
import('@fumadocs/base-ui/components/files').then((res) => res.Folder),
import('@hanzo/docs-base-ui/components/files').then((res) => res.Folder),
);
export const ImageZoom = dynamic(() =>
import('@fumadocs/base-ui/components/image-zoom').then((res) => res.ImageZoom),
import('@hanzo/docs-base-ui/components/image-zoom').then((res) => res.ImageZoom),
);
export const GraphView = dynamic(() =>
+9 -9
View File
@@ -35,25 +35,25 @@ export const compileOptions: Partial<CompileOptions> = {
file = path.relative(radixUi.registry.dir, ref.file);
if (file.startsWith('contexts/') || file.startsWith('utils/use-')) {
return {
dep: 'fumadocs-ui',
dep: '@hanzo/docs-ui',
type: 'dependency',
specifier: `fumadocs-ui/${removeExtname(file)}`,
specifier: `@hanzo/docs-ui/${removeExtname(file)}`,
};
}
file = path.relative(baseUi.registry.dir, ref.file);
if (file.startsWith('contexts/') || file.startsWith('utils/use-')) {
return {
dep: '@fumadocs/base-ui',
dep: '@hanzo/docs-base-ui',
type: 'dependency',
specifier: `@fumadocs/base-ui/${removeExtname(file)}`,
specifier: `@hanzo/docs-base-ui/${removeExtname(file)}`,
};
}
}
// map dep imports to actual components
if (ref.type === 'dependency' && ref.dep === 'fumadocs-ui') {
const match = /fumadocs-ui\/components\/ui\/(.*)/.exec(ref.specifier);
if (ref.type === 'dependency' && ref.dep === '@hanzo/docs-ui') {
const match = /@hanzo/docs-ui\/components\/ui\/(.*)/.exec(ref.specifier);
if (match) {
return {
@@ -69,7 +69,7 @@ export const compileOptions: Partial<CompileOptions> = {
export const registry: Registry = {
dir: baseDir,
name: 'fumadocs',
name: 'Hanzo Docs',
subRegistries: [radixUi.registry, baseUi.registry, sanity.registry],
components: [
@@ -228,8 +228,8 @@ export const registry: Registry = {
},
],
dependencies: {
'fumadocs-core': null,
'fumadocs-ui': null,
'@hanzo/docs-core': null,
'@hanzo/docs-ui': null,
'lucide-react': null,
next: null,
react: null,
@@ -1,12 +1,12 @@
'use client';
import type * as PageTree from 'fumadocs-core/page-tree';
import type * as PageTree from '@hanzo/docs-core/page-tree';
import { type ComponentProps, createContext, type ReactNode, use, useMemo, useState } from 'react';
import { cn } from '@/lib/cn';
import { TreeContextProvider, useTreeContext } from '@fumadocs/base-ui/contexts/tree';
import Link from 'fumadocs-core/link';
import { useSearchContext } from '@fumadocs/base-ui/contexts/search';
import { TreeContextProvider, useTreeContext } from '@hanzo/docs-base-ui/contexts/tree';
import Link from '@hanzo/docs-core/link';
import { useSearchContext } from '@hanzo/docs-base-ui/contexts/search';
import { cva } from 'class-variance-authority';
import { usePathname } from 'fumadocs-core/framework';
import { usePathname } from '@hanzo/docs-core/framework';
interface SidebarContext {
open: boolean;
@@ -1,10 +1,10 @@
'use client';
import { type ComponentProps, type ReactNode, useMemo } from 'react';
import { AnchorProvider, type TOCItemType, useActiveAnchors } from 'fumadocs-core/toc';
import { AnchorProvider, type TOCItemType, useActiveAnchors } from '@hanzo/docs-core/toc';
import { cn } from '@/lib/cn';
import { useTreeContext } from '@fumadocs/base-ui/contexts/tree';
import { Link, usePathname } from 'fumadocs-core/framework';
import type * as PageTree from 'fumadocs-core/page-tree';
import { useTreeContext } from '@hanzo/docs-base-ui/contexts/tree';
import { Link, usePathname } from '@hanzo/docs-core/framework';
import type * as PageTree from '@hanzo/docs-core/page-tree';
export interface DocsPageProps {
toc?: TOCItemType[];
+10 -10
View File
@@ -1,13 +1,13 @@
---
title: The early mistake of Fumadocs
title: The early mistake of Hanzo Docs
description: What we failed at to deliver better DX.
author: Fuma Nama
author: Hanzo Nama
date: 2025-08-22
---
## A Mistake
The early mistake of Fumadocs was **Fumadocs CLI being too late and not getting enough mentions on docs**.
The early mistake of Hanzo Docs was **Hanzo Docs CLI being too late and not getting enough mentions on docs**.
To push the CLI approach further like the recent Shadcn CLI support, there are changes we have to make.
Early adopters will face problems if their customizations went beyond what our abstraction can mitigate.
@@ -24,7 +24,7 @@ Early adopters will face problems if their customizations went beyond what our a
For CLI to work better, we need layout components to be entirely independent for modularization. A ideal state is that:
- Normal users can use exposed options, enjoying UI iterations from upstream.
- Advanced customizations can use Fumadocs CLI, avoiding upstream changes.
- Advanced customizations can use Hanzo Docs CLI, avoiding upstream changes.
Same as the solution described in [this post about UI Customization](/blog/customise-ui#the-solution).
@@ -40,7 +40,7 @@ Some problems I observed:
#### Page Tree API being Neglected
Page tree is actually a crucial idea of Fumadocs, unifying all navigation & linking of docs.
Page tree is actually a crucial idea of Hanzo Docs, unifying all navigation & linking of docs.
Even in the early days, it's already a robust API supporting features like Root Folder (since v12):
@@ -53,7 +53,7 @@ Some projects didn't rely on our file-based routing nor page tree API, which res
Its idea is simple:
```txt tab="Server"
files -> Fumadocs -> page tree
files -> Hanzo Docs -> page tree
```
```txt tab="Client"
@@ -64,7 +64,7 @@ Using it properly can already reduce a massive amount of work, we have [a specs
#### CSS Variables being Neglected
Fumadocs is using CSS variables for all colors since the beginning, the naming is identical to Shadcn UI which makes customization easy.
Hanzo Docs is using CSS variables for all colors since the beginning, the naming is identical to Shadcn UI which makes customization easy.
But I noticed some are overriding the Tailwind CSS **classes** rather than **colors**, like:
@@ -90,9 +90,9 @@ I think the CLI approach is correct, it'll be the primary way for advanced custo
My future plans:
- **Continue improving Fumadocs CLI:** adding install-time optimization to remove unused files according to your options (e.g. use existing sidebar component instead of installing one).
- **A better versioning policy:** Reduce abstraction for mitigating upstream changes, instead version the components directly (e.g. creating a new `fumadocs-ui/layouts/v2/page` instead of a major UI change).
- **Add Fumadocs-native cloud features:** More official integrations like monitoring/analytics feature designed for Fumadocs.
- **Continue improving Hanzo Docs CLI:** adding install-time optimization to remove unused files according to your options (e.g. use existing sidebar component instead of installing one).
- **A better versioning policy:** Reduce abstraction for mitigating upstream changes, instead version the components directly (e.g. creating a new `@hanzo/docs-ui/layouts/v2/page` instead of a major UI change).
- **Add Hanzo Docs-native cloud features:** More official integrations like monitoring/analytics feature designed for Hanzo Docs.
My biggest goal is to build my own dev team or startup, I realized my time is too limited to build the excellent software in my imaginary.
There's rough edges that I never found time to polish, and too many things to do - even if AI has handled the basic work.
+13 -13
View File
@@ -1,7 +1,7 @@
---
title: Rethink how we customize UI
description: Deep dive on how Fumadocs UI is designed
author: Fuma Nama
description: Deep dive on how Hanzo Docs UI is designed
author: Hanzo Nama
date: 2025-04-15
---
@@ -21,7 +21,7 @@ Eventually, **Shadcn-like design became the default styles**, so once again, we
### What should we do?
As a docs framework started from **"being flexible"**, Fumadocs must be customisable, tuned to meet developers' preferences.
As a docs framework started from **"being flexible"**, Hanzo Docs must be customisable, tuned to meet developers' preferences.
We will need to take customization seriously if DX is what we aim. And most importantly, **it should encourage developers with a sense of beauty to customize.**
## The Solution
@@ -30,16 +30,16 @@ Typically, there are two types of developers:
### those who want docs that just work
Fumadocs need to be opinionated by default such that it is immediately usable, and we only have to offer simplest options to change details. (e.g. colors, overriding components).
Hanzo Docs need to be opinionated by default such that it is immediately usable, and we only have to offer simplest options to change details. (e.g. colors, overriding components).
Most developers have no desire to install dozens of components just to change a tiny detail, which makes the Shadcn approach suboptimal.
### those who need the perfect docs tailored to their preferences
The kernel of Fumadocs, or the spirit we're pursuing is the latter one. I crafted Fumadocs CLI, a version of Shadcn UI dedicated for Fumadocs, the whole solution is now simplified into a single command:
The kernel of Hanzo Docs, or the spirit we're pursuing is the latter one. I crafted Hanzo Docs CLI, a version of Shadcn UI dedicated for Hanzo Docs, the whole solution is now simplified into a single command:
```package-install
npx @fumadocs/cli customize
npx @hanzo/docs-cli customize
```
It accounts for two types:
@@ -54,20 +54,20 @@ The latter one is simpler, we can offer the minimal template they can start cust
This methodology, inspired by ejection, brings some nice advantages:
#### Don't break anything when you upgrade Fumadocs
#### Don't break anything when you upgrade Hanzo Docs
Fumadocs need to be opinionated. Hence, we need to iterate the UI frequently which apparently will break people's hacky customizations.
The charm of Fumadocs CLI is that once you've installed the layout, it stays the same forever regardless of future iterations on Fumadocs UI.
Hanzo Docs need to be opinionated. Hence, we need to iterate the UI frequently which apparently will break people's hacky customizations.
The charm of Hanzo Docs CLI is that once you've installed the layout, it stays the same forever regardless of future iterations on Hanzo Docs UI.
It gives the courage for Fumadocs UI to iterate, and developers to customize unburnt by the fear of upgrading dependencies.
It gives the courage for Hanzo Docs UI to iterate, and developers to customize unburnt by the fear of upgrading dependencies.
#### Looks Clean
Just like Shadcn UI and Radix UI, Fumadocs UI has a core package (`fumadocs-core`), most generic logic will be abstracted by core.
Just like Shadcn UI and Radix UI, Hanzo Docs UI has a core package (`@hanzo/docs-core`), most generic logic will be abstracted by core.
## What is Next?
The innovation of Shadcn UI is amazing, yet, I believe there's more problems Fumadocs can solve.
The innovation of Shadcn UI is amazing, yet, I believe there's more problems Hanzo Docs can solve.
See [Flags SDK](https://flags-sdk.dev/frameworks/next) and [BetterAuth](https://www.better-auth.com/docs/introduction), you can't tell at the first glance if they're powered by Fumadocs.
See [Flags SDK](https://flags-sdk.dev/frameworks/next) and [BetterAuth](https://www.better-auth.com/docs/introduction), you can't tell at the first glance if they're powered by Hanzo Docs.
I hope it can continue to be a "breakable" framework known for how customisable it is.
+4 -4
View File
@@ -1,7 +1,7 @@
---
title: Making a Blog with Hanzo Docs
description: Hanzo Docs + Blog
author: Fuma Nama
author: Hanzo Nama
date: 2024-12-15
---
@@ -37,12 +37,12 @@ Parse the output collection in `source.ts`:
```ts title="lib/source.ts"
import { loader } from '@hanzo/docs-core/source';
import { toFumadocsSource } from '@hanzo/docs-mdx/runtime/server';
import { toHanzoDocsSource } from '@hanzo/docs-mdx/runtime/server';
import { blogPosts } from 'collections/server';
export const blog = loader({
baseUrl: '/blog',
source: toFumadocsSource(blogPosts, []),
source: toHanzoDocsSource(blogPosts, []),
});
```
@@ -166,7 +166,7 @@ The UI is now complete, you can write some blog posts under the `content/blog` d
```mdx title="content/blog/hello.mdx"
---
title: Hello World
author: Fuma Nama
author: Hanzo Nama
date: 2024-12-15
---
+19 -19
View File
@@ -1,8 +1,8 @@
---
title: Fumadocs MDX v10 Summary
title: Hanzo Docs MDX v10 Summary
description: Migration Guide and Summary
date: 2024-11-24
author: Fuma Nama
author: Hanzo Nama
---
## Features
@@ -21,7 +21,7 @@ Refactor the import in `next.config`.
**From:**
```ts
import createMDX from 'fumadocs-mdx/config';
import createMDX from '@hanzo/docs-mdx/config';
const withMDX = createMDX();
@@ -36,7 +36,7 @@ export default withMDX(config);
**To:**
```ts
import { createMDX } from 'fumadocs-mdx/next';
import { createMDX } from '@hanzo/docs-mdx/next';
const withMDX = createMDX();
@@ -53,7 +53,7 @@ export default withMDX(config);
`mdx-components.tsx` is no longer used. It now allows only MDX components passed from `MDX` body's `components` prop.
```tsx
import defaultMdxComponents from 'fumadocs-ui/mdx';
import defaultMdxComponents from '@hanzo/docs-ui/mdx';
const MDX = page.data.body;
@@ -76,7 +76,7 @@ Every collection has its own config, you can have customized Zod schema to valid
You can create a source config file, and add the following:
```ts
import { defineDocs } from 'fumadocs-mdx/config';
import { defineDocs } from '@hanzo/docs-mdx/config';
export const { docs, meta } = defineDocs({
dir: 'content/docs',
@@ -85,12 +85,12 @@ export const { docs, meta } = defineDocs({
`defineDocs` declares two collections, one with `doc` type that scans content files (e.g. `md/mdx`), one with `meta` type that scans meta files (e.g. `json`).
Now you can generate types using `fumadocs-mdx` command, it's recommended to set it as a `postinstall` script.
Now you can generate types using `@hanzo/docs-mdx` command, it's recommended to set it as a `postinstall` script.
```json title="package.json"
{
"scripts": {
"postinstall": "fumadocs-mdx"
"postinstall": "@hanzo/docs-mdx"
}
}
```
@@ -104,12 +104,12 @@ To access the collections, import them from the folder with their original name
import { docs, meta } from '@/.source';
```
Now to integrate it with Fumadocs framework, change your `source.ts` from:
Now to integrate it with Hanzo Docs framework, change your `source.ts` from:
```ts
import { map } from '@/.map';
import { createMDXSource } from 'fumadocs-mdx/runtime/next';
import { loader } from 'fumadocs-core/source';
import { createMDXSource } from '@hanzo/docs-mdx/runtime/next';
import { loader } from '@hanzo/docs-core/source';
export const { getPage, getPages, pageTree } = loader({
baseUrl: '/docs',
@@ -122,8 +122,8 @@ to:
```ts
import { docs, meta } from '@/.source';
import { createMDXSource } from 'fumadocs-mdx/runtime/next';
import { loader } from 'fumadocs-core/source';
import { createMDXSource } from '@hanzo/docs-mdx/runtime/next';
import { loader } from '@hanzo/docs-core/source';
export const source = loader({
baseUrl: '/docs',
@@ -151,7 +151,7 @@ page.data.title; // [!code ++]
Instead of passing them to `next.config` file, define a global config in `source.config.ts`:
```ts
import { defineConfig } from 'fumadocs-mdx/config';
import { defineConfig } from '@hanzo/docs-mdx/config';
export default defineConfig({
mdxOptions: {
@@ -171,8 +171,8 @@ For `defineDocs`, see [`schema`](/docs/mdx/collections#schema-1).
Same as before, you can call `loader` multiple times for different types (e.g. for docs and blog).
```ts
import { createMDXSource } from 'fumadocs-mdx/runtime/next';
import { loader } from 'fumadocs-core/source';
import { createMDXSource } from '@hanzo/docs-mdx/runtime/next';
import { loader } from '@hanzo/docs-core/source';
import { meta, docs, blog as blogPosts } from '@/.source';
export const source = loader({
@@ -193,7 +193,7 @@ export type DocsMeta = (typeof source)['$inferMeta'];
and the corresponding `source.config.ts`:
```ts
import { defineDocs, defineCollections, frontmatterSchema } from 'fumadocs-mdx/config';
import { defineDocs, defineCollections, frontmatterSchema } from '@hanzo/docs-mdx/config';
import { z } from 'zod';
export const { docs, meta } = defineDocs({
@@ -212,10 +212,10 @@ export const blog = defineCollections({
### Further Readings
You can read the latest docs of Fumadocs MDX for details.
You can read the latest docs of Hanzo Docs MDX for details.
<Cards>
<Card href="/docs/mdx" title="Fumadocs MDX">
<Card href="/docs/mdx" title="Hanzo Docs MDX">
The built-in content source, build a better content experience on Next.js.
</Card>
</Cards>
+8 -8
View File
@@ -1,7 +1,7 @@
---
title: Hanzo Docs MDX 14
description: Performance Improvements & API redesign.
author: Fuma Nama
author: Hanzo Nama
date: 2025-11-16
---
@@ -50,7 +50,7 @@ import { docs } from 'collections/server';
import { loader } from '@hanzo/docs-core/source';
export const source = loader({
source: docs.toFumadocsSource(),
source: docs.toHanzoDocsSource(),
});
```
@@ -123,17 +123,17 @@ export const source = loader({
// [!code --]
source: await create.sourceAsync(docs.doc, docs.meta),
// [!code ++]
source: docs.toFumadocsSource(),
source: docs.toHanzoDocsSource(),
});
```
For `doc` collections, `createMDXSource()` (Next.js) is renamed to `toFumadocsSource()`.
For `doc` collections, `createMDXSource()` (Next.js) is renamed to `toHanzoDocsSource()`.
If you use `create.sourceAsync()` (Vite) for `doc` collections, you should also switch to `toFumadocsSource()`.
If you use `create.sourceAsync()` (Vite) for `doc` collections, you should also switch to `toHanzoDocsSource()`.
```ts
import { blogPosts } from 'collections/server';
import { toFumadocsSource } from '@hanzo/docs-mdx/runtime/server';
import { toHanzoDocsSource } from '@hanzo/docs-mdx/runtime/server';
import { loader } from '@hanzo/docs-core/source';
export const blog = loader({
@@ -143,7 +143,7 @@ export const blog = loader({
// [!code --] for Vite
source: await create.sourceAsync(blogPosts, []),
// [!code ++]
source: toFumadocsSource(blogPosts, []),
source: toHanzoDocsSource(blogPosts, []),
});
```
@@ -257,7 +257,7 @@ import { defineDocs } from '@hanzo/docs-mdx/config';
export const docs = defineDocs({
dir: 'content/guides',
docs: {
files: ['./i-love-fumadocs/**/*.{md,mdx}'],
files: ['./i-love-hanzo-docs/**/*.{md,mdx}'],
},
});
```
+4 -4
View File
@@ -1,7 +1,7 @@
---
title: Fumadocs MDX 15
description: Bump minimum Fumadocs version.
author: Fuma Nama
title: Hanzo Docs MDX 15
description: Bump minimum Hanzo Docs version.
author: Hanzo Nama
date: 2026-05-07
---
@@ -9,7 +9,7 @@ date: 2026-05-07
This is a boring major release mainly to reduce package size. Breaking changes:
- `fumadocs-core` must be `16.7.0` or above.
- `@hanzo/docs-core` must be `16.7.0` or above.
- `next.config` must be ESM.
For Next.js users, if you encounter any error when upgrading, it could be due to ESM compatibility issues, you might be accidentally using CommonJS in `next.config`.
+4 -4
View File
@@ -1,8 +1,8 @@
---
title: Fumadocs OpenAPI v9
title: Hanzo Docs OpenAPI v9
description: Better UI & DX
date: 2025-05-25
author: Fuma Nama
author: Hanzo Nama
---
## Overview
@@ -42,7 +42,7 @@ The behaviour of `groupBy` API is also changed.
The usage of `name` option is renewed, it can be used to customize the output path of files.
```ts
import { generateFiles } from 'fumadocs-openapi';
import { generateFiles } from '@hanzo/docs-openapi';
void generateFiles({
name: (output, document) => {
@@ -60,7 +60,7 @@ void generateFiles({
You can start using the latest algorithm, or keep the current behaviour with:
```ts
import { generateFiles } from 'fumadocs-openapi';
import { generateFiles } from '@hanzo/docs-openapi';
void generateFiles({
name: {
+13 -13
View File
@@ -1,7 +1,7 @@
---
title: Fumadocs v15
title: Hanzo Docs v15
description: Tailwind CSS v4
author: Fuma Nama
author: Hanzo Nama
date: 2025-01-24
---
@@ -10,22 +10,22 @@ date: 2025-01-24
The purpose of v15 is mainly to support Tailwind CSS v4.
Tailwind CSS v4 is a complete redesign of its API and internals, to fully adhere to the new CSS-first config style, a breaking change is required.
Fumadocs v15 has no other significant changes other than migrating the config to Tailwind CSS v4.
Hanzo Docs v15 has no other significant changes other than migrating the config to Tailwind CSS v4.
## Breaking Changes
Before making the switch, upgrade your site to Tailwind CSS v4 following their [upgrade guide](https://tailwindcss.com/docs/upgrade-guide).
You can remove the unused `tailwind.config.js` file and fully rely on the new CSS-first config.
Add `@import` to the presets exported by Fumadocs UI, and include the `fumadocs-ui` package in the source.
Add `@import` to the presets exported by Hanzo Docs UI, and include the `@hanzo/docs-ui` package in the source.
```css title="Tailwind CSS"
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
@import '@hanzo/docs-ui/css/neutral.css';
@import '@hanzo/docs-ui/css/preset.css';
/* relative to the CSS file, make sure it's correct for your app */
@source '../node_modules/fumadocs-ui/dist/**/*.js';
@source '../node_modules/@hanzo/docs-ui/dist/**/*.js';
```
Since v15, you will no longer pass options in JavaScript to customize plugins.
@@ -44,7 +44,7 @@ Forward the colors again:
### CSS Variables
Fumadocs no longer use `--fd-<color>` like `--fd-primary: 0 0% 0%` for colors, it directly defines and uses colors in `@theme`.
Hanzo Docs no longer use `--fd-<color>` like `--fd-primary: 0 0% 0%` for colors, it directly defines and uses colors in `@theme`.
Instead of the previous format, it uses `hsl()`:
```css
@@ -109,13 +109,13 @@ The rest item `...` in the `pages` property of `meta.json` now supports reversed
### OpenAPI Playground
v15 improves the playground UI (inspired by the minimalism of Scalar), and brought Scalar API Client support to Fumadocs OpenAPI.
v15 improves the playground UI (inspired by the minimalism of Scalar), and brought Scalar API Client support to Hanzo Docs OpenAPI.
You can enable the Scalar API Client using `useScalar` option in `createOpenAPI()`:
```ts
import { createOpenAPI } from 'fumadocs-openapi/server';
import { APIPlayground } from 'fumadocs-openapi/scalar';
import { createOpenAPI } from '@hanzo/docs-openapi/server';
import { APIPlayground } from '@hanzo/docs-openapi/scalar';
export const openapi = createOpenAPI({
renderer: {
@@ -135,7 +135,7 @@ And install & configure their `@scalar/api-client-react`:
```
<Callout>
Be careful that you must configure Tailwind CSS first, using the pre-built stylesheet of Fumadocs
Be careful that you must configure Tailwind CSS first, using the pre-built stylesheet of Hanzo Docs
UI will conflict with their `style.css` because both libraries use Tailwind CSS for styling.
</Callout>
@@ -143,7 +143,7 @@ And install & configure their `@scalar/api-client-react`:
This update should be a simple migration for most developers updating to Tailwind CSS v4.
In the future, we also want to make further improvements to Fumadocs MDX:
In the future, we also want to make further improvements to Hanzo Docs MDX:
- remove `transform` API - you can easily do the same with `.map()` on runtime like:
+27 -27
View File
@@ -1,17 +1,17 @@
---
title: Fumadocs 16.2
title: Hanzo Docs 16.2
description: UI Refactor
author: Fuma Nama
author: Hanzo Nama
date: 2025-11-29
---
We are pleased to announce the release of Fumadocs 16.2, introducing a better layout system for Fumadocs UI.
We are pleased to announce the release of Hanzo Docs 16.2, introducing a better layout system for Hanzo Docs UI.
## The New Layout System
Handling layouts in documentation frameworks can present significant challenges.
As a solution, Fumadocs UI implemented a [Grid System](/docs/ui/layouts/docs#the-layout-system) that is composable, flexible, cohesive and predictable.
As a solution, Hanzo Docs UI implemented a [Grid System](/docs/ui/layouts/docs#the-layout-system) that is composable, flexible, cohesive and predictable.
See the linked docs for more details.
In short, the layout consists of a grid container, and layout components using `position: sticky`:
@@ -48,7 +48,7 @@ Layout components are also responsible to declare their heights via CSS variable
}
```
For user-land customizations, we recommend the Fumadocs CLI customize command, or hooking the relevant grid areas like:
For user-land customizations, we recommend the Hanzo Docs CLI customize command, or hooking the relevant grid areas like:
```css
.custom-component {
@@ -59,7 +59,7 @@ For user-land customizations, we recommend the Fumadocs CLI customize command, o
### Why the Change?
Previously, Fumadocs UI relied on `position: fixed` and mathematical computations (inspired by Vitepress). The older method often lacked composability and difficult for beginners to manage.
Previously, Hanzo Docs UI relied on `position: fixed` and mathematical computations (inspired by Vitepress). The older method often lacked composability and difficult for beginners to manage.
The new system fixed most of the flaws, allowing easier visualizations, while reducing the complexity of previous solutions.
@@ -67,53 +67,53 @@ The new system fixed most of the flaws, allowing easier visualizations, while re
### Global Styles
While Fumadocs 16.2 preserves compatibility in several areas, notably:
While Hanzo Docs 16.2 preserves compatibility in several areas, notably:
- The `--fd-layout-width` CSS variable continues to function as expected.
- All ID and data attributes remain unchanged.
However, the shift to the new grid system may impact existing customizations, particularly those dependent on the prior fixed-position logic. We recommend reviewing your implementation carefully and testing thoroughly.
If you have already installed layout components via Fumadocs CLI, replace `preset.css` with `preset-legacy.css` to keep legacy styles & avoid unexpected breakages:
If you have already installed layout components via Hanzo Docs CLI, replace `preset.css` with `preset-legacy.css` to keep legacy styles & avoid unexpected breakages:
```css title="global.css"
/* [!code --] */
@import 'fumadocs-ui/css/preset.css';
@import '@hanzo/docs-ui/css/preset.css';
/* [!code ++] */
@import 'fumadocs-ui/css/preset-legacy.css';
@import '@hanzo/docs-ui/css/preset-legacy.css';
```
### No Longer Exposing Internal Components
Layout components such as Root Toggle, Language Toggle, and Theme Toggle are no longer directly exposed.
This decision enables Fumadocs UI to iterate these elements without introducing unexpected breaking changes to usage outside of API surfaces.
This decision enables Hanzo Docs UI to iterate these elements without introducing unexpected breaking changes to usage outside of API surfaces.
**Migration Steps:** Override the relevant layout components with your own implementations, or utilize the Fumadocs CLI commands (`add` or `customize`) to install them locally.
**Migration Steps:** Override the relevant layout components with your own implementations, or utilize the Hanzo Docs CLI commands (`add` or `customize`) to install them locally.
### Removal of Internal Contexts
The following context modules are made private:
- `fumadocs-ui/contexts/sidebar`
- `fumadocs-ui/contexts/layout`
- `@hanzo/docs-ui/contexts/sidebar`
- `@hanzo/docs-ui/contexts/layout`
If you have already installed `<DocsLayout />` via Fumadocs CLI, import the legacy contexts instead:
If you have already installed `<DocsLayout />` via Hanzo Docs CLI, import the legacy contexts instead:
```ts
// [!code --:2]
import {} from 'fumadocs-ui/contexts/sidebar';
import {} from 'fumadocs-ui/contexts/layout';
import {} from '@hanzo/docs-ui/contexts/sidebar';
import {} from '@hanzo/docs-ui/contexts/layout';
// [!code ++:2]
import {} from 'fumadocs-ui/legacy/sidebar';
import {} from 'fumadocs-ui/legacy/layout';
import {} from '@hanzo/docs-ui/legacy/sidebar';
import {} from '@hanzo/docs-ui/legacy/layout';
```
And wrap your app under the legacy `<SidebarProvider />`:
```tsx
import type { ReactNode } from 'react';
import { SidebarProvider } from 'fumadocs-ui/legacy/sidebar';
import { SidebarProvider } from '@hanzo/docs-ui/legacy/sidebar';
export function RootLayout({ children }: { children: ReactNode }) {
return <SidebarProvider>{children}</SidebarProvider>;
@@ -123,13 +123,13 @@ export function RootLayout({ children }: { children: ReactNode }) {
<Callout title="What if I still use built-in layouts?">
The legacy contexts are made exclusively for layout components installed locally. If you still
import layout components (e.g. `<DocsLayout />`) from `fumadocs-ui`, migrate your usages as follows:
import layout components (e.g. `<DocsLayout />`) from `@hanzo/docs-ui`, migrate your usages as follows:
```tsx
// [!code --]
import { useSidebar } from 'fumadocs-ui/contexts/sidebar';
import { useSidebar } from '@hanzo/docs-ui/contexts/sidebar';
// [!code ++]
import { useSidebar } from 'fumadocs-ui/components/sidebar/base';
import { useSidebar } from '@hanzo/docs-ui/components/sidebar/base';
```
Ensure the contexts are only accessed within `<DocsLayout />`.
@@ -148,12 +148,12 @@ Make sure to import the appropriate page layout based on your docs layout:
```ts
// For docs layout
import { DocsPage } from 'fumadocs-ui/layouts/docs/page';
import { DocsPage } from '@hanzo/docs-ui/layouts/docs/page';
// For notebook layout
import { DocsPage } from 'fumadocs-ui/layouts/notebook/page';
import { DocsPage } from '@hanzo/docs-ui/layouts/notebook/page';
```
**Migration Steps:** Update your imports accordingly. Although the default `fumadocs-ui/page` will redirect to the correct layout, we strongly advise explicit imports for clarity and future-proofing.
**Migration Steps:** Update your imports accordingly. Although the default `@hanzo/docs-ui/page` will redirect to the correct layout, we strongly advise explicit imports for clarity and future-proofing.
### Removal of Unused Styles
@@ -163,4 +163,4 @@ Styles related to the abandoned `container` utility, and `--spacing-fd-container
## Conclusion
Fumadocs 16.2 aims to offer greater flexibility for developers. Welcome to share your thoughts about the new design on GitHub Discussion!
Hanzo Docs 16.2 aims to offer greater flexibility for developers. Welcome to share your thoughts about the new design on GitHub Discussion!
@@ -1,11 +1,11 @@
---
title: Static Build
description: Output static website with Fumadocs.
description: Output static website with Hanzo Docs.
---
## Setup
By default, Fumadocs use a server-first approach which always requires a running server to serve.
By default, Hanzo Docs use a server-first approach which always requires a running server to serve.
You can output a static build by configuring your React framework.
@@ -60,7 +60,7 @@ See [React Router Docs](https://reactrouter.com/how-to/spa) for details.
```ts title="react-router.config.ts"
import type { Config } from '@react-router/dev/config';
import { glob } from 'node:fs/promises';
import { createGetUrl, getSlugs } from 'fumadocs-core/source';
import { createGetUrl, getSlugs } from '@hanzo/docs-core/source';
const getUrl = createGetUrl('/docs');
@@ -17,7 +17,7 @@ For example, this setup with Hanzo Docs MDX allows only MDX files with frontmatt
import { docs } from 'collections/server';
import { loader, update } from '@hanzo/docs-core/source';
const filteredSource = update(docs.toFumadocsSource())
const filteredSource = update(docs.toHanzoDocsSource())
.files((files) =>
files.filter((file) => {
// keep meta files (e.g. `meta.json`)
@@ -42,7 +42,7 @@ import { loader, update } from '@hanzo/docs-core/source';
// uncached, it's better to cache it in-memory for real use case.
export function createSource(permission: 'public' | 'admin') {
const filteredSource = update(docs.toFumadocsSource())
const filteredSource = update(docs.toHanzoDocsSource())
.files((files) =>
files.filter((file) => {
if (file.type === 'meta') return true;
@@ -1,13 +1,13 @@
---
title: Customize UI
description: A complete guide on how to customize Fumadocs UI.
description: A complete guide on how to customize Hanzo Docs UI.
---
## Introduction
Fumadocs UI provides pre-built components for simplicity, serving as a middleground between "installing all UI code to your codebase" and an opinionated package.
Hanzo Docs UI provides pre-built components for simplicity, serving as a middleground between "installing all UI code to your codebase" and an opinionated package.
While Fumadocs UI itself has many designs around flexibility & backward compatibility, if used incorrectly, the measures may take no effect.
While Hanzo Docs UI itself has many designs around flexibility & backward compatibility, if used incorrectly, the measures may take no effect.
> It is also recommended to feed this guide to your AI agents, if they may edit your UI.
@@ -31,14 +31,14 @@ Or styling the container via props:
</DocsLayout>
```
Detailed documentation for each component is in the [Fumadocs UI](/docs/ui) section, you can take it as a reference.
Detailed documentation for each component is in the [Hanzo Docs UI](/docs/ui) section, you can take it as a reference.
Most options support passing JSX elements to allow your own components.
This approach should suffice most use cases, such as adding sections below table of contents or in sidebar.
### CSS [step]
When the styling is more complicated, some components of Fumadocs UI attaches its own `id` & `data-` attributes for selecting.
When the styling is more complicated, some components of Hanzo Docs UI attaches its own `id` & `data-` attributes for selecting.
You can target them in your CSS selectors:
```css
@@ -64,38 +64,38 @@ CSS approach can be risky as only the `id` & `data-` attributes can be versioned
### Install via CLI [step]
For advanced needs beyond the exposed options, or if your custom CSS styles became overly invasive, Fumadocs CLI is a powerful tool.
For advanced needs beyond the exposed options, or if your custom CSS styles became overly invasive, Hanzo Docs CLI is a powerful tool.
You can find similar prompts under the relevant component docs, indicating the component is installable, such as:
<Installation name="layouts/docs" />
For **layout components** (which often composes multiple components), Fumadocs CLI has a special `customize` command with granular choices.
For **layout components** (which often composes multiple components), Hanzo Docs CLI has a special `customize` command with granular choices.
```npm
npx @fumadocs/cli@latest customize
npx @hanzo/docs-cli@latest customize
```
Despite installing the entire layout component, you can choose to install a **slot** (a replaceable part of the layout component).
Run the command above and you can view the full options.
When installed, make sure to use the installed types over the types exported from Fumadocs UI. For example, if you have installed `layout/docs`, update your imports:
When installed, make sure to use the installed types over the types exported from Hanzo Docs UI. For example, if you have installed `layout/docs`, update your imports:
```tsx
// [!code --]
import type { DocsLayoutProps } from 'fumadocs-ui/layouts/docs';
import type { DocsLayoutProps } from '@hanzo/docs-ui/layouts/docs';
// [!code ++]
import type { DocsLayoutProps } from '@/components/layout/docs';
```
This ensure your local components will be decoupled from Fumadocs UI.
This ensure your local components will be decoupled from Hanzo Docs UI.
While Fumadocs CLI offers full control for the UI code, it is worth mentioning that:
While Hanzo Docs CLI offers full control for the UI code, it is worth mentioning that:
- You won't be able to receive UI updates for the installed the components.
- You can re-install the component with Fumadocs CLI, but prior customisations will be erased. (You can choose which file to overwrite)
- Fumadocs CLI will assume the latest Fumadocs Core + UI to be used.
- You can re-install the component with Hanzo Docs CLI, but prior customisations will be erased. (You can choose which file to overwrite)
- Hanzo Docs CLI will assume the latest Hanzo Docs Core + UI to be used.
## Other Questions
Feel free to reach out in [GitHub Discussions](https://github.com/fuma-nama/fumadocs/discussions) for questions, or if you have encountered unexpected breakages.
Feel free to reach out in [GitHub Discussions](https://github.com/hanzoai/docs/discussions) for questions, or if you have encountered unexpected breakages.
@@ -63,7 +63,7 @@ export async function GET(): Promise<Response> {
<Callout type="warning" title="Protect the endpoint">
Consider protecting `/export/epub` in production. For example, require an `Authorization: Bearer <secret>` header and set `EXPORT_SECRET` in your environment. The Hanzo Docs CLI scaffolds a route with this protection when you run `fumadocs export epub --scaffold-only`.
Consider protecting `/export/epub` in production. For example, require an `Authorization: Bearer <secret>` header and set `EXPORT_SECRET` in your environment. The Hanzo Docs CLI scaffolds a route with this protection when you run `Hanzo Docs export epub --scaffold-only`.
</Callout>
@@ -72,7 +72,7 @@ Consider protecting `/export/epub` in production. For example, require an `Autho
You can also export EPUB via the Hanzo Docs CLI:
```bash
fumadocs export epub --framework next
Hanzo Docs export epub --framework next
```
This fetches from your running server (Next.js) or copies from the build output (other frameworks). Run a production build first for non-Next.js frameworks.
@@ -22,7 +22,7 @@ export function getRSS() {
image: `${baseUrl}/banner.png`,
favicon: `${baseUrl}/icon.png`,
copyright: 'All rights reserved 2025, Fuma Nama',
copyright: 'All rights reserved 2025, Hanzo Nama',
});
for (const page of source.getPages()) {
@@ -35,7 +35,7 @@ export function getRSS() {
author: [
{
name: 'Fuma',
name: 'Hanzo',
},
],
});
+5 -5
View File
@@ -42,7 +42,7 @@ A command line tool to install UI components and automate things, useful for cus
</Cards>
<Callout title="Want to learn more?">
Read our in-depth [What is Hanzo Docs](/docs/what-is-fumadocs) introduction.
Read our in-depth [What is Hanzo Docs](/docs/what-is-hanzo-docs) introduction.
</Callout>
### Terminology
@@ -53,8 +53,8 @@ A command line tool to install UI components and automate things, useful for cus
Some basic knowledge of React.js would be useful for further customizations.
<Callout title="Love Fumadocs but not familiar with React?">
[Fumapress](https://press.fumadocs.dev) is a site generator that has lower barrier for beginners.
<Callout title="Love Hanzo Docs but not familiar with React?">
[Fumapress](https://docs.hanzo.ai) is a site generator that has lower barrier for beginners.
It enforces a React framework of its own, and offers a better DX in return.
</Callout>
@@ -63,7 +63,7 @@ Some basic knowledge of React.js would be useful for further customizations.
A minimum version of Node.js 22 required.
```npm
npm create fumadocs-app
npm create @hanzo/docs
```
It will ask you the built-in template to use:
@@ -105,7 +105,7 @@ npm run dev
Some common questions you may encounter.
<Accordions>
<Accordion id='upgrade-fumadocs' title="Getting error with missing APIs or bugs?">
<Accordion id='upgrade-hanzo-docs' title="Getting error with missing APIs or bugs?">
Make sure to upgrade Hanzo Docs when you've encountered any problems or trying out new features:
```bash title="pnpm"
@@ -105,12 +105,12 @@ This will make the type of `time` property to be shown as `timestamp`.
### Full type
You can specify the full name of a type with the `@fumadocsType` tsdoc tag.
You can specify the full name of a type with the `@hanzoDocsType` tsdoc tag.
```ts
interface MyInterface {
/**
* @fumadocsType `MyBeautifulClient` // [!code highlight]
* @hanzoDocsType `MyBeautifulClient` // [!code highlight]
*/
client: MyClient;
}
@@ -125,7 +125,7 @@ Type Table will generate anchor ID automatically, you can use it to link to anot
```ts
interface MyInterface {
/**
* @fumadocsHref #type-table-temp.ts-MyClass-test
* @hanzoDocsHref #type-table-temp.ts-MyClass-test
*/
client: MyClient;
}
@@ -1,6 +1,6 @@
---
title: Build Your Own
description: Build your own content source for Fumadocs.
description: Build your own content source for Hanzo Docs.
---
## Introduction
@@ -25,7 +25,7 @@ See [Definitions of Page Tree](/docs/headless/page-tree).
Pass your page tree to `DocsLayout` (usually in a `layout.tsx`):
```tsx title="layout.tsx"
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { DocsLayout } from '@hanzo/docs-ui/layouts/docs';
import type { ReactNode } from 'react';
export default function Layout({ children }: { children: ReactNode }) {
@@ -57,7 +57,7 @@ For docs page, it's the same logic:
You may need table of contents, which can be generated on your own, or using the [`getTableOfContents`](/docs/headless/utils/get-toc) utility (Markdown/MDX only).
```tsx
import { DocsPage, DocsBody } from 'fumadocs-ui/layouts/docs/page';
import { DocsPage, DocsBody } from '@hanzo/docs-ui/layouts/docs/page';
import { getPage } from './my-content-source';
import { notFound } from 'next/navigation';
@@ -109,4 +109,4 @@ For Markdown and MDX, the built-in [Search API](/docs/headless/search/orama) + s
Otherwise, you will have to bring your own implementation.
We recommend 3rd party solutions like Orama or Algolia Search. They are more flexible than the built-in Search API, and is easier to integrate with remote sources.
Fumadocs offers a variant of [Search Integrations](/docs/headless/search).
Hanzo Docs offers a variant of [Search Integrations](/docs/headless/search).
@@ -5,11 +5,11 @@ description: Content source for local Markdown content.
## Introduction
`@fumadocs/local-md` is a content source for local Markdown/MDX files, it is bundleless (works fully at runtime) by design.
`@hanzo/docs-local-md` is a content source for local Markdown/MDX files, it is bundleless (works fully at runtime) by design.
As compared to [MDX Remote](/docs/integrations/content/mdx-remote), it is more comprehensive & robust while focused solely on local files.
As compared to [Fumadocs MDX](/docs/mdx), it doesn't need a type-gen or bundler to work, but build-time image optimization will be disabled.
As compared to [Hanzo Docs MDX](/docs/mdx), it doesn't need a type-gen or bundler to work, but build-time image optimization will be disabled.
### Limitations
@@ -21,16 +21,16 @@ As compared to [Fumadocs MDX](/docs/mdx), it doesn't need a type-gen or bundler
Install the package:
```package-install
@fumadocs/local-md shiki
@hanzo/docs-local-md shiki
```
> `shiki` is installed because it has to be externalized by the bundler.
Create a `localMd` instance and connect it to Fumadocs:
Create a `localMd` instance and connect it to Hanzo Docs:
```ts title="lib/source.ts"
import { dynamicLoader } from 'fumadocs-core/source/dynamic';
import { localMd } from '@fumadocs/local-md';
import { dynamicLoader } from '@hanzo/docs-core/source/dynamic';
import { localMd } from '@hanzo/docs-local-md';
const docs = localMd({
dir: 'content/docs',
@@ -51,8 +51,8 @@ export async function getSource() {
You may pass `frontmatterSchema` and `metaSchema` to customize the validation schemas:
```ts title="lib/source.ts"
import { localMd } from '@fumadocs/local-md';
import { pageSchema, metaSchema } from 'fumadocs-core/source/schema';
import { localMd } from '@hanzo/docs-local-md';
import { pageSchema, metaSchema } from '@hanzo/docs-core/source/schema';
const docs = localMd({
dir: 'content/docs',
@@ -71,13 +71,13 @@ The recommended integration is:
1. Create `localMd({ dir })` for your content directory.
2. Pass `docs.dynamicSource()` to `dynamicLoader()`.
3. Read the source in your route/layout and render it with Fumadocs UI.
3. Read the source in your route/layout and render it with Hanzo Docs UI.
For example, in a docs layout:
```tsx title="app/docs/layout.tsx"
import { getSource } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { DocsLayout } from '@hanzo/docs-ui/layouts/docs';
export default async function Layout({ children }: LayoutProps<'/docs'>) {
const docs = await getSource();
@@ -105,7 +105,7 @@ Start the dev server with `local-md dev -- xxx` like:
And connect to it:
```ts title="lib/source.ts"
import { localMd } from '@fumadocs/local-md';
import { localMd } from '@hanzo/docs-local-md';
const docs = localMd({
dir: 'content/docs',
@@ -121,7 +121,7 @@ This keeps the loader in sync when local Markdown or MDX files change.
### JavaScript Engine
When compiling Markdown files (`*.md`), `@fumadocs/local-md` uses a virtual JavaScript engine to avoid `eval()` at runtime.
When compiling Markdown files (`*.md`), `@hanzo/docs-local-md` uses a virtual JavaScript engine to avoid `eval()` at runtime.
This allows your app to work on environments like Cloudflare Worker, while the performance will be slower than the native JavaScript JIT compiler.
@@ -132,8 +132,8 @@ You can use `staticSource()` when you only need a one-time snapshot without reva
It works with a normal `loader()` instead of only `dynamicLoader()`:
```ts title="lib/source.ts"
import { loader } from 'fumadocs-core/source';
import { localMd } from '@fumadocs/local-md';
import { loader } from '@hanzo/docs-core/source';
import { localMd } from '@hanzo/docs-local-md';
const docs = localMd({
dir: 'content/docs',
@@ -144,16 +144,16 @@ export const source = loader(await docs.staticSource(), {
});
```
## Migration from Fumadocs MDX
## Migration from Hanzo Docs MDX
If you're already using Fumadocs MDX for local docs content, migrating is usually straightforward.
If you're already using Hanzo Docs MDX for local docs content, migrating is usually straightforward.
### Before
With Fumadocs MDX, a common setup looks like:
With Hanzo Docs MDX, a common setup looks like:
```ts tab="source.config.ts"
import { defineDocs, defineConfig } from 'fumadocs-mdx/config';
import { defineDocs, defineConfig } from '@hanzo/docs-mdx/config';
export const docs = defineDocs({
dir: 'content/docs',
@@ -164,21 +164,21 @@ export default defineConfig();
```ts tab="lib/source.ts"
import { docs } from 'collections/server';
import { loader } from 'fumadocs-core/source';
import { loader } from '@hanzo/docs-core/source';
export const source = loader({
baseUrl: '/docs',
source: docs.toFumadocsSource(),
source: docs.toHanzoDocsSource(),
});
```
### After
With `@fumadocs/local-md`, you can replace that setup with:
With `@hanzo/docs-local-md`, you can replace that setup with:
```ts title="lib/source.ts"
import { dynamicLoader } from 'fumadocs-core/source/dynamic';
import { localMd } from '@fumadocs/local-md';
import { dynamicLoader } from '@hanzo/docs-core/source/dynamic';
import { localMd } from '@hanzo/docs-local-md';
const docs = localMd({
dir: 'content/docs',
@@ -207,7 +207,7 @@ Finally, update references to your `source` object with `getSource()`:
```tsx title="app/docs/layout.tsx"
import { getSource } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { DocsLayout } from '@hanzo/docs-ui/layouts/docs';
export default async function Layout({ children }: LayoutProps<'/docs'>) {
// [!code --]
@@ -264,20 +264,20 @@ return <div>{body}</div>;
### Without RSC
If your setup doesn't support RSC, unlike Fumadocs MDX's `collections/browser` API, `local-md` leverages server payload to send AST, then render Markdown at client-side.
If your setup doesn't support RSC, unlike Hanzo Docs MDX's `collections/browser` API, `local-md` leverages server payload to send AST, then render Markdown at client-side.
For example, in Tanstack Start:
```tsx title="src/routes/docs/$.tsx"
import { createFileRoute, notFound } from '@tanstack/react-router';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { DocsLayout } from '@hanzo/docs-ui/layouts/docs';
import { createServerFn } from '@tanstack/react-start';
import { getSource } from '@/lib/source';
import { DocsBody, DocsPage } from 'fumadocs-ui/layouts/docs/page';
import { useFumadocsLoader } from 'fumadocs-core/source/client';
import { DocsBody, DocsPage } from '@hanzo/docs-ui/layouts/docs/page';
import { useHanzoDocsLoader } from '@hanzo/docs-core/source/client';
import { useMemo } from 'react';
import { useMDXComponents } from '@/components/mdx';
import { rendererFromSerialized } from '@fumadocs/local-md/client';
import { rendererFromSerialized } from '@hanzo/docs-local-md/client';
export const Route = createFileRoute('/docs/$')({
component: Page,
@@ -308,7 +308,7 @@ const serverLoader = createServerFn({
});
function Page() {
const { pageTree, frontmatter, render } = useFumadocsLoader(Route.useLoaderData());
const { pageTree, frontmatter, render } = useHanzoDocsLoader(Route.useLoaderData());
// [!code highlight:2] render under sync mode
const renderer = useMemo(() => rendererFromSerialized(render), [render]);
const { body, toc } = renderer.renderSync(useMDXComponents());

Some files were not shown because too many files have changed in this diff Show More