Skip to main content

Docusaurus Setup


A complete guide to integrating docsgen into a Docusaurus 3 project, including plugin configuration, sidebar setup, and the optional importer remark plugin.


Step 1 - Install Dependencies

npm install @docsgen/core @docsgen/docusaurus

Step 2 - Add the Plugin

In docusaurus.config.ts, add @docsgen/docusaurus to the plugins array:

import plugin from "@docsgen/docusaurus";

const config = {
plugins: [
[
"@docsgen/docusaurus",
{
id: "api",
outDir: "docs/api",
packages: [
{
title: "core",
dir: "../packages/core",
entryPath: "src/index.ts",
tsconfigDir: "../packages/core",
},
],
} satisfies Parameters<typeof plugin>[1],
],
],
};

The id should be unique if you use multiple docsgen instances. The outDir determines where generated MDX files are placed, relative to your Docusaurus site root.


Step 3 - Configure Sidebars

The simplest approach is to use Docusaurus autogenerated sidebars. In sidebars.ts:

const sidebars = {
docs: [
{
type: "autogenerated",
dirName: ".",
},
],
};

export default sidebars;

docsgen writes _category_.json files in each category folder, so Docusaurus automatically picks up the correct sidebar positions and labels.

If you want a dedicated API sidebar separate from your main docs:

const sidebars = {
docs: [{ type: "autogenerated", dirName: "guides" }],
api: [{ type: "autogenerated", dirName: "api" }],
};

Step 4 - Add the Importer (Optional)

To embed API fragments in hand-written MDX, add the importer remark plugin to your docs preset:

import { importer } from "@docsgen/core";

const config = {
presets: [
[
"classic",
{
docs: {
remarkPlugins: [
importer({
packageRoute: "api",
apiDir: "docs/api",
}),
],
},
},
],
],
};

The packageRoute should match the id used in the plugin config. The apiDir should match the outDir.


Step 5 - Build and Verify

Run the Docusaurus build:

npm run build

Or start the dev server:

npm run start

docsgen will run during the build, parse your TypeScript source, generate MDX files, and place them in the configured outDir. You should see log output from the generation process.


Complete Example

Here is a full docusaurus.config.ts based on the HyperFetch documentation:

import { importer } from "@docsgen/core";
import plugin from "@docsgen/docusaurus";
import type { Config } from "@docusaurus/types";
import type * as Preset from "@docusaurus/preset-classic";
import path from "path";
import fs from "fs";

const apiDocs = "api";
const apiDocsDir = "docs/api";

const getPackagesList = () => {
const dirPath = path.join(__dirname, "../packages");
return fs
.readdirSync(dirPath)
.filter((p) => ![".DS_Store"].includes(p))
.map((dirName) => ({
title: dirName.charAt(0).toUpperCase() + dirName.slice(1),
dir: path.join(dirPath, dirName),
entryPath: "src/index.ts",
tsconfigDir: path.join(dirPath, dirName),
}));
};

const config: Config = {
title: "My Library",
url: "https://my-library.dev",
baseUrl: "/",

presets: [
[
"classic",
{
docs: {
sidebarPath: "./sidebars.ts",
remarkPlugins: [
importer({
packageRoute: apiDocs,
apiDir: apiDocsDir,
}),
],
},
} satisfies Preset.Options,
],
],

plugins: [
[
"@docsgen/docusaurus",
{
id: apiDocs,
outDir: apiDocsDir,
packages: getPackagesList(),
logLevel: "trace",
addMonorepoPage: false,
addPackagePage: false,
} satisfies Parameters<typeof plugin>[1],
],
],
};

export default config;

Monorepo Tips

When to use it
  • Dynamic package discovery - Use fs.readdirSync to automatically find all packages in a monorepo directory, as shown in the example above.
  • Per-package overrides - Set generateMdx, outDir, or hasPackagePage on specific packages to control their output independently.
  • Kind remapping - Use kindMapper to rename categories like "Functions" to "Hooks" for React hook packages.
  • Category ordering - Use orderCategories to ensure consistent sidebar order across packages.
Summary

Integration requires adding the @docsgen/docusaurus plugin with package configurations, setting up autogenerated sidebars, and adding the importer remark plugin for @import directives. Once configured, your documentation updates automatically every time you build - generated API pages reflect the latest code, and @import directives in hand-written guides pull fresh data from the same source. No manual sync, no stale docs.