* feat(assets): refactor SCSS variables with Hugo config via hugo:vars Use Hugo's hugo:vars mechanism (v0.161.0+) to configure SCSS variables via [params.appearance] in hugo.toml, replacing the override.scss file. - Add [params.appearance] config section in hugo.toml - Create scss-vars.html partial for SCSS default values - Pass vars to toCSS via head/index.html - Rewrite _variables.scss to use @use "hugo:vars" as h with !default - Update all 20 consumer files from @use "override" to @use "variables" - Delete override.scss - Add admonition mixin in core/mixins/_admonition.scss - Update deprecation detection to use fileExists * refactor(assets): standardize module setup() and simplify main.ts init - Add setup() method to all modules (menu, theme, search, enc, misc, events) - Rename initMenu to setup, initMenuDesktop/initMenuMobile to initDesktop/initMobile - Rename initSearch, initFixItDecryptor to setup - Standardize setup() position at end of each module class and interface - Simplify main.ts init sequence to uniform setup() calls * refactor(assets): replace config.template.scss with hugo:vars/internal - Delete config.template.scss and its ExecuteAsTemplate pipeline - Pass internal config (base URL, logo, loading) via hugo:vars/internal namespace - Move CSS custom properties to _root.scss using set-fi-vars mixin - Simplify _variables.scss by removing config namespace dependency - Update CLAUDE.md to reflect new SCSS architecture * style(i18n): fix spacing in Korean translation strings * fix(assets): resolve dead SCSS config keys and deduplicate defaults - Wire up 5 config keys with v.$ references: menu-active-color, tag-cloud-start, tag-cloud-end, tag-cloud-end-dark, pagination-link-color-dark (were reading from SCSS vars, ignoring hugo:vars overrides) - Remove dead !default flags from all v.$ references (hugo:vars always provides values, making !default unreachable) - Compute derived defaults in scss-vars.html from base values instead of hardcoding duplicates - Extract admonition mixin set-fi-vars map to shared $vars variable
7.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
FixIt is a modern, responsive theme for the Hugo static site generator. Built with Hugo templates, SCSS, and TypeScript.
Development Commands
Prerequisites
- Node.js >= 20
- Hugo Extended >= 0.158.0 (Dart Sass required)
- pnpm
Development
pnpm install # Install dependencies
pnpm dev:demo # Start demo site dev server
pnpm dev:test # Start test site dev server
pnpm dev:docs # Start docs dev server (requires fixit-docs as sibling directory)
Build
pnpm build:demo # Build demo site
pnpm build:test # Build test site
pnpm build # Build all sites (demo + test, merged into public/)
pnpm preview # Preview built site (requires build first)
Code Generation
pnpm gen:lexers # Regenerate assets/scss/core/maps/_chroma-lexers.scss from Chroma source
Code Quality
pnpm lint # Run ESLint
pnpm typecheck # Run TypeScript type checking
There are no unit tests. Verify changes by building pnpm build:demo or pnpm build:test and inspecting the output.
Architecture
Monorepo Structure
Root package.json is @hugo-fixit/core. pnpm workspaces include apps/* and packages/*:
apps/demo/— Demo site (deployed todemo.fixit.lruihao.cn)apps/test/— Test site for exercising theme featurespackages/shared— Shared utilities (exportsworkspaceRoot,fromRoot,runCommand,capitalize,consola)packages/versioning— Version management (auto-updates version inlayouts/_partials/init/index.htmlduring pre-commit)packages/integration— Post-build: merges demo/test output intopublic/packages/chroma-lexers— Generates Chroma lexer SCSS map from GitHub
JavaScript Module System (assets/js/)
Service-class architecture with direct constructor calls:
main.ts— Entry point. Instantiates all modules with direct constructor calls, builds the typedwindow.fixitpublic API facade, and runs the init sequence onDOMContentLoaded.types/— TypeScript type definitions:config.ts—FixItConfigand all config sub-types.ui.ts—FixItPublicAPI, globalwindowaugmentation for third-party libs.third-party.ts— Types for vendored libraries.
core/— Infrastructure layer:event-bus.ts— Typed event bus singleton wrapping DOMCustomEvents. ExportseventBus(module-level singleton) andFixItEventMaptype.tokens.ts— Service interfaces (CoreService,ThemeService,CodeService, etc.) used for module constructor typing.
modules/— Feature modules. Each is a class implementing its service interface. Dependencies are constructor-injected. Private state uses ES6#fields. Modules: charts, code, content, core, encryption, events, menu, misc, search, theme, toc.pagefind.tsis a standalone factory consumed bySearchModule.utils/— Pure utility functions (no side effects, no DOM state). Re-exported fromutils/index.ts.lib/— Third-party library wrappers (aplayer, echarts, file-tree, fixit-decryptor, lightgallery, mapbox, mathjax, mermaid, etc.). All import the sharedeventBussingleton.head/—color-scheme.tsruns synchronously in<head>before body render to prevent flash of wrong theme.pages/— Page-specific scripts (e.g.link.tsfor the link guard redirection page).
Cross-module communication uses the shared eventBus singleton, not direct module imports. The window.fixit facade exposes a typed public API for user custom scripts (custom.ts): theme control, scroll state, mask overlay management, content re-initialization, and the event bus.
Hugo Templates (layouts/)
_partials/— Reusable template components (organized intoinit/,base/,function/,plugin/,single/,store/)_shortcodes/— 31 custom shortcodes (admonition, aplayer, echarts, file-tree, mermaid, tabs, timeline, etc.)_markup/— 15 render hooks (code blocks, headings, images, links, tables, blockquote alerts, passthrough for math)
Asset Pipeline
Hugo Pipes processes all assets. The key orchestration is in _partials/base/assets.html:
- CSS:
scss/main.scssis the entry point importingcore/,pages/,widgets/,custom. SCSS variables are configured viahugo:vars(user-configurable from[params.appearance]) andhugo:vars/internal(theme system config). - JS:
_partials/function/js-build.htmlwrapsjs.Buildwith minify-in-production defaults. Hugo's@paramsinjection passes config values into TypeScript at build time. - Third-party libraries: Stored in
assets/lib/(vendored, not npm-managed). Tracked bylibrarybot.ymland updated weekly by thehugo-fixit/librarybotGitHub Action. Can be overridden via CDN config inassets/data/cdn/jsdelivr.ymlorunpkg.yml.
Theme Configuration
hugo.toml— Default theme configuration (1700+ lines). Uses_merge = "shallow"to let user configs override without deep merging.theme.toml— Theme metadata
Coding Standards
SCSS (assets/scss/)
- CSS classes: BEM or semantic naming (
header-desktop,menu-item) - SCSS variables: hyphen-separated, semantic (
$global-font-family) - CSS custom properties: prefixed with
fi-/--fi- - Use CSS variables for theme switching; SCSS variables for colors (no hardcoded values)
- Prefer relative units (rem, em, %) over absolute units
- Keep selector nesting shallow
TypeScript
- Use ES6
#private fields — not TypeScriptprivatewith_prefix - One module per file, one service interface per module
- Constructor injection for dependencies — no global state access
- Import the shared
eventBussingleton fromcore/event-bus— do not create new instances - Pure functions only in
utils/— no side effects, no DOM state - Comment style: follow TSDoc conventions
Hugo Templates
- Variable naming: camelCase (
$footerConfig,$fingerprint) - Translation: use
Tfunction ({{ T "header.switchTheme" }}) - Whitespace: use
{{- -}}trim markers - Use
partialCachedfor expensive partials that don't change per page - Use
.Site.Storefor shared computed values (e.g. fingerprint) - Check
hugo.IsProductionbefore adding analytics or minification - Minimize
idattribute usage — prefer class selectors for styling and JS queries. Reserveidfor:<label for>,aria-controls/aria-labelledby, fragment anchors, or third-party library requirements
Commit Convention
Follows Conventional Commits:
<type>(<scope>): <subject>
Types: feat, fix, refactor, chore, docs, perf, style, test, ci, build
Scopes: workflow, archetypes, assets, i18n, layouts, config, or specific directories.
Pre-commit Hooks
Pre-commit runs: versioning (dev mode), typecheck, lint-staged (eslint --fix on staged files).
ESLint
Uses @antfu/eslint-config with TypeScript support. Config at eslint.config.ts.