Writing Documentation
This guide explains how to add and organize different types of documentation in Thunder. Thunder uses Docusaurus with autogenerated sidebars, making it easy to add new content.
Prerequisites
Before writing Thunder documentation, familiarize yourself with the official Docusaurus guides:
- Markdown Features - Learn about basic Markdown syntax, frontmatter, callouts, code blocks, tabs, and more
- MDX and React - Understand how to use React components in MDX
- Assets - Learn how to add and reference images and files
- Links - Best practices for internal and external linking
- Admonitions (Callouts) - Using note, tip, warning, and danger callouts
- Code Blocks - Syntax highlighting, line numbers, and highlighting
- Tabs - Creating tabbed content
- Diagrams - Using Mermaid for diagrams
Documentation Structure
Thunder documentation is organized into separate sections, each with its own sidebar:
docs/content/
├── guides/ # User guides and tutorials (docsSidebar)
├── sdks/ # SDK documentation (per-SDK sidebars)
└── community/ # Community and contributing docs (communitySidebar)
Each section uses either autogenerated or manual sidebars defined in docs/sidebars.ts.
Components
Thunder provides several custom MDX components designed to enhance documentation. These components are registered in docs/src/theme/MDXComponents.tsx and can be used directly in any MDX file without importing.
Oxygen UI Components
Thunder documentation has access to Oxygen UI components which are pre-registered:
Box- Flexible container componentCard- Card containerCardContent- Card content wrapperTypography- Typography component for text styling
If you need additional components beyond the pre-registered ones, please add them to docs/src/theme/MDXComponents.tsx.
Example:
<Box sx={{ padding: 2, backgroundColor: 'background.paper' }}>
<Card>
<CardContent>
<Typography variant="h6">Custom Card</Typography>
<Typography>This is a custom card using Oxygen UI components.</Typography>
</CardContent>
</Card>
</Box>
Framework and Technology Icons
Pre-registered logo components for various frameworks and technologies:
ReactLogo- React frameworkNextLogo- Next.js frameworkVueLogo- Vue.js frameworkNuxtLogo- Nuxt frameworkAngularLogo- Angular frameworkBrowserLogo- Browser/JavaScriptNodeLogo- Node.jsExpressLogo- Express.jsGoLogo- Go languagePythonLogo- Python languageFlutterLogo- Flutter frameworkIOSLogo- iOS platformAndroidLogo- Android platformReactRouterLogo- React Router
Example:
<Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
<ReactLogo />
<NodeLogo />
<PythonLogo />
</Box>
Stepper
The Stepper component creates a step-by-step wizard interface from your content. It automatically converts headings into steps with collapsible content.
Props:
stepNode(optional): Heading level to use for steps (default:'h2')as(optional): HTML heading tag to render (default:'h2')
Usage:
<Stepper>
## Step 1: Setup
Configure your environment by installing dependencies.
\`\`\`bash
npm install
\`\`\`
## Step 2: Configuration
Create a configuration file.
\`\`\`yaml
server:
port: 8080
\`\`\`
## Step 3: Run
Start the application.
\`\`\`bash
npm start
\`\`\`
</Stepper>
Result: Each ## heading becomes a numbered step with collapsible content below it.
Source: docs/src/components/Stepper.tsx
TutorialHero
The TutorialHero component creates an attractive hero section for tutorials, automatically organizing content into a two-column layout with icons.
Props:
children: Content to display, includingTutorialHeroItemcomponents
TutorialHeroItem Props:
icon(optional): Custom icon componentchildren: Content for the list item
Usage:
<TutorialHero>
## What you'll learn
<TutorialHeroItem>
How to set up authentication
</TutorialHeroItem>
<TutorialHeroItem>
Implementing user login
</TutorialHeroItem>
<TutorialHeroItem>
Managing user sessions
</TutorialHeroItem>
## Prerequisites
<TutorialHeroItem icon={<NodeLogo />}>
Node.js 18 or higher
</TutorialHeroItem>
<TutorialHeroItem icon={<ReactLogo />}>
React 18 or higher
</TutorialHeroItem>
</TutorialHero>
Result: A two-column layout with heading sections and icon-based list items.
Source: docs/src/components/TutorialHero.tsx
SDKCard
The SDKCard component displays SDK information in an attractive card format with automatic version fetching from npm.
Props:
icon(required): Icon component to displaytitle(required): SDK titlepackageName(optional): npm package namepackageManager(optional): Package manager type ('npm'|'yarn'|'pnpm'|'go'|'pip'|'pod'|'gradle')version(optional): Version string (fetched automatically if using npm)description(required): SDK descriptioncomingSoon(optional): Show "Coming Soon" badge (default:false)href(optional): Link URL
Usage:
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: 3 }}>
<SDKCard
icon={<ReactLogo />}
title="React SDK"
packageName="@asgardeo/auth-react"
packageManager="npm"
description="Authenticate your React applications with Thunder"
href="/sdks/react"
/>
<SDKCard
icon={<NodeLogo />}
title="Node.js SDK"
packageName="@asgardeo/auth-node"
packageManager="npm"
description="Server-side authentication for Node.js applications"
href="/sdks/nodejs"
/>
<SDKCard
icon={<PythonLogo />}
title="Python SDK"
description="Python SDK for Thunder authentication"
comingSoon={true}
/>
</Box>
Features:
- Automatically fetches and displays the latest version from npm
- Shows "Coming Soon" badge for upcoming SDKs
- Hover effects and animations
- Responsive card layout
Source: docs/src/components/SDKCard.tsx
CodeBlock
The CodeBlock component displays code with syntax highlighting. It's a wrapper around Docusaurus's native CodeBlock with additional features for use with CodeGroup.
Props:
lang(optional): Programming language for syntax highlighting (default:'text')label(optional): Label for the code block tab when used insideCodeGroupchildren(required): Code content as string or React nodetitle(optional): Title displayed above the code blockshowLineNumbers(optional): Whether to show line numbers
Usage:
<CodeBlock lang="bash" title="Installation">
npm install @asgardeo/auth-react
</CodeBlock>
With line numbers:
<CodeBlock lang="typescript" showLineNumbers>
{`import { AuthProvider } from '@asgardeo/auth-react';
function App() {
return (
<AuthProvider config={config}>
<YourApp />
</AuthProvider>
);
}`}
</CodeBlock>
Source: docs/src/components/CodeBlock.tsx
CodeGroup
The CodeGroup component displays multiple code blocks in tabs, perfect for showing installation commands for different package managers or code examples in different languages.
Props:
defaultValue(optional): The default tab to display (defaults to first tab)groupId(optional): Group ID for syncing tabs across the page (default:'code-group')children(required):CodeBlockcomponents to display as tabs
Features:
- Automatically displays icons for known package managers (npm, yarn, pnpm, bun, deno)
- Syncs tab selection across all
CodeGroupcomponents with the samegroupId - Supports any number of code blocks as tabs
Usage:
<CodeGroup>
<CodeBlock lang="bash" label="npm">
npm install @asgardeo/auth-react
</CodeBlock>
<CodeBlock lang="bash" label="yarn">
yarn add @asgardeo/auth-react
</CodeBlock>
<CodeBlock lang="bash" label="pnpm">
pnpm add @asgardeo/auth-react
</CodeBlock>
</CodeGroup>
Multiple languages:
<CodeGroup groupId="api-examples">
<CodeBlock lang="javascript" label="JavaScript">
{`const response = await fetch('/api/users', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + token
}
});`}
</CodeBlock>
<CodeBlock lang="python" label="Python">
{`response = requests.get('/api/users',
headers={'Authorization': f'Bearer {token}'}
)`}
</CodeBlock>
<CodeBlock lang="go" label="Go">
{`req, _ := http.NewRequest("GET", "/api/users", nil)
req.Header.Add("Authorization", "Bearer " + token)
resp, _ := client.Do(req)`}
</CodeBlock>
</CodeGroup>
Result: A tabbed interface where users can switch between different package managers or programming languages. Tabs with the same groupId will sync their selection across the page.
Supported package manager icons:
- npm
- yarn
- pnpm
- bun
- deno
Source: docs/src/components/CodeGroup.tsx
Adding User Guides
User guides live in docs/content/guides/ and use an autogenerated sidebar.
Creating a Guide
- Create a new
.mdxfile indocs/content/guides/:
cd docs/content/guides
touch my-new-guide.mdx
- Add frontmatter and content:
---
title: My New Guide
sidebar_position: 1
description: Brief description of the guide
---
# My New Guide
Your guide content here...
- The guide will automatically appear in the sidebar based on its
sidebar_position.
Creating a Guide Category
To organize guides into categories (folders with subpages):
- Create a directory:
mkdir docs/content/guides/advanced-topics
- Create a
_category_.jsonfile inside:
{
"position": 5,
"label": "Advanced Topics",
"collapsible": true
}
Category Options:
position: Order in the sidebar (lower numbers appear first)label: Display name in the sidebarcollapsible: Whether the category can be collapsed (default:true)collapsed: Whether the category starts collapsed (default:true)
- Add guide pages inside the category:
touch docs/content/guides/advanced-topics/authentication.mdx
touch docs/content/guides/advanced-topics/authorization.mdx
Each page should have frontmatter with sidebar_position:
---
title: Authentication
sidebar_position: 1
---
# Authentication
Content here...
Example Guide Structure
guides/
├── introduction.mdx # sidebar_position: 1
├── installation.mdx # sidebar_position: 2
├── quick-start/ # Category (position: 4)
│ ├── _category_.json
│ └── react.mdx
└── advanced-topics/ # Category (position: 5)
├── _category_.json
├── authentication.mdx
└── authorization.mdx
Adding API Documentation
API documentation is automatically generated from OpenAPI specifications in the /api directory using Scalar.
How It Works
- OpenAPI specs are stored in
/api/(project root, not docs) - A merge script combines all specs into a single file
- Scalar API Reference renders the combined specification
Adding a New API Spec
- Create a new OpenAPI YAML file in
/api/:
openapi: 3.0.0
info:
title: My New API
version: 1.0.0
description: Description of the API
paths:
/resource:
get:
summary: Get resource
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
id:
type: string
- Regenerate the combined spec:
cd docs
pnpm generate:api-specs
This runs node ./scripts/merge-openapi-specs.mjs which:
- Reads all
.yamlfiles from/api/ - Merges them into a single spec
- Outputs to
docs/static/api/combined.yaml
- The API reference is automatically available at the
/apiroute
Displaying API Docs in Pages
Use the ApiReference component to embed API documentation:
<ApiReference specUrl="/api/combined.yaml" />
Or reference a specific API file:
<ApiReference specUrl="/api/authentication.yaml" />
API Spec Best Practices
- One API per file: Keep each API in its own YAML file
- Consistent naming: Use descriptive names (e.g.,
authentication.yaml,user-management.yaml) - Include descriptions: Add clear descriptions for all endpoints
- Use examples: Include request/response examples
- Tag endpoints: Group related endpoints with tags
Adding SDK Documentation
SDK documentation has custom sidebars defined per SDK. Each SDK can have its own navigation structure.
Creating SDK Documentation
- Create an SDK directory:
mkdir -p docs/content/sdks/my-sdk
- Create a sidebar configuration file:
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
const sidebar: SidebarsConfig = {
mySdkSidebar: [
{
type: 'doc',
id: 'sdks/my-sdk/overview',
label: 'Overview',
},
{
type: 'category',
label: 'Getting Started',
collapsed: false,
items: [
{
type: 'doc',
id: 'sdks/my-sdk/installation',
label: 'Installation',
},
{
type: 'doc',
id: 'sdks/my-sdk/quick-start',
label: 'Quick Start',
},
],
},
{
type: 'category',
label: 'API Reference',
collapsed: false,
items: [
{
type: 'category',
label: 'Components',
collapsed: true,
items: [
{
type: 'doc',
id: 'sdks/my-sdk/components/button',
label: '<Button />',
},
],
},
],
},
],
};
export default sidebar;
- Register the sidebar in
docs/sidebars.ts:
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
import reactSdkSidebar from './content/sdks/react/sidebar';
import mySdkSidebar from './content/sdks/my-sdk/sidebar'; // Add import
const sidebars: SidebarsConfig = {
docsSidebar: [{type: 'autogenerated', dirName: 'guides'}],
reactSdkSidebar,
mySdkSidebar, // Add sidebar
communitySidebar: [{type: 'autogenerated', dirName: 'community'}],
};
export default sidebars;
- Create documentation pages:
touch docs/content/sdks/my-sdk/overview.mdx
touch docs/content/sdks/my-sdk/installation.mdx
Each page's id in the sidebar must match its file path:
---
title: My SDK Overview
description: Introduction to My SDK
---
# My SDK
Welcome to My SDK documentation...
SDK Sidebar Structure
Manual sidebars give you complete control over:
- Navigation order: Exact order of items
- Nesting levels: Multiple levels of categories
- Custom labels: Different labels than file names
- Item types: Mix docs, categories, and links
See: React SDK sidebar for a complete example.
Adding Community Documentation
Community documentation (contributing guides, design docs, etc.) lives in docs/content/community/ and uses an autogenerated sidebar.
Creating Community Docs
- Navigate to the community directory:
cd docs/content/community
- Create a new guide or directory:
touch code-of-conduct.mdx
# Or create a category
mkdir design-principles
- Add content with frontmatter:
---
title: Code of Conduct
sidebar_position: 3
description: Community guidelines and expectations
---
# Code of Conduct
Our community guidelines...
Creating Community Categories
Same as guide categories, use _category_.json:
mkdir docs/content/community/design-principles
{
"position": 2,
"label": "Design Principles",
"collapsible": false
}
Example Community Structure
community/
├── contributing/
│ ├── _category_.json
│ ├── contributing-code/
│ │ ├── _category_.json
│ │ ├── prerequisites.mdx
│ │ ├── backend-development/
│ │ ├── documentation-development/
│ │ └── frontend-development/
│ └── contributing-docs.mdx
└── code-of-conduct.mdx
Frontmatter Reference
All documentation pages support these frontmatter fields:
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Page title (appears in browser tab and page) |
description | string | No | Page description for SEO and previews |
sidebar_position | number | No | Order in autogenerated sidebars |
sidebar_label | string | No | Custom label (overrides title) |
hide_table_of_contents | boolean | No | Hide right-hand table of contents |
keywords | array | No | SEO keywords |
id | string | No | Custom document ID (for manual sidebars) |
slug | string | No | Custom URL slug |
Frontmatter Examples
Basic guide:
---
title: Quick Start
sidebar_position: 1
description: Get started with Thunder in 5 minutes
---
Tutorial with keywords:
---
title: Authentication Tutorial
sidebar_position: 2
description: Learn how to implement OAuth2 authentication
keywords: [authentication, oauth2, tutorial, login]
---
Page with custom slug:
---
title: Frequently Asked Questions
slug: /faq
hide_table_of_contents: true
---
Testing Your Changes
Always test documentation locally before committing:
cd docs
pnpm dev
Check:
- ✅ Pages render correctly
- ✅ Sidebar navigation works
- ✅ Links are not broken
- ✅ Images load properly
- ✅ Code blocks display correctly
- ✅ API documentation appears (if changed)