Customization

Configuration

Configure ReallySimpleDocs in astro.config.mjs:

astro.config.mjs
import { defineConfig } from "astro/config";
import reallySimpleDocs from "reallysimpledocs/astro";

export default defineConfig({
  integrations: [
    reallySimpleDocs({
      docsDir: "./docs",
      routeBase: "/docs",
      customCss: ["./src/docs.css"],
      site: {
        title: "Acme Docs",
        subtitle: "v1.0.0",
        description: "Documentation for Acme.",
        url: "https://docs.example.com",
      },
    }),
  ],
});
OptionDefaultNotes
docsDir"./docs"Folder containing Markdown or MDX pages and docs.json.
routeBase"/docs"URL path where the docs are mounted. Use "/" for root docs.
style"vega"Basecoat style: vega, nova, maia, lyra, mira, luma, sera, or rhea.
customCss[]CSS files imported after Basecoat and ReallySimpleDocs styles.
csstrueSet to false when you provide the full CSS pipeline yourself.
bodyAttrs{}Extra attributes added to <body>.
components.HeadEmptyAstro component appended to the document <head>.
components.SidebarHeaderDefault headerAstro component used for the sidebar header.
components.SidebarFooterEmpty footerAstro component used for the sidebar footer.
components.ContentHeaderEmptyAstro component rendered between search and the built-in theme toggle.
site{}Site metadata used by layout, SEO tags, and default UI.
assetsBase"/assets"Base path for relative favicon, social image, and logo asset values.

Site metadata

site controls the default sidebar header, document titles, and metadata:

astro.config.mjs
reallySimpleDocs({
  site: {
    title: "Acme Docs",
    subtitle: "v1.0.0",
    description: "Documentation for Acme.",
    url: "https://docs.example.com",
    favicon: "favicon.svg",
    appleTouchIcon: "apple-touch-icon.png",
    socialImage: "social.png",
    logo: {
      url: "/assets/favicon.svg",
    },
  },
});

Relative asset values resolve from assetsBase, which defaults to /assets. Favicon and social image tags are emitted only when configured.

Sitemap

Use Astro’s sitemap integration when you need a sitemap. ReallySimpleDocs does not generate its own sitemap.

npm install @astrojs/sitemap
astro.config.mjs
import sitemap from "@astrojs/sitemap";
import { defineConfig } from "astro/config";
import reallySimpleDocs from "reallysimpledocs/astro";

export default defineConfig({
  site: "https://docs.example.com",
  integrations: [reallySimpleDocs(), sitemap()],
});

The integration writes sitemap-index.xml and sitemap chunk files during astro build. It is not served by astro dev.

Robots

Add robots.txt as a static file when you need one:

public/robots.txt
User-agent: *
Allow: /

Sitemap: https://docs.example.com/sitemap-index.xml

Component overrides

Override layout regions when the default docs shell is not enough:

astro.config.mjs
reallySimpleDocs({
  components: {
    Head: "./src/docs/Head.astro",
    SidebarHeader: "./src/components/SidebarHeader.astro",
    SidebarFooter: "./src/components/SidebarFooter.astro",
    ContentHeader: "./src/components/ContentHeader.astro",
  },
});

Use Head to add scripts, styles, preload tags, or site-specific metadata to the document <head>. The default RSD head scripts and metadata still render.

src/docs/Head.astro
<script src="/assets/docs.js" defer></script>

Head receives config, site, title, description, pagePath, metaTitle, and absoluteUrl.

SidebarHeader

Use SidebarHeader when the default logo/title block is not enough.

src/components/SidebarHeader.astro
---
const { site } = Astro.props;
---

<a href="/" class="btn" data-variant="ghost">
  {site.title}
</a>

SidebarFooter

Use SidebarFooter for persistent sidebar actions or secondary links.

src/components/SidebarFooter.astro
<div class="p-2 text-xs text-muted-foreground">
  v1.0.0
</div>

ContentHeader

Use ContentHeader for controls between search and the built-in theme toggle. Header actions, such as a GitHub link, belong in this component rather than in site metadata.

src/components/ContentHeader.astro
<nav class="flex items-center gap-2">
  <a class="btn" data-variant="outline" data-size="sm" href="https://github.com/acme/project">
    GitHub
  </a>
</nav>

ContentHeader receives site and page.

Custom landing pages, marketing pages, blogs, and app pages should stay as normal Astro routes outside the ReallySimpleDocs docs route.

CSS and Basecoat

ReallySimpleDocs is built on Basecoat. Pick a Basecoat style with style, then add project-specific CSS with customCss:

astro.config.mjs
reallySimpleDocs({
  style: "nova",
  customCss: ["./src/docs.css"],
});
src/docs.css
:root {
  --primary: oklch(54.6% 0.245 262.881);
}

.dark {
  --primary: oklch(70.7% 0.165 254.624);
}

By default, ReallySimpleDocs manages one Tailwind/Basecoat stylesheet for the app. It scans:

  • src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}
  • docs/**/*.{md,mdx}
  • ReallySimpleDocs runtime components

That means custom Astro pages outside the docs route can use Tailwind and Basecoat classes without a separate stylesheet.

Managed CSS

Disable managed CSS only when you want to own the full stylesheet pipeline:

astro.config.mjs
reallySimpleDocs({
  css: false,
});

With managed CSS enabled, ReallySimpleDocs inserts:

  • Tailwind
  • the selected Basecoat style
  • RSD layout/component CSS
  • each customCss file

Use css: false when you bring your own Tailwind/Basecoat/RSD stylesheet.

When managed CSS is disabled, import RSD’s own docs CSS from the public package entry:

src/docs.css
@import "reallysimpledocs/css";
@import "reallysimpledocs/css/styles/vega";

Use the reallysimpledocs/css/styles/{style} import that matches your Basecoat style.

ReallySimpleDocs always inserts its managed JavaScript: theme initialization, Basecoat JavaScript, copy-code behavior, and command search behavior.

When you disable managed CSS, use these source files as references for what you may need to reproduce:

Prefer style and customCss for normal styling changes, and Head or ContentHeader for additive UI. Use css: false only when you are replacing RSD’s stylesheet pipeline.

Public files

Put docs media in public/media/ and reference it with absolute paths:

docs/page.md
![Diagram](/media/diagram.png)

Put favicon and social assets in public/assets/ when using the default assetsBase.

Search uses a generated Lunr index. ReallySimpleDocs indexes normalized Markdown, including fallback Markdown for known MDX components, while keeping code examples separate so prose matches stay readable.

Render the exported CommandDialog on any Astro page when you want docs search outside the ReallySimpleDocs route:

src/pages/index.astro
---
import { CommandDialog } from "reallysimpledocs/components";
---

<CommandDialog />

<button type="button" class="btn" onclick="window.rsdOpenCommandSearch?.()">
  Search docs
</button>

CommandDialog uses the generated docs search index by default. Pass indexUrl only when you need to point at a different index.

src/pages/index.astro
<CommandDialog indexUrl="/docs/search-index.json" />

The dialog registers window.rsdOpenCommandSearch() and the ⌘K / Ctrl+K shortcut on pages where it is rendered.

htmx

Install htmx first:

npm install htmx.org

Use bodyAttrs to boost links into the docs content container. Because the sidebar is outside #content, update its current-page state from Head after htmx swaps:

reallySimpleDocs({
  bodyAttrs: {
    "hx-boost": "true",
    "hx-target": "#content",
    "hx-select": "#content",
    "hx-swap": "outerHTML",
    "hx-push-url": "true",
  },
  components: {
    Head: "./src/docs/Head.astro",
  },
});

Using a CDN is also fine; see the htmx installation docs for options.