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)