Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/deploy-website.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Deploy website

on:
push:
branches: [main]
paths:
- 'packages/website/**'
- '.github/workflows/deploy-website.yml'
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: github-pages
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- name: Build
run: |
cd packages/website
bun run check
bun run build
- uses: actions/upload-pages-artifact@v3
with:
path: packages/website/dist

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
3 changes: 3 additions & 0 deletions packages/website/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
// GitHub Pages 项目页:https://cavinhuang.github.io/lume/ ;换自定义域名时清掉 base 即可
site: 'https://cavinhuang.github.io',
base: '/lume',
// 中文为默认语言(无前缀),英文挂 /en/ 前缀
i18n: {
defaultLocale: 'zh',
Expand Down
12 changes: 6 additions & 6 deletions packages/website/src/components/Footer.astro
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
---
import { REPO_URL } from '../lib/site';
import { REPO_URL, withBase } from '../lib/site';
import { t, type Lang } from '../i18n/ui';

interface Props {
lang: Lang;
}
const { lang } = Astro.props;

const base = Astro.url.pathname.startsWith('/en') ? '/en' : '';
const langPrefix = lang === 'zh' ? '' : '/en';
const product = [
{ href: `${base}/download`, label: t(lang, 'nav.download') },
{ href: `${base}/docs`, label: t(lang, 'nav.docs') },
{ href: `${base}/changelog`, label: t(lang, 'nav.changelog') },
{ href: withBase(`${langPrefix}/download`), label: t(lang, 'nav.download') },
{ href: withBase(`${langPrefix}/docs`), label: t(lang, 'nav.docs') },
{ href: withBase(`${langPrefix}/changelog`), label: t(lang, 'nav.changelog') },
];
---

<footer class="border-t border-border bg-bg-subtle">
<div class="mx-auto grid max-w-6xl gap-10 px-4 py-12 sm:px-6 md:grid-cols-[1fr_auto_auto]">
<div>
<div class="flex items-center gap-2 font-semibold">
<img src="/logo.png" alt="Lume" class="h-6 w-6 rounded-md" />
<img src={withBase('/logo.png')} alt="Lume" class="h-6 w-6 rounded-md" />
<span class="text-body-lg">Lume</span>
</div>
<p class="mt-3 max-w-sm text-caption leading-relaxed text-fg-muted">
Expand Down
7 changes: 4 additions & 3 deletions packages/website/src/components/LangSwitch.astro
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
---
import { counterpartPath, getLangFromUrl, languages, t } from '../i18n/ui';
import { stripBase, withBase } from '../lib/site';

const lang = getLangFromUrl(Astro.url);
const target = counterpartPath(Astro.url.pathname);
// 链接文案是「你要切过去的语言」
const other = lang === 'zh' ? 'en' : 'zh';

// 链接文案是「你要切过去的语言」
---

<a
href={target}
href={withBase(counterpartPath(stripBase(Astro.url.pathname)))}
hreflang={other}
aria-label={t(lang, 'lang.switch')}
class="rounded-lg px-2 py-1.5 text-ui text-fg-muted transition-colors hover:bg-surface-hover hover:text-fg"
Expand Down
17 changes: 9 additions & 8 deletions packages/website/src/components/Nav.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
import { t, type Lang } from '../i18n/ui';
import { withBase } from '../lib/site';
import ThemeToggle from './ThemeToggle.astro';
import LangSwitch from './LangSwitch.astro';

Expand All @@ -8,19 +9,19 @@ interface Props {
}
const { lang } = Astro.props;

// 英文页都在 /en/ 前缀下,中文页无前缀
const base = Astro.url.pathname.startsWith('/en') ? '/en' : '';
// 英文页都在 /en/ 前缀下,中文页无前缀;再统一补 GitHub Pages 的 base 前缀
const langPrefix = lang === 'zh' ? '' : '/en';
const links = [
{ href: `${base}/#features`, label: t(lang, 'nav.features') },
{ href: `${base}/docs`, label: t(lang, 'nav.docs') },
{ href: `${base}/changelog`, label: t(lang, 'nav.changelog') },
{ href: withBase(`${langPrefix}/#features`), label: t(lang, 'nav.features') },
{ href: withBase(`${langPrefix}/docs`), label: t(lang, 'nav.docs') },
{ href: withBase(`${langPrefix}/changelog`), label: t(lang, 'nav.changelog') },
];
---

<header class="sticky top-0 z-40 border-b border-border bg-bg/85 backdrop-blur">
<nav class="mx-auto flex h-14 max-w-6xl items-center gap-6 px-4 sm:px-6">
<a href={`${base}/`} class="flex items-center gap-2 font-semibold">
<img src="/logo.png" alt="Lume" class="h-6 w-6 rounded-md" />
<a href={withBase(`${langPrefix}/`)} class="flex items-center gap-2 font-semibold">
<img src={withBase('/logo.png')} alt="Lume" class="h-6 w-6 rounded-md" />
<span class="text-body-lg">Lume</span>
</a>
<div class="hidden items-center gap-5 text-ui text-fg-muted sm:flex">
Expand All @@ -45,7 +46,7 @@ const links = [
<LangSwitch />
<ThemeToggle />
<a
href={`${base}/download`}
href={withBase(`${langPrefix}/download`)}
class="ml-1 rounded-lg bg-accent px-3.5 py-1.5 text-ui font-medium text-accent-fg transition-colors hover:bg-accent-strong"
>
{t(lang, 'nav.download')}
Expand Down
19 changes: 15 additions & 4 deletions packages/website/src/components/pages/DocsPage.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { getCollection, render, type CollectionEntry } from 'astro:content';
import Base from '../../layouts/Base.astro';
import { counterpartPath, languages, t, type Lang } from '../../i18n/ui';
import { stripBase, withBase } from '../../lib/site';

interface Props {
lang: Lang;
Expand All @@ -22,7 +23,9 @@ if (entry) {
const found = (await getCollection('docs')).find(
(e) => e.id === `${otherLang}/${slug}`,
);
translated = found ? counterpartPath(Astro.url.pathname) : undefined;
translated = found
? withBase(counterpartPath(stripBase(Astro.url.pathname)))
: undefined;
}

const Content = entry ? (await render(entry)).Content : undefined;
Expand All @@ -38,7 +41,7 @@ const Content = entry ? (await render(entry)).Content : undefined;
{all.map((doc) => (
<li>
<a
href={`${base}/docs/${doc.id.slice(3)}`}
href={withBase(`${base}/docs/${doc.id.slice(3)}`)}
aria-current={doc.id === entry?.id ? 'page' : undefined}
class:list={[
'-ml-px block border-l-2 py-1 pl-3 transition-colors',
Expand All @@ -63,7 +66,12 @@ const Content = entry ? (await render(entry)).Content : undefined;
<Content />
</article>
<p class="mt-10 border-t border-border pt-5 text-ui">
<a href={translated ? translated : `${lang === 'zh' ? '/en' : ''}/docs/`} class="text-accent hover:text-accent-strong">
<a
href={translated
? translated
: withBase(`${lang === 'zh' ? '/en' : ''}/docs/`)}
class="text-accent hover:text-accent-strong"
>
{translated ? languages[lang === 'zh' ? 'en' : 'zh'] : t(lang, 'docs.backToDocs')}
</a>
</p>
Expand All @@ -75,7 +83,10 @@ const Content = entry ? (await render(entry)).Content : undefined;
<ul class="mt-8 space-y-3">
{all.map((doc) => (
<li class="rounded-xl border border-border bg-surface p-4 transition-colors hover:border-border-strong">
<a href={`${base}/docs/${doc.id.slice(3)}`} class="text-body-lg font-medium text-fg hover:text-accent">
<a
href={withBase(`${base}/docs/${doc.id.slice(3)}`)}
class="text-body-lg font-medium text-fg hover:text-accent"
>
{doc.data.title}
</a>
{doc.data.description && (
Expand Down
7 changes: 4 additions & 3 deletions packages/website/src/components/pages/Landing.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import Base from '../../layouts/Base.astro';
import { REPO_URL } from '../../lib/site';
import { t, type Lang, type UiKey } from '../../i18n/ui';
import { withBase } from '../../lib/site';

interface Props {
lang: Lang;
Expand Down Expand Up @@ -42,7 +43,7 @@ const features = [
<p class="mx-auto mt-5 max-w-xl text-body-lg text-fg-muted">{t(lang, 'hero.subtitle')}</p>
<div class="mt-8 flex flex-wrap items-center justify-center gap-3">
<a
href={`${lang === 'zh' ? '' : '/en'}/download`}
href={withBase(`${lang === 'zh' ? '' : '/en'}/download`)}
class="rounded-xl bg-accent px-5 py-2.5 text-body-lg font-medium text-accent-fg shadow-(--shadow-card) transition-colors hover:bg-accent-strong"
>
{t(lang, 'hero.ctaDownload')}
Expand All @@ -61,7 +62,7 @@ const features = [
class="relative mx-auto mt-14 max-w-4xl rounded-2xl border border-border bg-surface p-2 shadow-(--shadow-card)"
>
<img
src="/screenshot.png"
src={withBase('/screenshot.png')}
alt={t(lang, 'hero.screenshotAlt')}
width="1456"
height="816"
Expand Down Expand Up @@ -197,7 +198,7 @@ for await (const event of agent.query('Read package.json and summarize the proje
<h2 class="text-headline font-semibold tracking-tight text-fg">{t(lang, 'cta.title')}</h2>
<p class="mt-3 text-body-lg text-fg-muted">{t(lang, 'cta.desc')}</p>
<a
href={`${lang === 'zh' ? '' : '/en'}/download`}
href={withBase(`${lang === 'zh' ? '' : '/en'}/download`)}
class="mt-7 inline-block rounded-xl bg-accent px-6 py-3 text-body-lg font-medium text-accent-fg shadow-(--shadow-card) transition-colors hover:bg-accent-strong"
>
{t(lang, 'cta.button')}
Expand Down
2 changes: 1 addition & 1 deletion packages/website/src/content/docs/en/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Anything behind an OpenAI-compatible API — OpenAI, Anthropic, Gemini, DeepSeek

## Which platforms?

Installers are available for Windows and macOS; Linux builds are on the way. See the [download page](/en/download/).
Installers are available for Windows and macOS; Linux builds are on the way. See the [download page](../../download/).

## Is it free?

Expand Down
2 changes: 1 addition & 1 deletion packages/website/src/content/docs/en/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ order: 1

## Install

Grab the latest build from the [download page](/en/download/):
Grab the latest build from the [download page](../../download/):

- **Windows**: download the `.exe` installer and follow the wizard.
- **macOS**: pick the Apple Silicon or Intel `.dmg`, open it and drag Lume into Applications.
Expand Down
2 changes: 1 addition & 1 deletion packages/website/src/content/docs/zh/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ order: 5

## 支持哪些平台?

Windows 与 macOS 提供安装包,Linux 安装包在制作中。详见[下载页](/download/)。
Windows 与 macOS 提供安装包,Linux 安装包在制作中。详见[下载页](../../download/)。

## 收费吗?

Expand Down
2 changes: 1 addition & 1 deletion packages/website/src/content/docs/zh/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ order: 1

## 安装

前往[下载页](/download/)获取最新安装包:
前往[下载页](../../download/)获取最新安装包:

- **Windows**:下载 `.exe` 安装程序,按向导完成安装。
- **macOS**:根据芯片选择 Apple Silicon 或 Intel 版 `.dmg`,打开后将 Lume 拖入「应用程序」。
Expand Down
5 changes: 3 additions & 2 deletions packages/website/src/layouts/Base.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../styles/global.css';
import Nav from '../components/Nav.astro';
import Footer from '../components/Footer.astro';
import { getLangFromUrl } from '../i18n/ui';
import { withBase } from '../lib/site';

interface Props {
title: string;
Expand All @@ -20,11 +21,11 @@ const lang = getLangFromUrl(Astro.url);
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{title}</title>
<meta name="description" content={description} />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/svg+xml" href={withBase('/favicon.svg')} />
<meta name="generator" content={Astro.generator} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content="/screenshot.png" />
<meta property="og:image" content={withBase('/screenshot.png')} />
<!-- 首屏前定主题,避免闪白/闪黑 -->
<script is:inline>
(() => {
Expand Down
17 changes: 17 additions & 0 deletions packages/website/src/lib/site.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
// 站点常量:发新版本时同步更新 VERSION 与对应资产文件名

/** GitHub Pages 项目页子路径前缀(base: '/lume');根路径部署时 BASE_URL 为 '/' */
const RAW_BASE = import.meta.env.BASE_URL.replace(/\/+$/, '');
const BASE_PREFIX = RAW_BASE === '' ? '/' : `${RAW_BASE}/`;

/** 给站内根相对路径补 base 前缀;外链不要经过这里 */
export const withBase = (path: string): string => `${RAW_BASE}${path}`;

/** 去掉当前 URL 上的 base 前缀,得到语言层路径('/lume/en/docs/' → '/en/docs/') */
export function stripBase(pathname: string): string {
if (RAW_BASE === '') return pathname;
if (pathname === RAW_BASE) return '/'; // 首页构建时 pathname 无尾斜杠
return pathname.startsWith(BASE_PREFIX)
? pathname.slice(BASE_PREFIX.length - 1)
: pathname;
}

export const REPO = 'CavinHuang/lume';
export const REPO_URL = `https://github.com/${REPO}`;
export const ISSUES_URL = `${REPO_URL}/issues`;
Expand Down
Loading