Skip to content

Interaction case · Phase 1 refactor

Three themeConfigs, One Source of Truth ​

Pass·VitePress 1.6.4

TL;DR ​

The site carried the same navigation in three places: the top-level themeConfig, the root locale and the zh locale. The AI partner assumed the root locale would inherit the top-level defaults, so editing the shared block would update English pages. It did not: the root locale had its own copy, which shadowed the defaults. The fix was not "copy the values again" but "remove the duplicate and make the merge order explicit".

Context ​

Phase 1 consolidated scattered configuration in a bilingual VitePress site. The relevant shape before the change was:

js
themeConfig: {
  logo, socialLinks, footer, editLink,
  nav: [...], sidebar: {...}          // English defaults
},
locales: {
  root: { themeConfig: { nav, sidebar } }, // duplicate of the defaults
  zh:    { themeConfig: { nav, sidebar, editLink } }
}

VitePress resolves a page's theme config as a shallow merge:

js
themeConfig: {
  ...siteData.themeConfig,
  ...siteData.locales[localeIndex]?.themeConfig
}

That behaviour is correct, but it means a locale block is not "only overrides" unless it is written that way. The root block was a full copy, so the top-level block was dead weight for English pages.

The information gap ​

AssumptionActual behaviourConsequence
Root inherits top-level navRoot has its own nav and wins the mergeEdits to the shared block never reach /
One source of truth existsThree copies can drift independentlySilent EN/ZH divergence
Removing the root block is safeOnly if English defaults live at the top levelRequires moving the defaults first

This is the kind of gap that does not produce an error message. Both copies were valid; the site simply ignored one of them.

Test design ​

  1. Move the English nav and sidebar to the top-level themeConfig.
  2. Delete the root.themeConfig block entirely.
  3. Keep only true overrides in zh.themeConfig (nav, sidebar, editLink).
  4. Build and inspect rendered navigation and sidebar on four routes: /, /projects/, /zh/, /zh/projects/.
  5. Confirm shared chrome (logo, footer, social link) still renders on both locales.

Evidence ​

CheckResult
Production buildPassed, 21 HTML pages
English navHome / Projects
Chinese nav首页 / 项目
English sidebarProjects by Role / Individual Projects
Chinese sidebar按角色分类 / 个人项目
Logo, footer, social linkPresent on both locales
Locale regressions0

Verdict ​

Pass. The consolidation removed a shadowing block instead of adding a fourth copy, and every rendered locale route was checked after the build.

The reusable rule: a locale themeConfig should contain only the keys that actually differ. Everything else belongs in the shared default, and the merge order should be documented next to it.

Next boundary to test ​

The next risk is not configuration but content: a single loader now feeds multiple card surfaces. That contract is covered in the content loader evaluation.

Crystaria (with Paw and Kyle)