Qubik's Site

themeConfig Reference

Every user-facing option of VitePress Theme Terminal, with its type, default, and an example. This is the complete configuration surface: with very few documented exceptions (listed at the end), nothing the theme lets you configure lives anywhere else.

The schema itself is TerminalThemeConfig in .vitepress/theme/config.ts; the defaults below are the themeConfigDefaults object in the same file. Every option is optional — an unset option falls back to its default.

ts
ts
// .vitepress/config.mts
import { defineConfigWithTheme } from "vitepress";
import type { TerminalThemeConfig } from "./theme/config";

export const themeConfig: TerminalThemeConfig = {
  mainColor: "#80E0A7",
  // …
};

export default defineConfigWithTheme<TerminalThemeConfig>({
  themeConfig,
  // …
});

Export the object (rather than inlining it) — the build-time dynamic-route loaders under src/ import it to apply the same series toggles the components use.

Localizable text

Any option documented as LocalizableText accepts either a plain string (used for every language) or a per-language map keyed by BCP 47 tag:

ts
ts
title: "VitePress Theme Terminal"
title: { en: "VitePress Theme Terminal", "zh-Hans": "VitePress 终端主题" }

A map is resolved against the active UI language: exact tag → primary subtag (zh-CN matches a zh entry) → en → first entry. See guide/internationalization.md.

Quick reference

OptionTypeDefault
mainColorstring'#80E0A7'
titleLocalizableText'' (site config title)
descriptionLocalizableText'' (site config description)
siteNamestring'' (normalized site title)
localeStringsRecord<string, Partial<ThemeLocaleStrings>>{}
authorTerminalAuthorConfig{ name: 'Admin', username: 'admin' }
licenseTerminalLicenseConfigCC BY-NC-SA 4.0 (see below)
toolbarTerminalToolbarConfig{ nav: [], actions: [] }
explorerTerminalExplorerItem[] | 'auto'[] (no explorer)
tocTerminalTocConfig{ enabled: true, minLevel: 2, maxLevel: 3, minHeadings: 2 }
footerTerminalFooterConfig{ rss: '', social: [] }
taxonomyTerminalTaxonomyConfig{ tags: {}, categories: {} }
seriesTerminalSeriesConfigall four toggles false
homeTerminalHomeConfig{}
friendsTerminalFriendsConfig{ showCount: true, showRandom: true, groups: {} }
searchTerminalSearchConfig{ provider: 'algolia', algolia: null }
commentsTerminalCommentsConfig{ provider: 'waline', waline: null }

mainColor

  • Type: string (any CSS color; hex is conventional)
  • Default: '#80E0A7'

The single configurable color of the theme. Every auxiliary tone — hover, dimmed text, subtle backgrounds, borders, selection — is derived from it in SCSS and is never configured separately (that rule is binding: design/color-system.md §2–3). The value is written into <head> at build time as the --ct-main custom property, so there is no flash of the default color.

ts
ts
mainColor: "#80E0A7",

title

  • Type: LocalizableText
  • Default: '' — falls back to the site config's title

The site title as shown in theme chrome and the browser tab. The site config's title stays the server-rendered default; a per-language map here is applied client-side when the UI language changes.

ts
ts
title: { en: "VitePress Theme Terminal", "zh-Hans": "VitePress 终端主题" },

description

  • Type: LocalizableText
  • Default: '' — falls back to the site config's description

Same rules as title; drives the home page tagline fallback and the meta[name=description] tag on language switches.

ts
ts
description: {
  en: "A TUI-inspired VitePress Theme for Blog and Personal Website",
  "zh-Hans": "一个受 TUI 界面风格启发的 VitePress 博客与个人网站主题",
},

siteName

  • Type: string
  • Default: '' — the active site title, normalized automatically

The shell-safe host segment in card prompt decorations (user@host:~$ …). The value is trimmed; blank or unset means "derive from the site title". It is normalized like any prompt identifier: diacritics stripped, lowercased, whitespace → -, anything outside a-z 0-9 . _ - dropped.

ts
ts
siteName: "vitepress-theme-terminal",

localeStrings

  • Type: Record<string, Partial<ThemeLocaleStrings>> — BCP 47 tag → partial string table
  • Default: {}

Per-language overrides of the theme's own UI strings, applied on top of the built-in tables (en, zh-Hans). A complete table under a new tag adds a whole language to the switcher. The UI language is a client-side preference — there are no /<lang>/ URL trees.

ts
ts
localeStrings: {
  "zh-Hans": { "mode.paper": "阅读" },
  fr: { "lang.label": "Français", "mode.dark": "Sombre", /* … */ },
},

See guide/internationalization.md for the key list and what a complete table requires.

author

  • Type: TerminalAuthorConfig
  • Default: { name: 'Admin', username: 'admin' }
FieldTypeDefault
nameLocalizableText'Admin'
usernamestringderived from name ('user' if nothing usable)

The single source for the footer copyright, shell-prompt decorations, author displays, and the license card. username is the shell-safe prompt identifier; when unset it is derived from name with the normalization described under siteName.

ts
ts
author: { name: "Ada Lovelace", username: "ada" },

license

  • Type: TerminalLicenseConfig

  • Default:

    ts
    ts
    {
      name: "CC BY-NC-SA 4.0",
      url: "https://creativecommons.org/licenses/by-nc-sa/4.0/",
      icons: [
        "fa-brands fa-creative-commons",
        "fa-brands fa-creative-commons-by",
        "fa-brands fa-creative-commons-nc",
        "fa-brands fa-creative-commons-sa",
      ],
    }
FieldTypeDefault
namestring'CC BY-NC-SA 4.0'
urlstringthe CC deed URL only while name is the default
iconsstring[] (Font Awesome class lists)the four CC brand icons, same condition

The content license, shown by the footer license cluster and the end-of-article license card. A custom name replaces the default as a whole: the CC url and icons are not inherited, so supply your own (an unset field then means "none").

ts
ts
license: { name: "MIT", url: "https://opensource.org/license/mit/" },

toolbar

  • Type: TerminalToolbarConfig
  • Default: { nav: [], actions: [] }

The built-in ~/home tab and the search / color-mode controls always render; these entries add to them.

toolbar.nav

  • Type: TerminalNavItem[]
  • Default: []
FieldTypeRequiredNotes
textLocalizableTextyesTab label
linkstringyesSite-absolute path or external URL (opens in a new tab)
iconstringnoFont Awesome class list, rendered before the label (decorative)
itemsTerminalNavChild[]noChild links shown in a hover dropdown

A TerminalNavChild is { text: LocalizableText, link: string, icon?: string } — pure links, one level only. A tab with items still needs its own link, and highlights when either it or one of its children matches the current page.

toolbar.actions

  • Type: TerminalToolbarAction[]
  • Default: []
FieldTypeRequiredNotes
iconstringyesFont Awesome class list
linkstringyesSite-absolute path or external URL
labelLocalizableTextnoAccessible name / tooltip; falls back to the URL

Extra icon slots rendered before the built-in search and color-mode controls — the extension point for important social links or external tools.

ts
ts
toolbar: {
  nav: [
    {
      text: { en: "Guide", "zh-Hans": "指南" },
      link: "/guide/",
      icon: "fa-solid fa-book",
      items: [
        {
          text: { en: "Getting Started", "zh-Hans": "快速开始" },
          link: "/guide/getting-started",
          icon: "fa-solid fa-rocket",
        },
      ],
    },
    { text: "Archives", link: "/archives", icon: "fa-solid fa-box-archive" },
  ],
  actions: [
    {
      icon: "fa-brands fa-github",
      link: "https://github.com/iXORTech/vitepress-theme-terminal",
      label: "GitHub",
    },
  ],
},

When the bar cannot show the title, tabs, and icons in full, the nav and all action icons move into the [⋮] overflow drawer automatically — no configuration needed.

explorer

  • Type: TerminalExplorerItem[] | 'auto'
  • Default: [] — no explorer, and no tool-bar toggle

'auto' discovers every Markdown page below src/: directories become folders, each index.md becomes its folder's link, labels come from frontmatter. An explicit array is a hand-authored tree instead:

FieldTypeRequiredNotes
textLocalizableTextyesRow label
linkstringnoSite-absolute path or external URL; on a folder node this is its index page
itemsTerminalExplorerItem[]noChild nodes — their presence makes the node a folder
ts
ts
explorer: "auto",
ts
ts
explorer: [
  { text: { en: "Guide", "zh-Hans": "指南" }, link: "/guide/", items: [
    { text: "Getting Started", link: "/guide/getting-started" },
  ] },
],

Per-page and per-folder explorer metadata (labels, ordering, visibility) is authored beside the source pages, not here — see frontmatter.md and guide/navigation.md.

toc

  • Type: TerminalTocConfig
  • Default: { enabled: true, minLevel: 2, maxLevel: 3, minHeadings: 2 }
FieldTypeDefaultNotes
enabledbooleantrueMaster switch for the "on this page" panel
minLevelnumber2Shallowest heading level, clamped to 1–6
maxLevelnumber3Deepest heading level, clamped to 1–6
minHeadingsnumber2Headings required (within range) before the panel shows; rounded, minimum 1

A reversed minLevel/maxLevel pair is swapped rather than treated as empty. The panel renders only on article pages, never in paper mode or print, and is hidden below 1024 px.

ts
ts
toc: { enabled: true, minLevel: 2, maxLevel: 4, minHeadings: 3 },
  • Type: TerminalFooterConfig
  • Default: { rss: '', social: [] }
FieldTypeDefaultNotes
rssstring''Feed URL; the RSS icon renders only when set
socialTerminalSocialLink[][]Icons at the right of the copyright row

A TerminalSocialLink is { icon: string, link: string, label?: LocalizableText }icon is a Font Awesome class list, label is the accessible name and falls back to the URL.

The copyright author and the license icons are not configured here; they come from author and license.

ts
ts
footer: {
  rss: "/feed.rss",
  social: [
    { icon: "fa-brands fa-github", link: "https://github.com/…", label: "GitHub" },
  ],
},

taxonomy

  • Type: TerminalTaxonomyConfig
  • Default: { tags: {}, categories: {} }
FieldTypeDefault
tagsRecord<string, LocalizableText>{}
categoriesRecord<string, LocalizableText>{}

Display labels for taxonomy terms, keyed by the term name as authored in post frontmatter (matched case-insensitively through its slug, so Guides and guides share one entry). Display-only: slugs, /tags/… and /categories/… URLs, and grouping identity always come from the authored name, so routes never change with the language. A term without an entry renders verbatim.

ts
ts
taxonomy: {
  tags: { theme: { en: "theme", "zh-Hans": "主题" } },
  categories: { Guides: { en: "Guides", "zh-Hans": "指南" } },
},

series

  • Type: TerminalSeriesConfig
  • Default: every toggle false
FieldTypeDefaultIncludes series articles in
inPostsbooleanfalsethe post index and its pagination
inArchivesbooleanfalsethe archives timeline
inCategoriesbooleanfalsethe category index and per-category pages
inTagsbooleanfalsethe tag index and per-tag pages

Series articles always render on their own pages, on the series index, and in their series' landing list; these toggles decide whether they also join the general listings. An admitted article shows its series name before the title (Terminal Internals › Part 1).

ts
ts
series: { inArchives: true, inCategories: true, inTags: true },

home

  • Type: TerminalHomeConfig
  • Default: {} — the welcome card falls back to the site title/description
FieldTypeDefault
commandstring'whoami'
greetingLocalizableTextthe localized site title
taglineLocalizableTextthe localized site description
bodyLocalizableTextnone (paragraph omitted)
linksTerminalPageLink[][]

A TerminalPageLink is { text: LocalizableText, link: string, icon?: string } — rendered as call-to-action buttons; icon accepts a Font Awesome or Nerd Font class list.

ts
ts
home: {
  command: "whoami",
  greeting: { en: "Hi, I'm the Terminal theme", "zh-Hans": "你好,我是终端主题" },
  links: [{ text: "Read the guide", link: "/guide/", icon: "fa-solid fa-book" }],
},

The Projects and About pages are authored Vue views, not configuration — see guide/customization.md.

friends

  • Type: TerminalFriendsConfig
  • Default: { showCount: true, showRandom: true, groups: {} }
FieldTypeDefaultNotes
showCountbooleantruePer-group entry count in group headers
showRandombooleantrueThe [⇄ random] control above the groups
groupsRecord<string, { name?: LocalizableText, desc?: LocalizableText }>{}Display-label overrides keyed by group id

The friend-link data is deliberately not configured here — it lives in linksData.mjs modules under .vitepress/theme/assets/ (design/friend-links.md). This block only holds display options; groups localizes generated plain-string labels.

ts
ts
friends: {
  groups: {
    group2: {
      name: { en: "Group 2", "zh-Hans": "第二组" },
      desc: { en: "Localized via themeConfig.friends.groups.", "zh-Hans": "通过配置本地化。" },
    },
  },
},
  • Type: TerminalSearchConfig
  • Default: { provider: 'algolia', algolia: null }
FieldTypeDefaultNotes
provider'algolia''algolia'Reserved for future back-ends
algolia{ appId, apiKey, indexName }nullAll three strings required

The find palette (tool-bar magnifier or /) queries the index directly from the browser and renders results in its own TUI window — the theme does not use DocSearch's modal. Use the search-only (public) API key, never an admin key. An incomplete credential set counts as unconfigured: the palette still opens and shows a "not configured" notice.

ts
ts
search: {
  algolia: {
    appId: "YOUR_APP_ID",
    apiKey: "YOUR_SEARCH_ONLY_API_KEY",
    indexName: "YOUR_INDEX",
  },
},

comments

  • Type: TerminalCommentsConfig
  • Default: { provider: 'waline', waline: null }
FieldTypeDefaultNotes
provider'waline''waline'Reserved for future back-ends
waline{ serverURL: string }nullURL of your deployed Waline server

With a server URL set, every article ends with a comment card and shows view/comment counts near its title. A blank or absent URL counts as unconfigured — neither the card nor the counts render. A page opts out with comments: false in its frontmatter.

ts
ts
comments: { waline: { serverURL: "https://waline.example.com" } },

What is configured elsewhere (and why)

The rule is that user-facing options live in themeConfig. Three surfaces are documented exceptions, each because the data belongs with the content:

SurfaceWhere it livesWhy
Per-page metadata — titles, ordering, explorer visibility, taxonomy, coverspage frontmatter and adjacent explorer.json files (frontmatter.md)It describes one page and must travel with it
Series metadata — icon, title, description, ordersrc/series/<slug>/series.yml (design/content-architecture.md §5)It describes one content folder
Friend-link data.vitepress/theme/assets/**/linksData.mjs (design/friend-links.md)It is generated/synced from an external repository

Site-level VitePress options (title, description, lang, cleanUrls, lastUpdated, …) remain plain VitePress configuration; see clean-urls.md for the one whose behavior the theme depends on.

READ~/docs/configuration/theme-config
TOPdark