A modern, high-performance documentation platform built with Next.js 16 and MDX
Features β’ Quick Start β’ Documentation β’ Project Structure β’ Contributing
TK Doc is a production-ready documentation template designed for developers who need a fast, beautiful, and maintainable documentation site. Built with cutting-edge technologies, it provides an exceptional reading experience while maintaining excellent developer experience.
Perfect for technical documentation, API references, knowledge bases, and developer guides.
- Next.js 16 with App Router for optimal performance
- React 19 with Server Components
- TypeScript for type safety
- Tailwind CSS 4 for modern styling
- pnpm for fast, efficient package management
- MDX Support - Write docs in Markdown with React components
- Frontmatter - Metadata support for title, description, and tags
- Code Highlighting - Beautiful syntax highlighting with Prism
- Auto-generated Sidebar - Automatic navigation from folder structure
- Table of Contents - Automatic heading extraction
- 30+ Pre-built Components - Accordion, Alert, Badge, Card, Tabs, and more
- Organized Structure - Components organized by category (buttons, forms, modals)
- PascalCase Naming - React-consistent naming conventions for easy identification
- Radix UI Primitives - Accessible, unstyled components
- Responsive Design - Mobile-first approach
- Custom Fonts - Inter for text, JetBrains Mono for code
- Performance Optimized - Dynamic imports for non-critical components
- System-Aware Theme - Automatically follows your OS preference via
next-themes - Theme Toggle - Sun/Moon toggle button in the header for manual switching
- Full Coverage - Dark mode styles across all components, sidebar, search, code blocks, and more
- Command Palette - Quick search with
Cmd+K/Ctrl+K - Keyboard Shortcuts - Press
?to view all available keyboard shortcuts - Back to Top - Floating button appears on scroll for quick navigation
- Click-to-Copy Inline Code - Click any inline
codesnippet to copy it to clipboard - Related Articles - Tag-based related content suggestions at the bottom of each page
- Social Sharing - Share buttons for Twitter, Bluesky, LinkedIn, WhatsApp, Email, and copy link
- Responsive Table of Contents - Collapsible mobile-friendly TOC with active heading tracking
- RSS Feed - Auto-generated RSS feed at
/feed.xmlfrom all MDX content - SEO Optimized - Meta tags, OpenGraph, Twitter cards, JSON-LD structured data
- Security Headers - HSTS, CSP, X-Frame-Options configured
- Sitemap Generation - Automatic sitemap for better indexing
- Hot Reload - Instant feedback during development
- ESLint - Code quality checks
- TypeScript Strict Mode - Maximum type safety
- Component Examples - View all available components
- Node.js 18.17 or higher
- pnpm (recommended) or npm/yarn
-
Use this template or clone:
git clone https://github.com/kolasokol/tk-doc.git cd tk-doc -
Install dependencies:
pnpm install
-
Start the development server:
pnpm dev
-
Open your browser:
Navigate to http://localhost:3000
pnpm build
pnpm startThe template includes one example file: component-examples.mdx showing all available components.
To add your own content:
- Create a new
.mdxfile in thecontent/directory (or in a subfolder):
---
title: Getting Started
description: Learn how to use TK Doc
tags: [guide, beginner]
---
# Getting Started
Welcome to your documentation site!
## Installation
Install the package:
```bash
npm install your-package
```
<Alert>
<AlertTitle>Note</AlertTitle>
<AlertDescription>
This is an example of using components in MDX.
</AlertDescription>
</Alert>- The page will automatically appear in the sidebar based on the folder structure
- Organize pages into folders for better navigation (e.g.,
content/guides/getting-started.mdx) - You can safely remove
component-examples.mdxonce you're familiar with the components
All UI components are available in MDX files. See the complete list with examples:
<Tabs defaultValue="npm">
<TabsList>
<TabsTrigger value="npm">npm</TabsTrigger>
<TabsTrigger value="pnpm">pnpm</TabsTrigger>
</TabsList>
<TabsContent value="npm">```bash npm install package ```</TabsContent>
<TabsContent value="pnpm">```bash pnpm add package ```</TabsContent>
</Tabs>The content/ folder starts with only one file:
content/
βββ component-examples.mdx # Component showcase & reference
To add your documentation:
- Create folders for different sections (e.g.,
guides/,api/,tutorials/) - Add
.mdxfiles inside these folders - The sidebar navigation will be auto-generated from your folder structure
Example structure you might create:
content/
βββ component-examples.mdx # Keep this as reference
βββ getting-started/
β βββ installation.mdx
β βββ quick-start.mdx
βββ guides/
β βββ authentication.mdx
β βββ deployment.mdx
βββ api/
βββ reference.mdx
Each folder becomes a section in the sidebar, and files within become pages.
Site configuration uses a 3-layer approach for smooth updates:
We separate defaults, production overrides, and optional local changes:
config/config.base.tsβ Template defaults (do not modify)config/config.private.tsβ Committed, production overrides (domain, analytics, socials)config/config.local.tsβ Gitignored, dev-only overrides (optional)config/site.tsβ Aggregator that merges Base β Private β Local
This keeps updates simple and hosting predictable, with zero surprises.
- Copy the example local file (optional, for dev):
cp config/config.local.example.ts config/config.local.ts- Edit
config/config.private.tsfor production settings, andconfig/config.local.tsfor dev-only overrides:
import type { BaseSiteConfig } from "./config.base";
export const privateConfig: Partial<BaseSiteConfig> = {
// Basic Information
name: "Your Site Name",
title: "Your Site Title",
description: "Your site description",
url: "https://yourdomain.com",
// Social Media Links (set to empty string "" to hide)
social: {
github: "https://github.com/yourusername",
twitter: "https://twitter.com/yourusername",
linkedin: "https://linkedin.com/in/yourusername",
},
// Twitter/X Card Configuration
twitter: {
card: "summary_large_image",
creator: "@yourtwitterhandle",
},
// Open Graph Image (for social sharing)
og: {
image: "/og-image.png",
imageWidth: 1200,
imageHeight: 630,
},
// Google Analytics
analytics: {
googleAnalyticsId: "G-XXXXXXXXXX", // Add your GA4 ID
},
// Footer Branding
footer: {
companyName: "YourCompany",
},
};Note: You only need to specify fields you want to override. Unspecified fields use defaults from
config.base.ts. Dev-only changes go inconfig.local.ts.
- Clean separation - Base defaults stay intact, your changes are isolated
- Easy updates - Update the template without losing your customizations
- Type safety - TypeScript ensures your overrides match the base config
- Git-friendly -
config.local.tsis gitignored;config.private.tsis committed for predictable hosting
| Field | Purpose | Example |
|---|---|---|
name |
Company/site name | "TK Doc" |
title |
Page title (appears in browser tab) | "TK Doc" |
description |
Meta description (SEO) | "A modern documentation platform" |
url |
Your production domain | "https://docs.example.com" |
social.github |
GitHub profile link | Leave empty "" to hide |
social.twitter |
Twitter profile link | Leave empty "" to hide |
social.linkedin |
LinkedIn profile link | Leave empty "" to hide |
twitter.creator |
Twitter handle for cards | "@yourhandle" |
og.image |
Social sharing image | Must be in /public folder |
β
Site title - Browser tab, metadata, social cards
β
Site description - Meta tags, SEO, social sharing
β
Social links - Header and footer links
β
Sitemap & Robots - Generated with your domain
β
Footer text - Company name in copyright
β
OG Image - Used when shared on social media
π‘ Tip: After updating
config/config.private.tsorconfig/config.local.ts, restart your dev server for changes to take effect.
Edit config/config.private.ts with client-specific overrides:
import type { BaseSiteConfig } from "./config.base";
export const privateConfig: Partial<BaseSiteConfig> = {
name: "Client Inc",
title: "Client Inc Documentation",
description: "Official documentation for Client Inc products",
url: "https://docs.clientinc.com",
social: {
github: "https://github.com/clientinc",
twitter: "https://twitter.com/clientinc",
linkedin: "https://linkedin.com/company/clientinc",
},
twitter: {
card: "summary_large_image",
creator: "@clientinc",
},
og: {
image: "/og-image.png",
},
footer: {
companyName: "Client Inc",
},
} as const;That's it! All branding updates instantly across the entire site.
Add your GA4 Measurement ID in config/config.private.ts (production) or leave empty in config/config.local.ts (dev):
export const privateConfig: Partial<BaseSiteConfig> = {
// ... other config
analytics: {
googleAnalyticsId: "G-XXXXXXXXXX", // Replace with your GA4 ID
},
};- The ID is read by
components/analytics.tsxand injected globally fromapp/layout.tsx - Leave
googleAnalyticsIdempty to disable Google Analytics automatically - Restart dev server or redeploy after updating the ID
tk-doc/
βββ app/ # Next.js App Router
β βββ layout.tsx # Root layout with sidebar & dynamic imports
β βββ page.tsx # Homepage
β βββ globals.css # Global styles
β βββ docs/
β β βββ [...slug]/ # Dynamic MDX routes
β βββ feed.xml/
β β βββ route.ts # RSS feed generation
β βββ ui/
β βββ search.tsx # Search component
β βββ interface/ # Layout components
βββ components/ # React components
β βββ ui/ # Radix UI components (PascalCase)
β β βββ Accordion.tsx
β β βββ Alert.tsx
β β βββ Badge.tsx
β β βββ Button.tsx
β β βββ Card.tsx
β β βββ Tabs.tsx
β β βββ README.md # Component documentation
β β βββ ... (30+ components)
β βββ analytics.tsx # Analytics (dynamically loaded)
β βββ BackToTop.tsx # Floating back-to-top button
β βββ Code.tsx # Prism syntax-highlighted code blocks
β βββ InlineCode.tsx # Click-to-copy inline code
β βββ KeyboardShortcutsHelp.tsx # Keyboard shortcuts dialog ("?" key)
β βββ RelatedArticles.tsx # Tag-based related content
β βββ ShareButtons.tsx # Social sharing buttons
β βββ TableOfContents.tsx # Responsive TOC with active tracking
β βββ ThemeProvider.tsx # next-themes provider wrapper
β βββ ThemeToggle.tsx # Dark/light mode toggle
β βββ header.tsx # Site header
β βββ footer.tsx # Site footer (dynamically loaded)
βββ config/ # Configuration files
β βββ config.base.ts # Base configuration (template defaults)
β βββ config.private.ts # Production overrides (committed)
β βββ config.local.example.ts # Example dev overrides (copy to config.local.ts)
β βββ site.ts # Aggregator that merges all configs
βββ content/ # MDX documentation files
β βββ component-examples.mdx # Component showcase (reference)
βββ hooks/ # Custom React hooks
β βββ use-mobile.ts
β βββ use-toast.ts
βββ lib/ # Utility functions
β βββ mdx-utils.ts # MDX parsing utilities
β βββ extract-headings.ts # TOC extraction
β βββ utils.ts # General utilities
βββ public/ # Static assets
β βββ robots.txt
β βββ assets/
βββ types/ # TypeScript definitions
βββ next.config.mjs # Next.js configuration
βββ tailwind.config.ts # Tailwind configuration
βββ tsconfig.json # TypeScript configuration
βββ package.json # Dependencies & scripts
| Technology | Purpose |
|---|---|
| Next.js 16 | React framework with App Router |
| React 19 | UI library |
| TypeScript | Type safety |
| Tailwind CSS 4 | Utility-first CSS |
| MDX | Markdown + JSX |
| Radix UI | Accessible component primitives |
| Lucide | Icon library |
| Prism | Syntax highlighting |
| gray-matter | Frontmatter parsing |
| next-themes | Dark mode / theme management |
The easiest way to customize your site is using the three-file config system:
π Edit config/config.private.ts - Production settings (domain, analytics, social links).
π Copy & edit config/config.local.ts (optional) - Dev-only overrides (copy from config.local.example.ts).
See the Configuring Your Site section above for all options.
- Global styles:
app/globals.css - Tailwind config:
tailwind.config.ts - Code highlighting:
app/code-highlight.css
Add custom components in components/ and import them in MDX files.
The application implements performance best practices:
- Dynamic Imports - Non-critical components (
Footer,Analytics) are dynamically imported inapp/layout.tsx - Server Components - Layout and pages use Next.js Server Components by default for better performance
- Lazy Loading - Components are loaded only when needed, reducing initial bundle size
Example - Dynamic Import Pattern:
import dynamic from "next/dynamic";
const Footer = dynamic(() => import("@/components/footer"), {
ssr: true,
});Always use the correct import path with PascalCase names:
// β
Correct
import { Button } from "@/components/ui/Button";
import { Card, CardHeader, CardContent } from "@/components/ui/Card";
// β Incorrect (old naming convention)
import { Button } from "@/components/ui/button";When creating new UI components:
- Place them in
components/ui/with PascalCase filenames - Use Radix UI as the foundation for accessible components
- Style with Tailwind CSS
- Export from the component file and import with PascalCase naming
- Consider organizing in subfolders (
buttons/,forms/,modals/) based on functionality
Example Component Structure:
// components/ui/Button.tsx
import * as React from "react";
import { cn } from "@/lib/utils";
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: "primary" | "secondary";
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant = "primary", ...props }, ref) => (
<button
ref={ref}
className={cn(
"px-4 py-2 rounded font-medium transition-colors",
variant === "primary" && "bg-blue-600 text-white hover:bg-blue-700",
variant === "secondary" &&
"bg-gray-200 text-gray-800 hover:bg-gray-300",
className,
)}
{...props}
/>
),
);
Button.displayName = "Button";
export { Button };- Store all documentation in the
content/folder - Organize by topic in subfolders (e.g.,
content/guides/,content/api/) - Use frontmatter for metadata (title, description, tags)
- Keep MDX files focused and modular
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Made with β€οΈ by kolasokol
Documentation β’ GitHub β’ Issues