博客

Astro Starlight + LunariaJS:打造完美的多语言文档站点

手把手教你将 LunariaJS 集成到 Astro Starlight 文档站点,从安装配置到仪表板嵌入,打造一个支持多语言、可视化追踪翻译进度的专业文档站点。

LibDoc Team 2026年3月6日 LunariaJS 专栏 64 分钟阅读
#LunariaJS #Astro #Starlight #文档站点 #多语言

Astro Starlight + LunariaJS:打造完美的多语言文档站点

在前面的文章中,我们学习了 LunariaJS 的核心功能和 Git 工作流集成。今天,让我们探讨 LunariaJS 与 Astro Starlight 的完美结合,手把手教你构建一个专业的多语言文档站点。

💡 官方文档LunariaJS 中文文档 - Starlight 集成

Starlight 简介

什么是 Astro Starlight?

Astro Starlight 是基于 Astro 框架构建的现代化文档主题,它提供了:

特性说明
🚀 极致性能Astro 的部分水合技术,页面加载飞快
🎨 美观设计开箱即用的专业文档界面
📱 响应式完美适配桌面和移动设备
🔍 内置搜索Pagefind 全文搜索
🌙 暗色模式自动检测系统偏好
🌐 国际化原生多语言支持

为什么需要 LunariaJS?

虽然 Starlight 提供了国际化(i18n)支持,但它不包含翻译管理功能

需求Starlight+ LunariaJS
多语言路由
语言切换器
翻译 UI 组件
翻译状态追踪
可视化仪表板
Git 工作流集成

LunariaJS 填补了 Starlight 在翻译管理方面的空白

@lunariajs/starlight 安装

前置条件

确保你的项目满足以下条件:

  • Astro 4.0+ 或 5.0+
  • Starlight 已安装
  • 项目使用 Git 进行版本控制

安装步骤

1. 安装依赖

# 使用 npm
npm install @lunariajs/starlight

# 使用 yarn
yarn add @lunariajs/starlight

# 使用 pnpm
pnpm add @lunariajs/starlight

2. 检查版本兼容性

# 查看已安装版本
npm list @astrojs/starlight @lunariajs/starlight

确保版本兼容:

@astrojs/starlight@lunariajs/starlight
0.25.x0.4.x
0.26.x+0.5.x+

Starlight 配置集成

基础配置

astro.config.mjs 中添加 LunariaJS 集成:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import lunaria from '@lunariajs/starlight';

export default defineConfig({
  integrations: [
    starlight({
      title: 'My Documentation',
      defaultLocale: 'en',
      locales: {
        en: { label: 'English' },
        'zh-cn': { label: '简体中文' },
        ja: { label: '日本語' },
        ko: { label: '한국어' },
      },
      sidebar: [
        { label: 'Guide', link: '/guide/' },
        { label: 'Reference', link: '/reference/' },
      ],
    }),
    lunaria({
      // LunariaJS 配置
      sourceLanguage: 'en',
      languages: ['en', 'zh-cn', 'ja', 'ko'],
    }),
  ],
});

i18n 配置与 LunariaJS 同步

确保 Starlight 的 i18n 配置与 LunariaJS 一致:

// astro.config.mjs
const languages = ['en', 'zh-cn', 'ja', 'ko'];
const sourceLanguage = 'en';

export default defineConfig({
  integrations: [
    starlight({
      title: 'My Documentation',
      defaultLocale: sourceLanguage,
      locales: Object.fromEntries(
        languages.map(lang => [
          lang,
          { label: getLanguageLabel(lang) }
        ])
      ),
    }),
    lunaria({
      sourceLanguage,
      languages,
    }),
  ],
});

function getLanguageLabel(lang) {
  const labels = {
    en: 'English',
    'zh-cn': '简体中文',
    ja: '日本語',
    ko: '한국어',
  };
  return labels[lang] || lang;
}

路由结构设计

Starlight + LunariaJS 的推荐目录结构:

src/
└── content/
    └── docs/
        ├── en/                    # 英语(源语言)
        │   ├── index.md
        │   ├── guide.md
        │   └── reference.md
        ├── zh-cn/                 # 中文翻译
        │   ├── index.md
        │   ├── guide.md
        │   └── reference.md
        ├── ja/                    # 日文翻译
        │   └── ...
        └── ko/                    # 韩文翻译
            └── ...

完整配置示例

// astro.config.mjs
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import lunaria from '@lunariajs/starlight';

// 语言配置
const config = {
  sourceLanguage: 'en',
  languages: ['en', 'zh-cn', 'ja', 'ko'],
  languageLabels: {
    en: 'English',
    'zh-cn': '简体中文',
    ja: '日本語',
    ko: '한국어',
  },
};

export default defineConfig({
  site: 'https://docs.example.com',
  integrations: [
    starlight({
      title: 'My Project',
      defaultLocale: config.sourceLanguage,
      locales: Object.fromEntries(
        config.languages.map(lang => [
          lang,
          { label: config.languageLabels[lang] }
        ])
      ),
      sidebar: {
        en: [
          { label: 'Home', link: '/' },
          { label: 'Guide', link: '/guide/' },
          { label: 'API Reference', link: '/reference/' },
        ],
        'zh-cn': [
          { label: '首页', link: '/' },
          { label: '指南', link: '/guide/' },
          { label: 'API 参考', link: '/reference/' },
        ],
        // 其他语言...
      },
      social: {
        github: 'https://github.com/your-org/your-repo',
      },
    }),
    lunaria({
      sourceLanguage: config.sourceLanguage,
      languages: config.languages,
      files: [
        {
          sourcePath: 'src/content/docs/{lang}/{slug}.md',
          localizationPath: 'src/content/docs/{lang}/{slug}.md',
        },
      ],
      dashboard: {
        outputDir: 'public/i18n-status',
        title: 'My Project - Translation Status',
      },
    }),
  ],
});

仪表板嵌入

方式一:作为独立路径

将 LunariaJS 仪表板放在 /i18n-status/ 路径下:

// astro.config.mjs
lunaria({
  dashboard: {
    outputDir: 'public/i18n-status',
  },
})

构建后,访问 /i18n-status/ 即可查看仪表板。

方式二:添加到导航菜单

在 Starlight 导航中添加仪表板链接:

// astro.config.mjs
starlight({
  title: 'My Documentation',
  sidebar: [
    { label: 'Guide', link: '/guide/' },
    { label: 'Reference', link: '/reference/' },
    {
      label: 'Translation Status',
      link: '/i18n-status/',
      badge: 'New',
    },
  ],
})

方式三:自定义导航组件

创建自定义导航组件显示翻译进度:

---
// src/components/I18nStatus.astro
---
<a href="/i18n-status/" class="i18n-status-link">
  <span class="icon">🌐</span>
  <span>Translation Status</span>
</a>

<style>
  .i18n-status-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    background: var(--sl-color-bg);
    border-radius: 0.5rem;
    text-decoration: none;
    color: var(--sl-color-text);
    transition: background 0.2s;
  }

  .i18n-status-link:hover {
    background: var(--sl-color-bg-hover);
  }
</style>

样式定制

覆盖 LunariaJS 仪表板的默认样式:

/* src/styles/lunaria-custom.css */
:root {
  /* 使用 Starlight 的颜色变量 */
  --lunaria-color-primary: var(--sl-color-accent);
  --lunaria-color-success: var(--sl-color-green);
  --lunaria-color-warning: var(--sl-color-orange);
  --lunaria-color-danger: var(--sl-color-red);

  /* 背景色 */
  --lunaria-bg-primary: var(--sl-color-bg);
  --lunaria-bg-secondary: var(--sl-color-bg-sidebar);
}

然后在配置中引用:

// astro.config.mjs
lunaria({
  dashboard: {
    customCss: './src/styles/lunaria-custom.css',
  },
})

实战:构建三语言文档站点

让我们通过一个完整的实战案例,构建一个支持中文、日文、韩文的三语言文档站点。

步骤 1:创建 Starlight 项目

# 使用模板创建项目
npm create astro@latest -- --template starlight

# 进入项目目录
cd my-docs

# 安装依赖
npm install

步骤 2:安装 LunariaJS

npm install @lunariajs/starlight

步骤 3:配置多语言

编辑 astro.config.mjs

import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import lunaria from '@lunariajs/starlight';

export default defineConfig({
  integrations: [
    starlight({
      title: 'My Project Docs',
      defaultLocale: 'en',
      locales: {
        en: { label: 'English', lang: 'en' },
        'zh-cn': { label: '简体中文', lang: 'zh-CN' },
        ja: { label: '日本語', lang: 'ja' },
        ko: { label: '한국어', lang: 'ko' },
      },
      sidebar: {
        en: [
          { label: 'Home', link: '/' },
          { label: 'Getting Started', items: [
            { label: 'Introduction', link: '/getting-started/' },
            { label: 'Installation', link: '/installation/' },
          ]},
        ],
        'zh-cn': [
          { label: '首页', link: '/' },
          { label: '快速开始', items: [
            { label: '简介', link: '/getting-started/' },
            { label: '安装', link: '/installation/' },
          ]},
        ],
        ja: [
          { label: 'ホーム', link: '/' },
          { label: 'はじめに', items: [
            { label: '概要', link: '/getting-started/' },
            { label: 'インストール', link: '/installation/' },
          ]},
        ],
        ko: [
          { label: '홈', link: '/' },
          { label: '시작하기', items: [
            { label: '소개', link: '/getting-started/' },
            { label: '설치', link: '/installation/' },
          ]},
        ],
      },
    }),
    lunaria({
      sourceLanguage: 'en',
      languages: ['en', 'zh-cn', 'ja', 'ko'],
    }),
  ],
});

步骤 4:创建内容文件

src/content/docs/
├── en/
│   ├── index.md
│   ├── getting-started.md
│   └── installation.md
├── zh-cn/
│   ├── index.md
│   └── getting-started.md      # 假设安装文档还未翻译
├── ja/
│   ├── index.md
│   └── getting-started.md
└── ko/
    └── index.md                 # 其他文档还未翻译

步骤 5:添加翻译元数据

每个 Markdown 文件都应包含 frontmatter:

---
title: Getting Started
description: Learn how to get started with our project.
---

# Getting Started

Welcome to our project! This guide will help you...

步骤 6:构建和预览

# 构建站点和仪表板
npm run build

# 预览
npm run preview

访问:

  • 文档站点:http://localhost:4321/
  • 翻译仪表板:http://localhost:4321/i18n-status/

步骤 7:验证翻译状态

打开仪表板,你应该看到类似:

Translation Status
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Language         Progress    Status
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🇺🇸 English       100%        Source
🇨🇳 简体中文       67%         2/3 done, 1 missing
🇯🇵 日本語         67%         2/3 done, 1 missing
🇰🇷 한국어          33%         1/3 done, 2 missing
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

常见问题与解决方案

Q1:仪表板 404 错误

问题:访问 /i18n-status/ 显示 404。

解决方案

# 确保 LunariaJS 配置的输出目录是 public/ 目录下
lunaria({
  dashboard: {
    outputDir: 'public/i18n-status',  // 必须在 public/ 目录下
  },
})

# 确保先运行 build
npm run build

Q2:语言代码不一致

问题:Starlight 使用 zh-CN,LunariaJS 使用 zh-cn

解决方案

starlight({
  locales: {
    'zh-cn': { label: '简体中文', lang: 'zh-CN' },  // 注意区分
  },
})

Q3:仪表板样式冲突

问题:仪表板样式与文档站点不一致。

解决方案:使用自定义 CSS 统一样式:

/* 在 lunaria 仪表板中使用 Starlight 变量 */
:root {
  --lunaria-color-primary: var(--sl-color-accent);
  --lunaria-bg-primary: var(--sl-color-bg);
}

Q4:构建时内存不足

问题:大型文档站点构建时内存不足。

解决方案

# 增加 Node.js 内存限制
NODE_OPTIONS="--max-old-space-size=4096" npm run build

Q5:路由冲突

问题:仪表板路径与文档路径冲突。

解决方案:选择不会与文档冲突的路径:

// 避免使用 /docs/、/guide/ 等常见文档路径
lunaria({
  dashboard: {
    outputDir: 'public/localization-status',  // 使用独特的路径
  },
})

最佳实践

1. 统一语言配置

创建共享配置文件:

// src/i18n-config.js
export const languages = ['en', 'zh-cn', 'ja', 'ko'];
export const sourceLanguage = 'en';
export const languageLabels = {
  en: 'English',
  'zh-cn': '简体中文',
  ja: '日本語',
  ko: '한국어',
};

在多处引用:

// astro.config.mjs
import { languages, sourceLanguage, languageLabels } from './src/i18n-config.js';

2. 自动化翻译检查

在 package.json 中添加脚本:

{
  "scripts": {
    "dev": "astro dev",
    "build": "astro build",
    "preview": "astro preview",
    "i18n:check": "lunaria build",
    "i18n:preview": "lunaria preview"
  }
}

3. 添加翻译指南

在文档中添加翻译贡献指南:

# Contributing Translations

We welcome translation contributions! Here's how to help:

1. Check the [Translation Status Dashboard](/i18n-status/)
2. Find a file marked as "missing" or "outdated"
3. Fork the repository and create a translation
4. Submit a pull request

Thank you for helping make our documentation accessible to everyone!

4. 设置 CI/CD 检查

# .github/workflows/i18n-check.yml
name: i18n Status

on: [pull_request]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci
      - run: npm run i18n:check

      - name: Upload Dashboard
        uses: actions/upload-artifact@v4
        with:
          name: i18n-dashboard
          path: public/i18n-status/

总结

LunariaJS 与 Astro Starlight 的集成提供了完整的多语言文档解决方案:

功能Starlight+ LunariaJS
多语言路由
语言切换
翻译 UI
翻译状态追踪
可视化仪表板
Git 工作流

关键要点

  • 使用 @lunariajs/starlight 包实现无缝集成
  • 确保语言代码在 Starlight 和 LunariaJS 间一致
  • 将仪表板嵌入导航菜单方便访问
  • 统一配置文件避免重复维护

下一步

下一篇文章,我们将探讨 LunariaJS 的 CI/CD 集成,学习如何:

  • 配置 GitHub Actions 自动化构建
  • 设计翻译状态检查流水线
  • 设置通知和报告机制
  • 实现持续本地化工作流

敬请期待!


💡 推荐阅读