A NukeHub-first documentation template built with plain Astro + React + Tailwind CSS v4 and the shared @nukehub/docs-kit package. Every pixel of the header, footer, sidebar, search, and theme is custom and reusable.
This repository is the reference consumer of @nukehub/docs-kit. It shows how to build a NukeHub documentation site from a thin layer of project-specific files while the shared components, layouts, shortcodes, and integrations live in the kit and update automatically via npm update @nukehub/docs-kit.
The content workflow stays the same:
- Write docs in Markdown/MDX under
docs/in the repo root. - Run
npm run sync-docsto copy and clean them intosrc/content/docs/. - Build a static site ready for GitHub Pages.
-
Click Use this template on GitHub and create a new repository.
-
Clone the new repository.
-
Install dependencies:
npm install
The kit is installed automatically as a dependency.
-
Update project identity in
src/data/site.ts:import { Logo, type SiteConfig } from "@nukehub/docs-kit"; export const SITE: SiteConfig = { name: "Your Project", logoText: "Your Project", description: "A short description.", site: "https://your-org.github.io", base: "/your-repo", github: "https://github.com/your-org/your-repo", editBranch: "main", editPath: "docs/", logo: Logo, };
The
basevalue must match your GitHub repository name. -
Customize
src/data/nav.tsandsrc/data/footer.ts. -
Add your own documentation under
docs/in the repo root. -
Run
npm run devto preview locally. -
Push to
main; the GitHub Actions workflow in.github/workflows/deploy.ymlpublishes to Pages.
| File | Purpose |
|---|---|
src/data/site.ts |
Site name, description, base path, GitHub URLs. |
src/data/nav.ts |
Header navigation items. |
src/data/footer.ts |
Footer link columns. |
Update these three files to rebrand the site. The kit provides the shared Logo, GitHubIcon, and type definitions so your data stays small and focused.
import { Logo, type SiteConfig } from "@nukehub/docs-kit";
export const SITE: SiteConfig = {
name: "Your Project",
logoText: "Your Project",
description: "A short description.",
site: "https://your-org.github.io",
base: "/your-repo",
github: "https://github.com/your-org/your-repo",
editBranch: "main",
editPath: "docs/",
logo: Logo,
};site+basemust match your GitHub Pages URL.editBranchandeditPathbuild the "Edit this page" links.logoaccepts the kit'sLogocomponent or your own.
import { Home, BookOpen } from "lucide-react";
import { GitHubIcon, type NavItem } from "@nukehub/docs-kit";
export const navItems: NavItem[] = [
{ title: "Home", icon: Home, url: "./" },
{ title: "Docs", icon: BookOpen, url: "./tutorials/getting-started/" },
{
title: "GitHub",
icon: GitHubIcon,
url: "https://github.com/your-org/your-repo",
newpage: true,
},
];Use lucide-react icons or the kit's GitHubIcon. Set newpage: true to open the link in a new tab.
import type { FooterColumn, FooterLink } from "@nukehub/docs-kit";
export const footerColumns: FooterColumn[] = [
{
title: "Project",
links: [
{
title: "License",
url: "https://github.com/your-org/your-repo/blob/main/LICENSE",
newpage: true,
},
],
},
];
export const footerLegal: FooterLink[] = [];The kit is declared as a normal npm dependency:
npm install @nukehub/docs-kitTo pull in the latest kit updates:
npm update @nukehub/docs-kitAfter updating, run npm run build to verify your site still compiles. The kit follows semver; breaking changes bump the major version.
Create files under docs/:
docs/
├── README.md # Becomes the home page
├── tutorials/
│ └── getting-started.md
├── reference/
│ └── index.md
├── development/
│ └── local-dev.md
└── architecture/
└── overview.md
Each page supports this frontmatter:
---
title: Page Title
description: A short description.
sidebar:
label: Short label
order: 1
draft: false
---The root README.md is renamed to index.md automatically, and internal .md links are rewritten to clean trailing-slash routes. This is handled by the nukehub-sync-docs CLI from @nukehub/docs-kit.
npm run sync-docs runs:
nukehub-sync-docs --src ./docs --dst ./src/content/docs --repo-root . --github-file-base https://github.com/nukehub-dev/docs-template/blob/mainIt:
- Copies every
.md/.mdxfile fromdocs/intosrc/content/docs/. - Injects frontmatter if a file is missing it.
- Rewrites internal
.mdlinks to trailing-slash routes. - Copies
CHANGELOG.mdfrom the repo root (if present). - Renames
docs/README.mdtosrc/content/docs/index.md.
You usually do not run this manually — npm run dev and npm run build call it automatically via predev/prebuild.
The template wires the kit's markdownNegotiation integration so every built HTML page gets a Markdown sibling:
import { defineConfig } from "astro/config";
import react from "@astrojs/react";
import mdx from "@astrojs/mdx";
import sitemap from "@astrojs/sitemap";
import tailwindcss from "@tailwindcss/vite";
import { SITE } from "./src/data/site.ts";
import markdownNegotiation from "@nukehub/docs-kit/integrations/markdown-negotiation";
export default defineConfig({
site: SITE.site,
base: SITE.base,
output: "static",
integrations: [react(), mdx(), sitemap(), markdownNegotiation()],
vite: {
plugins: [tailwindcss()],
},
});Do not remove markdownNegotiation() unless you do not want Markdown siblings.
Import from the package root for shared types, icons, and helpers:
import {
Logo,
GitHubIcon,
type SiteConfig,
type NavItem,
type FooterColumn,
} from "@nukehub/docs-kit";Import layouts directly from their subpaths (Astro .astro files cannot be re-exported from a .ts index):
---
import DocLayout from "@nukehub/docs-kit/components/layout/DocLayout.astro";
import BaseLayout from "@nukehub/docs-kit/components/layout/BaseLayout.astro";
import NotFound from "@nukehub/docs-kit/components/docs/NotFound.astro";
---Import the build integration from its subpath:
import markdownNegotiation from "@nukehub/docs-kit/integrations/markdown-negotiation";The kit registers these shortcodes in DocLayout automatically:
Callout, Tabs, TabItem, FileTree, Mermaid, Steps, Step, YouTube, Odysee, ImageFigure, DataTable.
To add a project-specific shortcode, edit src/pages/[...slug].astro and pass a components prop to DocLayout:
---
import DocLayout from "@nukehub/docs-kit/components/layout/DocLayout.astro";
import MyCustomComponent from "../components/MyCustomComponent.astro";
---
<DocLayout
doc={doc}
headings={headings}
allDocs={allDocs}
site={SITE}
navItems={navItems}
footerColumns={footerColumns}
footerLegal={footerLegal}
components={{ MyCustomComponent }}
/>Then use it in any .mdx file:
<MyCustomComponent />| Script | Purpose |
|---|---|
npm run dev |
Sync docs and start the dev server. |
npm run build |
Sync docs and build the static site. |
npm run preview |
Preview the built site. |
npm run check |
Run Astro type checks. |
npm run lint |
Run ESLint. |
npm run format |
Format files with Prettier. |
npm run format:check |
Check formatting without writing. |
Pages written as .mdx can use these components without importing them:
<Callout type="tip" title="Tip">
Run `npm run sync-docs` before building to refresh content. The script is provided by
`@nukehub/docs-kit`.
</Callout>
<Tabs defaultValue="npm">
<TabItem value="npm" label="npm">
npm install
</TabItem>
<TabItem value="pnpm" label="pnpm">
pnpm install
</TabItem>
</Tabs>
<FileTree items={[{ name: "docs", children: [{ name: "README.md" }] }]} />
<Mermaid chart={`flowchart LR; A --> B`} />
<Steps>
<Step>Do this first.</Step>
<Step>Then do this.</Step>
</Steps>
<YouTube id="dQw4w9WgXcQ" title="Getting started" />
<ImageFigure src="/docs-template/screenshot.png" alt="Screenshot" caption="Docs template" />
<DataTable
columns={[{ key: "name", header: "Name" }]}
data={[{ name: "U-235" }]}
sortable
searchable
/>Supported types for <Callout>: info, note, warning, tip, success, danger.
Code blocks in Markdown and MDX automatically get a copy button.
This repo owns only the thin project layer. All shared UI, layouts, shortcodes, theme, and build tooling live in the @nukehub/docs-kit package.
.
├── astro.config.mjs # Astro + kit integration config
├── docs/ # Your Markdown/MDX documentation
│ ├── README.md # Becomes the home page
│ └── ...
├── public/ # Static assets (favicon, worker script)
├── src/
│ ├── content/ # Synced docs content (generated, gitignored)
│ ├── content.config.ts # Astro content collection schema
│ ├── data/ # site.ts, nav.ts, footer.ts (project-specific)
│ ├── env.d.ts # Astro client types
│ └── pages/ # Routing pages that pass data into kit layouts
└── package.json # Declares @nukehub/docs-kit as a dependency
Do not add copies of kit components or styles to src/. Update the kit via npm update @nukehub/docs-kit instead.
- Kit changes not appearing: run
npm update @nukehub/docs-kitand thennpm run build. - Stale content: run
npm run sync-docsmanually or deletesrc/content/docs/and rebuild. basepath mismatch: thebasevalue insrc/data/site.tsmust match your GitHub repository name (e.g.,/your-repo).- 404 on refresh: GitHub Pages is configured for static hosting; ensure Pages source is set to GitHub Actions.
The included .github/workflows/deploy.yml builds and deploys to GitHub Pages on every push to main. Make sure the repository Pages source is set to GitHub Actions.
Every built HTML page also gets a Markdown sibling. For example, /tutorials/getting-started/ has a matching /tutorials/getting-started/index.md.
- Direct
.mdURLs serve the Markdown file. public/_worker.jsenablesAccept: text/markdowncontent negotiation on hosts that support Cloudflare Pages advanced-mode Workers.- GitHub Pages serves the generated
.mdfiles statically, but cannot negotiate byAcceptheader.
- The theme engine stores the preference in
localStorageunderdocs-themeand applies it viadata-themeon<html>. Accent color is stored underdocs-accentand applied viadata-accent; the favicon and<meta name="theme-color">follow the resolved theme and accent. public/favicon.svgis the no-JS fallback. When JavaScript runs, the kit replaces it with a data-URI SVG colored from the current--primaryCSS variable.- The command palette indexes doc titles, descriptions, and categories; open it with Cmd/Ctrl+K.
- Right-click anywhere to open a custom context menu with search, copy, and navigation.
- The sidebar is generated from the synced docs file tree.
- A scroll-progress bar appears at the top of doc pages.
- Code blocks get an automatic copy button.
BSD-2-Clause — see the LICENSE file.