Skip to Content

Configuration

Every option of your site, from press.config.tsx to the integration.

press.config.tsx at the project root configures your site. Only createPress() is required. The file can await your collections.

press.config.tsx
import { getCollection } from "astro:content";
import { toFumadocsSource } from "@fumadocs/astro/source";
import { createPress } from "@fumapress/astro/config";
import { linkValidationPlugin } from "@fumapress/astro/plugins/link-validation";

export const app = createPress(
  toFumadocsSource(await getCollection("docs"), await getCollection("meta")),
  { i18n },
).plugins(linkValidationPlugin());

export default app.config({
  site: { name: "Acme" },
  head: [{ tag: "link", attrs: { rel: "icon", href: "/favicon.ico" } }],
  ui: { layoutProps, renderPage },
});

Content and Plugins

createPress() takes your content sources and these options:

.plugins() adds plugins. Call it once.

To change the default plugins, set preset in .config().

Site

Name

site.name shows in the navbar and page metadata.

press.config.tsx
createPress(content).config({
  site: {
    name: "Acme Docs",
  },
});

URL

Set site in your Astro config. Without it, canonical links, the sitemap, RSS and Open Graph images fall back to relative URLs.

astro.config.mjs
export default defineConfig({
  site: "https://docs.example.com",
  integrations: [press()],
});

Repository

site.git adds a repository link to the navbar and a link to the source file of each page.

press.config.tsx
createPress(content).config({
  site: {
    git: {
      user: "acme",
      repo: "docs",
      branch: "main",
    },
  },
});

GitHub is the default. For GitLab or Bitbucket, set provider. For a self-hosted instance, also set url.

Source file links need the git root. Set rootDir when the build runs without a .git directory.

All Site Options

Prop

Type

Head Tags

head adds tags to <head> on every page, like analytics or fonts.

press.config.tsx
createPress(content).config({
  head: [{ tag: "meta", attrs: { name: "theme-color", content: "#000000" } }],
});

attrs take HTML attribute names, like crossorigin and http-equiv, not the React props.

These tags have a key: title, a meta tag by its name, property or http-equiv, the canonical link, and an alternate link by its hreflang. Your tags replace plugin tags with the same key. Other tags are kept, except exact duplicates.

Tags per Page

Use a function. When page is undefined, the tags you return apply to the whole site:

press.config.tsx
createPress(content).config({
  head({ page }) {
    if (!page)
      return [{ tag: "link", attrs: { rel: "icon", href: this.withBase("/favicon.ico") } }];
    if (page.path.startsWith("blog/"))
      return [{ tag: "meta", attrs: { property: "og:type", content: "article" } }];
  },
});

this.withBase() adds the base path for a site with a base path.

UI

These options change the look of your site. Most of them are under ui in .config().

The navbar shows site.name, linked to your home page. ui.layoutProps adds links and changes the title for every layout:

press.config.tsx
createPress(content).config({
  ui: {
    layoutProps: {
      nav: { title: "Acme" },
      links: [
        { url: "/blog", text: "Blog", active: "nested-url" },
        { url: "https://github.com/acme", text: "GitHub", external: true },
      ],
    },
  },
});

See Layout Links and Navbar for what they accept. ui.layoutProps also takes the props that every docs layout shares, like sidebar and tabs.

Links from plugins come after yours. For other options, your value takes priority.

nav.title can be any React element:

press.config.tsx
createPress(content).config({
  ui: {
    layoutProps: {
      nav: {
        title: (
          <>
            <img src="/logo.png" width={64} height={64} className="size-8" alt="" />
            Acme
          </>
        ),
      },
    },
  },
});

With internationalization, use a function. this.localizePath() adds the language prefix.

press.config.tsx
createPress(content, { i18n }).config({
  ui: {
    layoutProps({ lang }) {
      return {
        links: [
          {
            url: this.localizePath(lang, "/blog"),
            text: lang === "zh" ? "部落格" : "Blog",
          },
        ],
      };
    },
  },
});

To keep layoutProps in its own file, type it with UIOptions:

src/lib/layout-props.tsx
import type { UIOptions } from "@fumapress/astro/config";
import type { app } from "../../press.config";

export const layoutProps: UIOptions<typeof app>["layoutProps"] = function ({ lang }) {
  return { links: [{ url: this.localizePath(lang, "/blog"), text: "Blog" }] };
};

Colors

Swap the theme import in src/app.css. See Fumadocs UI Themes for the presets.

@fumapress/astro/css/default.css is a shortcut for these imports with the neutral theme, so replace it with them first.

src/app.css
@import "tailwindcss";
@import "fumadocs-ui/css/neutral.css";
@import "fumadocs-ui/css/black.css";
@import "fumadocs-ui/css/preset.css";
@import "@fumapress/astro/css/preset.css";

Dark Mode

Start in dark mode with ui.providerProps:

press.config.tsx
createPress(content).config({
  ui: {
    providerProps: {
      theme: { defaultTheme: "dark" },
    },
  },
});

Fonts

Load the font in head, then set it in src/app.css:

createPress(content).config({
  head: [
    { tag: "link", attrs: { rel: "preconnect", href: "https://fonts.googleapis.com" } },
    {
      tag: "link",
      attrs: { rel: "preconnect", href: "https://fonts.gstatic.com", crossorigin: "" },
    },
    {
      tag: "link",
      attrs: {
        rel: "stylesheet",
        href: "https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap",
      },
    },
  ],
});

Other UI Options

Integration

press() also takes the options of @fumadocs/astro, like collections and rehypeCodeOptions. It adds the React and MDX integrations, so don't list them yourself.

astro.config.mjs
import { defineConfig } from "astro/config";
import press from "@fumapress/astro";

export default defineConfig({
  integrations: [
    press({
      components: "./src/components/mdx.tsx",
    }),
  ],
});

Prop

Type

Types

Export the result of .plugins() as app, and pass typeof app to the type helpers from @fumapress/astro/config:

src/layouts/Docs.astro
---
import type { LayoutProps } from "@fumapress/astro/config";
import type { app } from "../../press.config";

type Props = LayoutProps<typeof app, "docs">;
---
HelperFor
RenderPagePropsprops of ui.renderPage, narrowed to a source or plugin page
UIOptionsan option of ui, like UIOptions<typeof app>["layoutProps"]
PressContextthis in callbacks, the result of getPressContext()
SharedLayoutPropsthe props of every docs layout
ProviderPropsthe root provider props

An .astro layout takes LayoutProps as props, and its island takes IslandProps.

Last updated on

On this page