Skip to content

cyguin/docs

Repository files navigation

@cyguin/docs

Embeddable help and documentation widget for Next.js. Searchable, markdown-backed docs in a modal or sidebar — no external service needed.

Quickstart

npm install @cyguin/docs

1. Add the widget to your app

// 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>
  );
}

2. Wire up the API route

// 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 });

3. Wire up the admin route

// 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 routes fail closed without it.

4. Seed some articles

import { createDocsHandler } from '@cyguin/docs/next';
import { createSQLiteAdapter } from '@cyguin/docs/adapters/sqlite';

const adapter = createSQLiteAdapter({ path: './docs.db' });
const handler = createDocsHandler({ adapter });

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,
  }),
}));

Modes

Modal (default)

Floating corner button opens a centered overlay. Click the backdrop or press Esc to close.

<DocsWidget mode="modal" triggerLabel="Help" />

Sidebar

Panel slides in from the right — good for persistent help panels.

<DocsWidget mode="sidebar" triggerLabel="Docs" />

Props

Prop Type Default Description
apiUrl string "/api/docs" Endpoint returning article list
mode "modal" | "sidebar" "modal" Modal or sidebar
triggerLabel string "Help" Label on the floating trigger button
defaultOpen boolean false Open on mount
className string "" CSS class on root element

API Contract

The apiUrl endpoint 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.

Theming

The widget is dark by default. Override --cyguin-* variables on :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);
}

Keyboard Navigation

Key Action
/ Focus search input
Esc Close widget
/ Navigate article list
Enter Open selected article

Exports

@cyguin/docs

Export Type Description
DocsWidget Component Searchable docs widget (modal/sidebar)
DocsWidgetProps Interface Component props
DocArticle Interface Article shape
defaultCssVars Object Default CSS variable values

@cyguin/docs/next

Export Type Description
createDocsHandler Function Factory for Next.js API route handler
DocsAdapter Interface Storage adapter contract
DocArticle Interface Article shape

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors