Extend Config

TIP

Extend Config is an advanced configuration provided by Valaxy, allowing you to customize more low-level and build-related settings.

Below are all the extend configuration options and related types.

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
    /**
     * @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
    }
  }

  /**
   * @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
  }

  /**
   * 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>

So you can use it like this:

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 的构建行为。

The build field configures the behavior of valaxy build.

ssgForPagination

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

When enabled, Valaxy generates static HTML for pagination pages (e.g., /page/1, /page/2). Default is false.

foucGuard

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

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

FOUC (Flash of Unstyled Content) guard. Inlines body { opacity: 0 !important } in <head> and uses JS to monitor all stylesheets (including async ones loaded by beasties) until they finish loading, then removes the hidden style tag to reveal the page with a smooth fade-in.

  • enabled (default true): enable/disable the guard
  • maxDuration (default 5000): max wait time (ms) before force-showing the page. Set to 0 to disable the timeout fallback
valaxy.config.ts
ts
import { defineValaxyConfig } from 'valaxy'

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

@vitejs/plugin-vue

Valaxy integrates @vitejs/plugin-vue by default. You can configure it via the vue option.

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

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

Vite

You can refer to the Vite documentation to customize Vite-related configurations.

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

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

SSG Options

Valaxy uses vite-ssg for Static Site Generation. You can customize SSG behavior via vite.ssgOptions.

Valaxy sets the following SSG defaults. User values override them:

  • script: 'async' — script loading mode
  • formatting: 'minify' — HTML output formatting (auto-degrades to 'none' under low memory)
  • beastiesOptions.preload: 'media' — non-critical CSS preload strategy (see beasties)
  • concurrency — concurrent page rendering count (auto-adjusted based on available heap memory)
  • onFinished — auto-generates sitemap after build (always runs; user callback runs after it)

See ViteSSGOptions for the full parameter list.

WARNING

SSG build minimum memory requirement: ~2.3 GB

vite-ssg runs Vite build and page rendering in the same Node.js process, and memory from the build phase cannot be fully reclaimed. Valaxy auto-adjusts based on V8 heap limits: when heap ≤ 2.5 GB, Critical CSS (beasties) and HTML minify are disabled to save memory.

If you encounter JavaScript heap out of memory errors, increase the heap limit:

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

See Dev FAQ - JavaScript heap out of memory for details.

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

You can customize Markdown-related configurations, such as code themes, block content, adding markdown-it plugins, transformers, etc.

See the effect at: 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

Set devtools: false to disable DevTools.

Addons

See Using Addons.

UnoCSS

See UnoCSS.

Modules

RSS

Valaxy has a built-in RSS module, which can be configured in valaxy.config.ts through the modules.rss configuration item.

  • enable: Whether to enable the RSS module. Default is true, enabled.
  • fullText: Whether to output the full text of the article. Default is false, only the summary is output.
  • extractImagePathsFromHTML: Whether to extract image paths from built HTML files (to resolve Vite hashed filenames). Default is true, enabled.
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,
    },
  },
})

About extractImagePathsFromHTML

When you reference images with relative paths in Markdown (e.g., ![pic](test.webp)), Vite will bundle the image and generate a hashed filename (e.g., /assets/test.zBFFFKJX.webp).

  • When enabled (default): Image URLs in RSS feed will use the actual built paths, like https://example.com/assets/test.zBFFFKJX.webp
  • When disabled: Image URLs in RSS feed will be constructed based on the post directory, like https://example.com/posts/article-name/test.webp

In most cases, you should keep this option as true to ensure RSS readers can load images correctly.

LLMS

Valaxy has a built-in LLMS module, following the llms.txt standard, to generate AI-readable Markdown content during build.

When enabled, the build output will include:

  • /llms.txt — Page index grouped by directory, with links to individual .md files
  • /llms-full.txt — All page content concatenated (optional)
  • /*.md — Raw Markdown files for each page, accessible via URL

Themes can use the useCopyMarkdown() composable to add a "Copy Markdown" button on post pages (built-in support in Yun theme).

  • enable: Whether to enable the LLMS module. Default is false, disabled.
  • files: Whether to generate individual .md files for each page. Default is true.
  • fullText: Whether to generate llms-full.txt (with all page content inlined). Default is true.
  • prompt: Custom prompt text, added to the llms.txt description section. Default is ''.
  • include: Glob patterns for markdown files to include (relative to pages/ directory). Default is ['posts/**/*.md'] to only include posts. Set to ['**/*.md'] to include all markdown files under pages/. You can also specify multiple directories, e.g. ['posts/**/*.md', 'guide/**/*.md'].

Pages in llms.txt are automatically grouped by their top-level directory (e.g. ## Posts, ## Guide, etc.).

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 Externals

Experimental

With the cdn.modules option, you can specify certain npm packages to be loaded from CDN at runtime instead of being bundled. This can significantly reduce bundle size and leverage CDN for faster resource loading.

This option only takes effect during valaxy build, not in dev mode.

TIP

Each module in cdn.modules requires the following fields:

  • name: npm package name (e.g., 'katex')
  • global: global variable name the library exposes on window (e.g., 'katex')
  • url: full CDN URL to the UMD/IIFE script
  • css (optional): full CDN URL to the stylesheet
  • exports (optional): named exports to re-export from the global variable (e.g., ['ref', 'computed'])

Example: Load KaTeX from CDN

KaTeX is bundled into the build output by default. If you want to load it from CDN to reduce bundle size, you can configure it as follows:

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',
      },
    ],
  },
})

You can also use other CDN providers by replacing the URL. For example, using 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',
      },
    ],
  },
})

Contributors