Site Configuration

Last updated: 02/25/2026Edit this page

After scaffolding a project, the first thing you'll want to do is configure it for your brand. Trellis Docs keeps all configuration in four files under config/:

FilePurpose
config/site.tsSite identity, logo, color mode, search, and feature flags
config/navigation.tsTop navbar links and footer text
config/sidebar.tsDocumentation sidebar structure
config/variables.tsReusable content variables for MDX pages

Site settings

config/site.ts is the main configuration file. It controls your site's identity, branding, and optional features.

Identity & GitHub

SettingDescription
titleSite name shown in the navbar and browser tab
taglineShort description used on the landing page
urlProduction URL (e.g., https://docs.example.com)
baseUrlBase path — use '/' unless hosting under a subdirectory
faviconPath to favicon relative to public/
organizationNameGitHub org or username
projectNameRepository name
repoUrlFull GitHub repo URL — powers the navbar GitHub link
editBaseUrlBase URL for "Edit this page" links (e.g., https://github.com/org/repo/edit/main)
SettingDescription
logo.navbarImage path for the navbar logo (relative to public/)
logo.heroImage path for the landing page hero — set to null to use navbar
logo.altAlt text for the logo image
logo.useBuiltInWhen true, renders the SVG component from components/brand/ instead of an <img> tag

Color mode

SettingDescription
colorMode.defaultMode'dark' or 'light' — the default theme
colorMode.respectPrefersColorSchemeWhen true, follows the user's OS preference

The built-in search indexes all documentation pages at build time. You can tune relevance with weights and exclude folders from indexing.

SettingDescription
search.weights.titleWeight for page titles (default 1.0)
search.weights['sections.heading']Weight for section headings (default 1.0)
search.weights.keywordsWeight for frontmatter keywords (default 0.8)
search.weights.descriptionWeight for frontmatter description (default 0.6)
search.weights['sections.content']Weight for section body text (default 0.5)
search.weights.contentWeight for full page content (default 0.4)
search.excludedFoldersFolders to skip (default ['includes', '_includes'])
search.excludedPrefixesFile prefixes to skip (default ['_'])

See Smart Search for more details.

Blog

Set enabled: false to disable the /blog route and hide the Blog link from the navigation. When enabled, choose between two layouts.

LayoutDescription
'minimal'Clean typography-driven list with featured post hero and simple article pages
'modern'Gradient heroes, animated card grid, author bio cards, and related posts
config/site.ts
blog: {
  enabled: true,
  layout: 'minimal' as 'modern' | 'minimal',
},

Release notes

Set enabled: false to disable the /release-notes route and hide the Release Notes link from the navigation. When enabled, choose between two layouts. Trellis Docs automatically detects and styles the content sections (## Added, ## Changed, ## Fixed, ## Removed).

LayoutDescription
'changelog'Simple card list with colored section badges — classic changelog style
'modern'Gradient featured hero, icon-decorated section cards with item counts
config/site.ts
releaseNotes: {
  enabled: true,
  layout: 'changelog' as 'modern' | 'changelog',
},

Subscribe call-to-action (CTA)

An optional email subscription form shown on the blog index and release notes index pages. When enabled, a dark gradient card with an email input and "Subscribe" button appears at the bottom of each page. The form POSTs { email } as JSON to your configured URL.

SettingDescription
subscribe.enabledSet to true to show the subscribe form
subscribe.urlThe endpoint that receives the POST request (e.g., Mailchimp, Buttondown, ConvertKit, or a custom API)
config/site.ts
subscribe: {
  enabled: true,
  url: 'https://buttondown.com/api/emails/your-newsletter',
},

When enabled is false or url is empty, the subscribe form is hidden. No setup needed by default.

Role chip colors

Customize the background color of role chips per role name. Trellis Docs automatically calculates text color (black or white) based on contrast.

config/site.ts
roleColor: {
  Admin: '#DAFA87',
  Editor: '#f7c948',
  Viewer: '#6bc4ff',
  Developer: '#EA5353',
},

Roles not listed in roleColor fall back to the theme's --primary color. This setting is optional — omit it entirely to use the default color for all roles.

Feature flags

Several features can be toggled with an enabled property. Blog and release notes are enabled by default — set enabled: false to turn them off. The features below are disabled by default. Each has a dedicated guide with full setup instructions.

API documentation

Render OpenAPI/Swagger specs as interactive API reference pages. Place your spec files (YAML or JSON) in the specDir directory. See the API Documentation guide.

config/site.ts
apiDocs: {
  enabled: true,
  specDir: 'content/api',
  routeBasePath: 'api',
  viewerOptions: {} as Record<string, unknown>,
},

Internationalization (i18n)

Serve your docs in multiple languages. Add locale entries and create translated content files. See the i18n guide.

config/site.ts
i18n: {
  enabled: true,
  defaultLocale: 'en',
  locales: [
    { code: 'en', name: 'English', dir: 'ltr' as const },
    { code: 'es', name: 'Español', dir: 'ltr' as const },
    { code: 'ja', name: '日本語', dir: 'ltr' as const },
  ],
},

Versioning

Snapshot your docs at a release so users can browse previous versions. See the Versioning guide.

config/site.ts
versioning: {
  enabled: true,
  currentLabel: 'Latest',
},

After enabling, run the snapshot script to create your first version:

npm run version:snapshot 1.0.0

Full example

config/site.ts
export const siteConfig = {
  title: 'Acme Docs',
  tagline: 'Developer documentation for Acme Platform',
  url: 'https://docs.acme.com',
  baseUrl: '/',
  favicon: '/img/favicon.svg',
  organizationName: 'acme',
  projectName: 'acme-docs',
  repoUrl: 'https://github.com/acme/acme-docs',
  editBaseUrl: 'https://github.com/acme/acme-docs/edit/main',
  logo: {
    navbar: '/img/logo.svg',
    hero: null,
    alt: 'Acme Logo',
    useBuiltIn: false,
  },
  lastUpdated: {
    showAuthor: false,
  },
  colorMode: {
    defaultMode: 'dark' as const,
    respectPrefersColorScheme: true,
  },
  roleColor: {
    Admin: '#DAFA87',
    Editor: '#f7c948',
    Viewer: '#6bc4ff',
  },
  search: {
    excludedFolders: ['includes', '_includes'],
    excludedPrefixes: ['_'],
    weights: {
      title: 1.0,
      'sections.heading': 1.0,
      keywords: 0.8,
      description: 0.6,
      'sections.content': 0.5,
      content: 0.4,
    },
  },
  faq: {
    faqDir: 'content/docs/faq',
    basePermalink: '/faq',
  },
  subscribe: {
    enabled: true,
    url: 'https://buttondown.com/api/emails/acme-docs',
  },
  blog: {
    enabled: true,
    layout: 'minimal' as 'modern' | 'minimal',
  },
  releaseNotes: {
    enabled: true,
    layout: 'changelog' as 'modern' | 'changelog',
  },
  apiDocs: {
    enabled: true,
    specDir: 'content/api',
    routeBasePath: 'api',
    viewerOptions: {} as Record<string, unknown>,
  },
  i18n: {
    enabled: false,
    defaultLocale: 'en',
    locales: [
      { code: 'en', name: 'English', dir: 'ltr' as const },
    ],
  },
  versioning: {
    enabled: false,
    currentLabel: 'Latest',
  },
}

config/navigation.ts defines the top navbar and footer. The navbar supports flat links and dropdown groups.

config/navigation.ts
export const navItems = [
  // Flat link
  { label: 'Introduction', href: '/introduction/' },

  // Dropdown group
  {
    label: 'Resources',
    items: [
      { label: 'Release Notes', href: '/release-notes/' },
      { label: 'Blog', href: '/blog/' },
      { label: 'FAQs', href: '/faq/' },
    ],
  },

  // External link
  { label: 'GitHub', href: 'https://github.com/acme/acme-docs' },
]

Each item has a label (display text) and either:

  • href — a direct link (internal route or external URL)
  • items — an array of child links rendered as a dropdown
config/navigation.ts
export const footerConfig = {
  copyright:${new Date().getFullYear()} Acme Inc.`,
  poweredBy: 'Powered by Next.js',
}

config/sidebar.ts defines the documentation sidebar. It exports a mainSidebar array of items that can be nested to any depth.

Item types

TypeFieldsDescription
docid, label?A documentation page. id is the file path under content/docs/ without the extension.
categorylabel, items, link?, collapsed?A collapsible group of items. Set link to make the label clickable.
linklabel, hrefAn external or arbitrary link in the sidebar.
apiid, label?An OpenAPI spec page (requires API Documentation enabled).

Example

config/sidebar.ts
export const mainSidebar: SidebarItem[] = [
  { type: 'doc', id: 'getting-started' },
  {
    type: 'category',
    label: 'Guides',
    collapsed: false,
    items: [
      { type: 'doc', id: 'guides/writing-docs' },
      { type: 'doc', id: 'guides/deployment' },
    ],
  },
  {
    type: 'category',
    label: 'API',
    link: 'api/index',
    collapsed: true,
    items: [
      { type: 'doc', id: 'api/authentication' },
      { type: 'doc', id: 'api/endpoints' },
    ],
  },
]
Note

The id field maps to a file path under content/docs/. For example, id: 'guides/docs' resolves to content/docs/guides/docs.mdx (or .md).

Content variables

config/variables.ts defines key-value pairs that you can reference in any MDX page using {vars.key}.

config/variables.ts
export const docVariables: Record<string, string> = {
  productName: 'Acme Platform',
  companyName: 'Acme Inc.',
  version: '2.1.0',
  frameworkName: 'Next.js',
}

Then in any MDX file:

Welcome to {vars.productName} version {vars.version}.

This renders as: "Welcome to Acme Platform version 2.1.0."

Trellis Docs injects variables at build time, so changes require restarting the dev server or rebuilding.

Tip

After scaffolding, start by customizing config/site.ts (your site identity and logo) and config/sidebar.ts (your page structure). The other two files work well with their defaults.


Was this page helpful?