扩展配置

提示

扩展配置是 Valaxy 提供的高阶配置,允许你自定义更多与底层/构建相关的配置。

以下是所有的扩展配置项与相关类型。

packages/valaxy/node/types/index.ts

package/valaxy/node/types/index.ts ValaxyExtendConfig
index.ts
ts
export * from './addon'
export * from './config'
export * from './hook'
export * from './loader'
export * from './options'
config.ts
ts
import type Vue from '@vitejs/plugin-vue'

import type { Hookable } from 'hookable'
import type { PluginVisualizerOptions } from 'rollup-plugin-visualizer'
import type { presetAttributify, presetIcons, presetTypography, presetWind4 } from 'unocss'
import type { VitePluginConfig as UnoCSSConfig } from 'unocss/vite'

import type Components from 'unplugin-vue-components/vite'
import type Markdown from 'unplugin-vue-markdown/vite'
import type { UserConfig as ViteUserConfig } from 'vite'
import type Layouts from 'vite-plugin-vue-layouts-next'
import type { groupIconVitePlugin } from 'vitepress-plugin-group-icons'
import type { EditableTreeNode } from 'vue-router/unplugin'
import type Router from 'vue-router/vite'
import type { DefaultTheme, PartialDeep, ValaxyConfig } from '../../types'
import type { createValaxyNode } from '../app'
import type { MarkdownOptions } from '../plugins/markdown/types'

import type { ValaxyAddons } from './addon'
import type { ValaxyHooks } from './hook'
import type { ContentLoader } from './loader'

import type { ResolvedValaxyOptions } from './options'

/**
 * @experimental
 * A module to load from CDN instead of bundling
 */
export interface CdnModule {
  /**
   * npm package name to externalize
   * @example 'vue'
   */
  name: string
  /**
   * Global variable name the library exposes on `window`
   * Used for mapping imports to `window[global]`
   * @example 'Vue'
   */
  global: string
  /**
   * Full CDN URL to the UMD/IIFE script
   * @example 'https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js'
   */
  url: string
  /**
   * Optional CSS URL if the module requires stylesheet
   * @example 'https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css'
   */
  css?: string
  /**
   * Named exports to re-export from the global variable.
   * Required for libraries that use named exports (e.g., `import { ref } from 'vue'`).
   * @example ['ref', 'computed', 'watch', 'createApp']
   */
  exports?: string[]
}

export type ValaxyNodeConfig<ThemeConfig = DefaultTheme.Config> = ValaxyConfig<ThemeConfig> & ValaxyExtendConfig
export type UserValaxyNodeConfig<ThemeConfig = DefaultTheme.Config> = PartialDeep<ValaxyNodeConfig<ThemeConfig>>
/**
 * fn with options for theme config
 */
export type ValaxyConfigFn<ThemeConfig = DefaultTheme.Config> = (options: ResolvedValaxyOptions<ThemeConfig>) => ValaxyNodeConfig | Promise<ValaxyNodeConfig>
export type ValaxyConfigExport<ThemeConfig = DefaultTheme.Config> = ValaxyNodeConfig<ThemeConfig> | ValaxyConfigFn<ThemeConfig>

export interface ValaxyNode {
  version: string

  hooks: Hookable<ValaxyHooks>
  hook: ValaxyNode['hooks']['hook']

  options: ResolvedValaxyOptions
}

export interface ValaxyExtendConfig {
  /**
   * Don't fail builds due to dead links.
   *
   * @default false
   * @deprecated use `build.ignoreDeadLinks` instead
   */
  ignoreDeadLinks?:
    | boolean
    | 'localhostLinks'
    | (string | RegExp | ((link: string) => boolean))[]

  /**
   * options for `valaxy build`
   */
  build: {
    /**
     * Don't fail builds due to dead links.
     * @zh 忽略死链
     * @default false
     */
    ignoreDeadLinks?:
      | boolean
      | 'localhostLinks'
      | (string | RegExp | ((link: string) => boolean))[]
    /**
     * Enable SSG for pagination
     * @en When enabled, it will generate pagination pages for you. `/page/1`, `/page/2`, ...
     * @zh 启用 SSG 分页,将单独构建分页页面 `/page/1`, `/page/2`, ...
     * @default false
     */
    ssgForPagination: boolean

    /**
     * SSG (Static Site Generation) configuration.
     */
    ssg?: {
      /**
       * @en SSG engine to use.
       * - `'valaxy'`: Built-in engine, no JSDOM dependency. (recommended)
       * - `'vite-ssg'`: Legacy engine based on vite-ssg / JSDOM.
       *
       * Can be overridden by CLI flag `--ssg-engine`.
       *
       * @zh 使用的 SSG 引擎。
       * - `'valaxy'`:内置引擎,无 JSDOM 依赖。(推荐)
       * - `'vite-ssg'`:基于 vite-ssg / JSDOM 的旧版引擎。
       *
       * 可通过 CLI 参数 `--ssg-engine` 覆盖。
       *
       * @default 'valaxy'
       */
      engine?: 'valaxy' | 'vite-ssg'
    }

    /**
     * @en FOUC (Flash of Unstyled Content) guard configuration.
     * Prevents layout shift on first paint by hiding the page body until
     * full CSS is loaded. Uses `body { opacity: 0 }` inline, then the
     * main stylesheet sets `body { opacity: 1 }` to reveal content.
     *
     * @zh FOUC(无样式内容闪烁)防护配置。
     * 通过在完整 CSS 加载前隐藏页面内容来防止首屏样式闪烁。
     * 内联 `body { opacity: 0 }`,完整 CSS 加载后通过 `body { opacity: 1 }` 解锁显示。
     */
    foucGuard?: {
      /**
       * @en Enable FOUC guard. When disabled, no opacity hiding or fallback
       * scripts will be injected.
       * @zh 是否启用 FOUC 防护。禁用后不会注入 opacity 隐藏及兜底脚本。
       * @default true
       */
      enabled?: boolean
      /**
       * @en Maximum wait time (ms) before force-showing the page, as a safety
       * fallback in case CSS fails to load. Set to `0` to disable the timeout
       * fallback (only `window.onload` will trigger reveal).
       * @zh 最大等待时间(毫秒),作为 CSS 加载失败时的安全兜底。
       * 设置为 `0` 可禁用超时兜底(仅依赖 `window.onload` 触发显示)。
       * @default 5000
       */
      maxDuration?: number
    }

    /**
     * @en Taxonomy i18n validation during `valaxy dev` / `valaxy build`.
     * Checks whether translated `tag.*` / `category.*` keys are consistently
     * defined across configured languages.
     *
     * @zh `valaxy dev` / `valaxy build` 期间的 taxonomy i18n 校验。
     * 用于检查 `tag.*` / `category.*` 翻译 key 是否在已配置语言中保持一致。
     */
    taxonomyI18n?: {
      /**
       * @en Validation level for taxonomy i18n checks.
       * - `'off'`: disable checks
       * - `'warn'`: print warnings and continue
       * - `'error'`: fail validation after reporting all issues
       *
       * @zh taxonomy i18n 校验级别。
       * - `'off'`:关闭检查
       * - `'warn'`:输出 warning 并继续流程
       * - `'error'`:输出所有问题后以错误结束
       *
       * @default 'warn'
       */
      level?: 'off' | 'warn' | 'error'
    }
  }

  /**
   * @experimental
   * Deploy to gh-pages/remote server
   */
  deploy: {
    /**
     * @zh 部署类型
     * @en deploy type
     */
    type?: 'gh-pages' | 'remote'
  }

  /**
   * internal modules
   */
  modules: {
    rss: {
      /**
       * enable rss
       */
      enable: boolean
      /**
       * @zh 全文输出
       * @en full text output
       * @default false
       */
      fullText: boolean
      /**
       * @zh 从构建后的 HTML 中提取图片路径(用于解析 Vite 打包后的 hash 文件名)
       * @en Extract image paths from built HTML files (to resolve Vite hashed filenames)
       * @default true
       */
      extractImagePathsFromHTML: boolean
    }
  }

  /**
   * Markdown Feature
   */
  features: {
    /**
     * enable katex for global
     *
     * - `true` (default): all pages render KaTeX, unless `frontmatter.katex: false`
     * - `false`: no pages render KaTeX by default, but individual pages can opt-in via `frontmatter.katex: true`
     *
     * @see [Example | Valaxy](https://valaxy.site/examples/katex)
     * @see https://katex.org/
     * @default true
     */
    katex: boolean
    /**
     * @description:en-US Auto-extract the first image from markdown content for Open Graph fallback
     * @description:zh-CN 自动从 Markdown 内容中提取第一张图片,作为 Open Graph 的回退图片
     * @default true
     */
    extractFirstImage: boolean
  }

  /**
   * Enable MathJax3 math rendering (aligned with VitePress `markdown.math`).
   *
   * When enabled, MathJax3 will be used via `markdown-it-mathjax3` to render
   * math formulas as self-contained SVG — no external CSS or fonts required.
   *
   * - `features.katex` and `math` are **mutually exclusive**.
   * - When `math` is enabled, `features.katex` is automatically ignored.
   * - `math` requires installing `markdown-it-mathjax3`: `pnpm add markdown-it-mathjax3`
   *
   * @see https://www.mathjax.org/
   * @default false
   */
  math: boolean
  /**
   * vite.config.ts options
   * @see https://vite.dev/
   */
  vite?: ViteUserConfig
  /**
   * @vitejs/plugin-vue options
   * @see https://github.com/vitejs/vite-plugin-vue/blob/main/packages/plugin-vue/README.md
   */
  vue?: Parameters<typeof Vue>[0] & {
    /**
     * @valaxy
     */
    isCustomElement?: ((tag: string) => boolean)[]
    /**
     * @valaxy
     * @see https://cn.vuejs.org/guide/scaling-up/tooling#note-on-in-browser-template-compilation
     * enable
     *
     * for runtime compile vue, encrypt and decrypt
     * for excerpt_type: html (runtime render)
     *
     * @default true
     *
     * browserTemplateCompilation
     * @description 支持浏览器内的模板编译
     */
    browserTemplateCompilation?: boolean
  }
  /**
   * @see https://github.com/unplugin/unplugin-vue-components
   *
   * exclude @default components/.exclude
   */
  components?: Parameters<typeof Components>[0]
  /**
   * @see https://github.com/loicduong/vite-plugin-vue-layouts-next
   */
  layouts?: Parameters<typeof Layouts>[0]
  /**
   * @see https://router.vuejs.org/file-based-routing/
   */
  router?: Parameters<typeof Router>[0]
  /**
   * @see https://unocss.dev/config/
   */
  unocss?: UnoCSSConfig
  /**
   * rollup-plugin-visualizer
   * @see https://github.com/btd/rollup-plugin-visualizer
   */
  visualizer?: PluginVisualizerOptions
  /**
   * @see https://github.com/yuyinws/vitepress-plugin-group-icons
   */
  groupIcons?: Partial<NonNullable<Parameters<typeof groupIconVitePlugin>[0]>>
  /**
   * unocss presets
   * @see https://unocss.dev/guide/presets
   */
  unocssPresets?: {
    /**
     * @deprecated use wind4 instead
     */
    uno?: Parameters<typeof presetWind4>[0]
    attributify?: Parameters<typeof presetAttributify>[0]
    icons?: Parameters<typeof presetIcons>[0]
    typography?: Parameters<typeof presetTypography>[0]
    wind4?: Parameters<typeof presetWind4>[0]
  }
  fuse?: {
    /**
     * @en_US Extends the metadata fields returned by the search
     * @zh_CN 扩展搜索返回的元数据字段
     * @default []
     * @description:en-US By default, returns the following fields: title, tags, categories, author, excerpt, link
     * @description:zh-CN 默认返回以下字段:title、tags、categories、author、excerpt、link
     */
    extendKeys?: string[]
  }
  /**
   * @experimental
   * Enable Vue Devtools & Valaxy Devtools
   * @see https://devtools-next.vuejs.org/
   */
  devtools?: boolean
  /**
   * @en config for markdown (include markdown-it plugins)
   * @zh markdown 相关配置
   * {@link MarkdownOptions}
   */
  markdown?: MarkdownOptions & Parameters<typeof Markdown>[0]
  /**
   * @en Extend markdown, you can modify the markdown content/excerpt
   * @zh 扩展 markdown
   */
  extendMd?: (ctx: {
    route: EditableTreeNode
    data: Readonly<Record<string, any>>
    content: string
    excerpt?: string
    path: string
  }) => void
  /**
   * @en Addons system
   * @zh 插件系统
   * @see 为什么需要插件? [Why Addon? | Valaxy](https://valaxy.site/addons/why)
   * @see 插件橱窗 [Addons Gallery | Valaxy](https://valaxy.site/addons/gallery)
   * @example
   * ```ts
   * import { defineValaxyConfig } from 'valaxy'
   * import { addonTest } from 'valaxy-addon-test'
   *
   * export default defineValaxyConfig({
   *   addons: [
   *     // we always recommend to use function, so that you can pass options
   *     addonTest(),
   *   ]
   * })
   * ```
   */
  addons?: ValaxyAddons

  /**
   * @en Hooks system, you can customize each stage of the lifecycle.
   * @zh 钩子系统,你可以对生命周期的各个阶段进行定制。
   * @see https://valaxy.site/guide/custom/hooks
   */
  hooks?: Partial<ValaxyHooks>

  /**
   * @experimental
   * CDN externals configuration.
   * Specify modules to load from CDN instead of bundling them.
   * Only takes effect during `valaxy build`, not in dev mode.
   * @see https://github.com/YunYouJun/valaxy/issues/604
   */
  cdn?: {
    /**
     * Modules to load from CDN instead of bundling
     * @default []
     */
    modules?: CdnModule[]
  }

  /**
   * @experimental
   * Content loaders for fetching content from external CMS platforms.
   * Loaded content is written as .md files to `.valaxy/content/pages/`
   * and automatically integrated into the routing and markdown pipeline.
   * @see https://github.com/YunYouJun/valaxy/issues/294
   */
  loaders?: ContentLoader[]
}

export type ValaxyApp = ReturnType<typeof createValaxyNode>

所以,你可以像这样使用:

valaxy.config.ts
ts
import type { ThemeConfig } from 'valaxy-theme-yun'
import { defineValaxyConfig } from 'valaxy'
import { addonComponents } from 'valaxy-addon-components'
import { VitePWA } from 'vite-plugin-pwa'

const safelist = [
  'i-ri-home-line',
]

export default defineValaxyConfig<ThemeConfig>({
  // site config see site.config.ts or write in siteConfig
  siteConfig: {},

  theme: 'yun',
  themeConfig: {
    banner: {
      enable: true,
      title: '云游君的小站',
    },
  },

  vite: {
    // https://vite-pwa-org.netlify.app/
    plugins: [VitePWA()],
  },

  unocss: {
    safelist,
  },

  addons: [
    addonComponents()
  ],
})

Build

build 字段用于配置 valaxy build 的构建行为。

ssgForPagination

启用后,Valaxy 会为分页页面生成独立的静态 HTML(如 /page/1/page/2 等)。默认 false

foucGuard

FOUC(Flash of Unstyled Content)防护配置。通过在 <head> 中内联 body { opacity: 0 !important } 隐藏页面,并通过 JS 监测所有样式表(包括 beasties 异步加载的样式表)加载完成后,移除该隐藏样式标签以显示页面,防止首屏样式闪烁和样式分批渲染的问题。

  • enabled(默认 true):是否启用 FOUC 防护
  • maxDuration(默认 5000):最大等待时间(毫秒),作为 CSS 加载失败时的安全兜底。设为 0 可禁用超时兜底
valaxy.config.ts
ts
import { defineValaxyConfig } from 'valaxy'

export default defineValaxyConfig({
  build: {
    ssgForPagination: false,
    foucGuard: {
      enabled: true,
      maxDuration: 5000,
    },
  },
})

@vitejs/plugin-vue

Valaxy 默认集成了 @vitejs/plugin-vue 插件,你可以通过 vue 配置项进行配置。

valaxy.config.ts
ts
import { defineValaxyConfig } from 'valaxy'

export default defineValaxyConfig({
  vue: {
    template: {
      compilerOptions: {
        isCustomElement: tag => tag.startsWith('my-')
      }
    }
  }
})

Vite

你可以参见 Vite 文档 自定义 Vite 相关配置。

valaxy.config.ts
ts
import { defineValaxyConfig } from 'valaxy'

export default defineValaxyConfig({
  vite: {
    plugins: []
  }
})

SSG Options

Valaxy 使用 vite-ssg 进行静态站点生成。 你可以通过 vite.ssgOptions 自定义 SSG 行为。

Valaxy 默认设置了以下 SSG 选项,用户配置会覆盖这些默认值:

  • script: 'async' — 脚本加载模式
  • formatting: 'minify' — HTML 输出格式(低内存时自动降级为 'none'
  • beastiesOptions.preload: 'media' — 非关键 CSS 预加载策略(详见 beasties
  • concurrency — 并发渲染页面数(根据可用堆内存自动调整)
  • onFinished — 构建完成后自动生成 sitemap(始终执行,用户回调会在其后运行)

完整参数列表请参见 ViteSSGOptions。 warning

SSG 构建最低内存要求:~2.3 GB

vite-ssg 在同一 Node.js 进程中执行 Vite 构建和页面渲染,构建阶段的内存无法完全释放。Valaxy 会根据 V8 堆限制自动调整:堆 ≤ 2.5 GB 时禁用 Critical CSS(beasties)和 HTML minify 以节省内存。

如果遇到 JavaScript heap out of memory 错误,请增大堆限制:

bash
NODE_OPTIONS=--max-old-space-size=4096 pnpm build --ssg

详见 开发 FAQ - JavaScript heap out of memory

valaxy.config.ts
ts
import { defineValaxyConfig } from 'valaxy'

export default defineValaxyConfig({
  vite: {
    ssgOptions: {
      // 输出目录风格: 'flat' | 'nested'
      // flat: /foo → /foo.html
      // nested: /foo → /foo/index.html
      dirStyle: 'nested',

      // 关键 CSS 内联 (beasties) 配置
      // 设为 false 可完全禁用
      beastiesOptions: {
        preload: 'media',
      },

      // 构建完成后的回调(Valaxy 的 sitemap 生成始终会先执行)
      async onFinished() {
        console.log('SSG build finished!')
      },

      // 自定义要生成的路由
      // includedRoutes(paths, routes) {
      //   return paths.filter(p => !p.includes(':'))
      // },

      // 脚本加载模式: 'sync' | 'async' | 'defer' | 'async defer'
      // script: 'async',

      // HTML 格式化: 'none' | 'minify' | 'prettify'
      // formatting: 'minify',

      // SSG 并发数
      // concurrency: 20,
    },
  },
})

Markdown

可自定义 Markdown 相关配置,如代码主题、区块内容、添加 markdown-it 插件、transformer 等。

效果参见: Markdown

valaxy/node/plugins/markdown/types.ts
types.ts
ts
import type {
  HeadersPluginOptions,
} from '@mdit-vue/plugin-headers'

import type { SfcPluginOptions } from '@mdit-vue/plugin-sfc'
import type { TocPluginOptions } from '@mdit-vue/plugin-toc'
import type { KatexOptions } from 'katex'

import type MarkdownIt from 'markdown-it'
import type anchorPlugin from 'markdown-it-anchor'

import type { MarkdownItAsync, Options } from 'markdown-it-async'
import type {
  BuiltinTheme,
  Highlighter,
  LanguageInput,
  ShikiTransformer,
  ThemeRegistration,
} from 'shiki'

// import type { lazyloadOptions } from './plugins/markdown-it/lazyload'

import type { PageData } from '../../../types'
import type { BlockItem, Blocks, ContainerOptions } from './plugins/markdown-it/container'

export type ThemeOptions
  = | ThemeRegistration
    | BuiltinTheme
    | {
      light: ThemeRegistration | BuiltinTheme
      dark: ThemeRegistration | BuiltinTheme
    }

/**
 * Extend Markdown options
 * @zh 扩展 Markdown 配置,包含代码高亮、Markdown-it 和插件配置
 */
export interface MarkdownOptions extends Options {
  /**
   * Setup markdown-it instance before applying plugins
   */
  preConfig?: (md: MarkdownItAsync) => void
  /**
   * markdown-it options
   */
  options?: MarkdownIt['options']
  /**
   * config markdown-it
   */
  config?: (md: MarkdownItAsync) => void
  anchor?: anchorPlugin.AnchorOptions
  attrs?: {
    leftDelimiter?: string
    rightDelimiter?: string
    allowedAttributes?: string[]
    disable?: boolean
  }
  /* ==================== Syntax Highlighting ==================== */

  /**
   * Custom theme for syntax highlighting.
   *
   * You can also pass an object with `light` and `dark` themes to support dual themes.
   *
   * @see You can use an existing theme. https://shiki.style/themes
   * @see Or add your own theme. https://shiki.style/guide/load-theme
   *
   * @example { theme: 'github-dark' }
   * @example light and dark themes
   * ```js
   * { theme: { light: 'github-light', dark: 'github-dark' } }
   * ```
   */
  theme?: ThemeOptions
  /**
   * Languages for syntax highlighting.
   * @see https://shiki.style/languages
   */
  languages?: LanguageInput[]
  /**
   * Custom language aliases.
   *
   * @example { 'my-lang': 'js' }
   * @see https://shiki.style/guide/load-lang#custom-language-aliases
   */
  languageAlias?: Record<string, string>
  /**
   * Show line numbers in code blocks
   * @default false
   */
  lineNumbers?: boolean
  /**
   * Fallback language when the specified language is not available.
   */
  defaultHighlightLang?: string
  /**
   * Transformers applied to code blocks
   * @see https://shiki.style/guide/transformers
   */
  codeTransformers?: ShikiTransformer[]
  /**
   * Setup Shiki instance
   */
  shikiSetup?: (shiki: Highlighter) => void | Promise<void>

  /* ==================== Markdown It Plugins ==================== */
  // mdit-vue plugins
  /**
   * Options for `@mdit-vue/plugin-headers`
   * @see https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-headers
   */
  headers?: HeadersPluginOptions | boolean
  /**
   * Options for `@mdit-vue/plugin-sfc`
   * @see https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-sfc
   */
  sfc?: SfcPluginOptions
  /**
   * Options for `@mdit-vue/plugin-toc`
   * @see https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc
   */
  toc?: TocPluginOptions
  /**
   * Options for `markdown-it-container`
   * @see https://github.com/markdown-it/markdown-it-container
   */
  container?: ContainerOptions
  /**
   * Custom block configurations based on `markdown-it-container`
   */
  blocks?: Record<string, BlockItem> | Blocks

  /**
   * @see [markdown-it-image-figures](https://www.npmjs.com/package/markdown-it-image-figures)
   */
  imageFigures?: {
    lazy: boolean
    removeSrc: boolean
    async: boolean
    classes: string
  }

  /**
   * @see https://katex.org/docs/options.html
   */
  katex?: KatexOptions

  /**
   * Options for `markdown-it-mathjax3`
   * @see https://github.com/tani/markdown-it-mathjax3
   */
  mathjax?: any

  externalLinks?: Record<string, string>
  /* lazyload?: {
    enabled?: boolean
    options: lazyloadOptions
  } */
}

export interface MarkdownCompileResult {
  vueSrc: string
  pageData: PageData
  deadLinks: { url: string, file: string }[]
  includes: string[]
}
valaxy.config.ts
ts
import { defineValaxyConfig } from 'valaxy'

export default defineValaxyConfig({
  markdown: {
    // default material-theme-palenight
    // theme: 'material-theme-palenight',
    theme: {
      // light: 'material-theme-lighter',
      light: 'github-light',
      // dark: 'material-theme-darker',
      dark: 'github-dark',
    },

    blocks: {
      tip: {
        icon: 'i-carbon-thumbs-up',
        text: 'ヒント',
        langs: {
          'zh-CN': '提示',
        },
      },
      warning: {
        icon: 'i-carbon-warning-alt',
        text: '注意',
      },
      danger: {
        icon: 'i-carbon-warning',
        text: '警告',
      },
      info: {
        text: 'información',
      },
    },

    codeTransformers: [
      // We use `[!code` in demo to prevent transformation, here we revert it back.
      {
        postprocess(code) {
          return code.replace(/\[!!code/g, '[!code')
        },
      },
    ],

    config(md) {
      // md.use(xxx)
    }
  },
})

DevTools

设置 devtools: false 以关闭 DevTools。

插件 Addons

参见 使用插件

UnoCSS

参见 UnoCSS

Modules

RSS

Valaxy 内置了 RSS 模块,你可以在 valaxy.config.ts 中通过 modules.rss 配置项进行配置。

  • enable: 是否启用 RSS 模块。默认 true,启用。
  • fullText: 是否输出文章全文。默认 false,只输出摘要。
  • extractImagePathsFromHTML: 是否从构建后的 HTML 中提取图片路径(用于解析 Vite 打包后的 hash 文件名)。默认 true,启用。
valaxy.config.ts
ts
export default defineValaxyConfig({
  modules: {
    rss: {
      enable: true,
      fullText: false,
      // 当设置为 true 时,会从构建后的 HTML 中提取图片的实际路径(包含 hash)
      // When set to true, it will extract actual image paths (with hash) from built HTML
      extractImagePathsFromHTML: true,
    },
  },
})

关于 extractImagePathsFromHTML

当你在 Markdown 中使用相对路径引用图片时(如 ![pic](test.webp)),Vite 会将图片打包并生成带 hash 的文件名(如 /assets/test.zBFFFKJX.webp)。

  • 启用此选项(默认):RSS feed 中的图片 URL 将使用构建后的实际路径,如 https://example.com/assets/test.zBFFFKJX.webp
  • 禁用此选项:RSS feed 中的图片 URL 将基于文章目录构建,如 https://example.com/posts/article-name/test.webp

大多数情况下,你应该保持此选项为 true,以确保 RSS 阅读器能正确加载图片。

LLMS

Valaxy 内置了 LLMS 模块,遵循 llms.txt 标准,在构建时生成 AI 可读的 Markdown 内容。

启用后,构建产物中将包含:

  • /llms.txt — 站点页面索引,按目录分组,包含指向各 .md 文件的链接
  • /llms-full.txt — 所有页面内容的合集(可选)
  • /*.md — 每个页面的原始 Markdown 文件,可通过 URL 直接访问

同时,主题可以利用 useCopyMarkdown() composable 为文章页添加「复制 Markdown」按钮(Yun 主题已内置支持)。

  • enable: 是否启用 LLMS 模块。默认 false,关闭。
  • files: 是否为每个页面生成独立的 .md 文件。默认 true
  • fullText: 是否生成 llms-full.txt(包含所有页面完整内容)。默认 true
  • prompt: 自定义提示词,添加到 llms.txt 的描述部分。默认 ''
  • include: 要包含的 Markdown 文件 glob 模式(相对于 pages/ 目录)。默认 ['posts/**/*.md'] 仅包含 posts 目录。设为 ['**/*.md'] 可包含所有 pages/ 下的 Markdown 文件,也可指定多个目录如 ['posts/**/*.md', 'guide/**/*.md']

llms.txt 中的页面会按顶级目录自动分组(如 ## Posts## Guide 等)。

site.config.ts
ts
export default defineSiteConfig({
  llms: {
    enable: true,
    files: true,
    fullText: true,
    prompt: '',
    // Default: only posts
    // include: ['posts/**/*.md'],

    // Include all markdown files under pages/
    // include: ['**/*.md'],

    // Include specific directories
    // include: ['posts/**/*.md', 'guide/**/*.md'],
  },
})

CDN 外部化

实验性功能

通过 cdn.modules 配置项,你可以指定某些 npm 包在构建时从 CDN 加载,而非打包到最终产物中。 这可以显著减小构建产物体积,并利用 CDN 加速资源加载。

该配置仅在 valaxy build 时生效,开发模式下不受影响。

提示

cdn.modules 中的每个模块需要提供以下字段:

  • name: npm 包名(如 'katex'
  • global: 该库在 window 上暴露的全局变量名(如 'katex'
  • url: CDN 脚本的完整 URL
  • css(可选): CDN 样式表的完整 URL
  • exports(可选): 需要重新导出的命名导出列表(如 ['ref', 'computed']

示例:通过 CDN 加载 KaTeX

KaTeX 默认会被打包进构建产物。如果你希望通过 CDN 加载 KaTeX 以减小打包体积,可以如下配置:

valaxy.config.ts
ts
import { defineValaxyConfig } from 'valaxy'

export default defineValaxyConfig({
  cdn: {
    modules: [
      {
        name: 'katex',
        global: 'katex',
        url: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js',
        css: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css',
      },
    ],
  },
})

你也可以使用其他 CDN 源,只需替换 URL 即可。例如使用 unpkg:

valaxy.config.ts
ts
import { defineValaxyConfig } from 'valaxy'

export default defineValaxyConfig({
  cdn: {
    modules: [
      {
        name: 'katex',
        global: 'katex',
        url: 'https://unpkg.com/[email protected]/dist/katex.min.js',
        css: 'https://unpkg.com/[email protected]/dist/katex.min.css',
      },
    ],
  },
})

贡献者