Embeddable help and documentation widget for Next.js — renders searchable, markdown-backed docs as a modal or sidebar overlay.
npm install @cyguin/docs// app/layout.tsx (or any page)
import { DocsWidget } from '@cyguin/docs';
import '@cyguin/docs/styles.css';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
{children}
<DocsWidget apiUrl="/api/docs" mode="modal" triggerLabel="Help" />
</body>
</html>
);
}// app/api/docs/[...cyguin]/route.ts
import { createDocsHandler } from '@cyguin/docs/next';
import { createSQLiteAdapter } from '@cyguin/docs/adapters/sqlite';
const adapter = createSQLiteAdapter({ path: './docs.db' });
export const GET = createDocsHandler({ adapter });// app/api/admin/docs/[...route]/route.ts
import { createAdminHandler } from '@cyguin/docs/next';
import { createSQLiteAdapter } from '@cyguin/docs/adapters/sqlite';
const adapter = createSQLiteAdapter({ path: './docs.db' });
const handler = createAdminHandler({
adapter,
secret: process.env.DOCS_ADMIN_SECRET,
});
export { handler as POST, handler as PUT, handler as PATCH, handler as DELETE };DOCS_ADMIN_SECRET is required. Admin writes fail closed when the secret is missing.
import { createDocsHandler } from '@cyguin/docs/next';
import { createSQLiteAdapter } from '@cyguin/docs/adapters/sqlite';
const adapter = createSQLiteAdapter({ path: './docs.db' });
const handler = createDocsHandler({ adapter });
// POST /admin/docs — create article
await handler.request(new Request('http://localhost/admin/docs', {
method: 'POST',
headers: { Authorization: 'Bearer your-secret', 'Content-Type': 'application/json' },
body: JSON.stringify({
title: 'Getting Started',
body_md: '# Getting Started\n\nWelcome to **My App**!',
section: 'Introduction',
article_order: 1,
}),
}));Floating corner button opens a centered overlay with backdrop. Click backdrop or press Esc to close.
<DocsWidget mode="modal" triggerLabel="Help" />Panel slides in from the right edge. Good for persistent help panels.
<DocsWidget mode="sidebar" triggerLabel="Docs" />| Prop | Type | Default | Description |
|---|---|---|---|
apiUrl |
string |
"/api/docs" |
Endpoint that returns article list |
mode |
"modal" | "sidebar" |
"modal" |
Widget display mode |
triggerLabel |
string |
"Help" |
Label shown on the floating trigger button |
defaultOpen |
boolean |
false |
Open on mount |
className |
string |
"" |
CSS class on root element |
The apiUrl must return a JSON array of articles:
[
{
"id": "1",
"title": "Getting Started",
"body_md": "# Getting Started\n\nWelcome...",
"section": "Introduction",
"article_order": 1,
"published_at": 1710000000
}
]GET /api/docs from @cyguin/docs/next returns this shape automatically.
All colors default to the cyguin dark theme and use --cyguin-* CSS custom properties. Override on your root element or :root:
:root {
--cyguin-bg: #0a0d17;
--cyguin-bg-subtle: #101521;
--cyguin-border: #252b3a;
--cyguin-border-focus: #f5a800;
--cyguin-fg: #f1f3f6;
--cyguin-fg-muted: #888888;
--cyguin-accent: #f5a800;
--cyguin-accent-dark: #c47f00;
--cyguin-accent-fg: #0a0a0a;
--cyguin-radius: 6px;
--cyguin-shadow: 0 1px 4px rgba(0,0,0,0.08);
}| Key | Action |
|---|---|
/ |
Focus search input |
Esc |
Close widget |
↑ / ↓ |
Navigate article list |
Enter |
Open selected article |
| Export | Type | Description |
|---|---|---|
DocsWidget |
Component | Searchable docs widget (modal/sidebar) |
DocsWidgetProps |
Interface | Component props |
DocArticle |
Interface | Article shape |
defaultCssVars |
Object | Default CSS variable values |
| Export | Type | Description |
|---|---|---|
createDocsHandler |
Function | Factory for Next.js API route handler |
DocsAdapter |
Interface | Storage adapter contract |
DocArticle |
Interface | Article shape |