diff --git a/astro.config.mjs b/astro.config.mjs index 3dc6242..9ad440a 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -32,6 +32,12 @@ function rehypeScrollingTables() { // https://astro.build/config export default defineConfig({ site: 'https://thinkwat.ch', + // Pages that moved. GitHub Pages cannot answer with a redirect, so each old + // address is built as a page that sends the browser on (and is not indexed). + redirects: { + '/license': '/pricing', + '/zh-CN/license': '/zh-CN/pricing', + }, i18n: { defaultLocale: 'en', locales: ['en', 'zh-CN'], @@ -58,7 +64,7 @@ export default defineConfig({ // Product landing pages: ThinkWatch, ThinkWatch Lite, ThinkWatch Core. const productPaths = ['/thinkwatch', '/lite', '/core']; const isProduct = productPaths.some((p) => pathname === p || pathname === `/zh-CN${p}`); - const isLicense = pathname === '/license' || pathname === '/zh-CN/license'; + const isPricing = pathname === '/pricing' || pathname === '/zh-CN/pricing'; if (isHome) { item.priority = 1.0; @@ -76,7 +82,7 @@ export default defineConfig({ } else if (isChangelog) { item.priority = 0.7; item.changefreq = ChangeFreqEnum.WEEKLY; - } else if (isLicense) { + } else if (isPricing) { item.priority = 0.6; item.changefreq = ChangeFreqEnum.MONTHLY; } else { diff --git a/src/components/SiteFooter.astro b/src/components/SiteFooter.astro index 6cc29d2..ca4386d 100644 --- a/src/components/SiteFooter.astro +++ b/src/components/SiteFooter.astro @@ -35,7 +35,7 @@ const year = new Date().getFullYear();
diff --git a/src/components/SiteHeader.astro b/src/components/SiteHeader.astro index 07ca3b3..2225969 100644 --- a/src/components/SiteHeader.astro +++ b/src/components/SiteHeader.astro @@ -26,7 +26,7 @@ const links = [ { href: localePath(lang, "/core"), label: s.nav.core, match: "/core" }, { href: localePath(lang, "/docs"), label: s.nav.docs, match: "/docs" }, { href: localePath(lang, "/changelog"), label: s.nav.changelog, match: "/changelog" }, - { href: localePath(lang, "/license"), label: s.nav.license, match: "/license" }, + { href: localePath(lang, "/pricing"), label: s.nav.pricing, match: "/pricing" }, ].map((l) => ({ ...l, active: currentPath === l.match || currentPath.startsWith(l.match + "/") })); const cleanPath = Astro.url.pathname.replace(/^\/zh-CN/, "") || "/"; diff --git a/src/components/home/CompareEditions.astro b/src/components/home/CompareEditions.astro index 3d7b147..443ea87 100644 --- a/src/components/home/CompareEditions.astro +++ b/src/components/home/CompareEditions.astro @@ -47,6 +47,6 @@ const rows = ["runsAs", "builtFor", "status", "license"] as const; ))} - {c.link} + {c.link} diff --git a/src/components/pages/LicensePage.astro b/src/components/pages/PricingPage.astro similarity index 96% rename from src/components/pages/LicensePage.astro rename to src/components/pages/PricingPage.astro index a932018..2b242fd 100644 --- a/src/components/pages/LicensePage.astro +++ b/src/components/pages/PricingPage.astro @@ -1,19 +1,20 @@ --- -// Shared /license page. Copy lives in src/i18n/pages/license.ts. +// Shared /pricing page: the licenses of the three products and the commercial +// terms of ThinkWatch Enterprise. Copy lives in src/i18n/pages/pricing.ts. import Base from "~/layouts/Base.astro"; import SiteHeader from "~/components/SiteHeader.astro"; import SiteFooter from "~/components/SiteFooter.astro"; import NeonMotion from "~/components/NeonMotion.astro"; import { getLang } from "~/i18n"; -import { licenseCopy } from "~/i18n/pages/license"; +import { pricingCopy } from "~/i18n/pages/pricing"; import { breadcrumbs, webPage } from "~/lib/structured-data"; const lang = getLang(Astro); -const c = licenseCopy[lang]; +const c = pricingCopy[lang]; const jsonLd = [ - webPage(lang, "/license", c.meta.title, c.meta.description), - breadcrumbs(lang, "/license", c.meta.breadcrumbHome, c.meta.breadcrumbPage), + webPage(lang, "/pricing", c.meta.title, c.meta.description), + breadcrumbs(lang, "/pricing", c.meta.breadcrumbHome, c.meta.breadcrumbPage), ]; --- diff --git a/src/components/pages/ThinkWatchPage.astro b/src/components/pages/ThinkWatchPage.astro index 4d3e3d8..45566a6 100644 --- a/src/components/pages/ThinkWatchPage.astro +++ b/src/components/pages/ThinkWatchPage.astro @@ -92,7 +92,7 @@ const delay = (i: number) => `animation-delay: ${i * 90}ms;`; {c.licenseTeaser.link} diff --git a/src/content/docs/en/overview.md b/src/content/docs/en/overview.md index cfda620..f14f4d5 100644 --- a/src/content/docs/en/overview.md +++ b/src/content/docs/en/overview.md @@ -22,4 +22,4 @@ ThinkWatch Enterprise is a self-hosted AI API and MCP gateway for organizations. 3. [Configuration](/docs/configuration): environment variables and system settings. 4. [Security](/docs/security): authentication, encryption, RBAC and the hardening checklist. -ThinkWatch Enterprise is source-available under the Business Source License 1.1: free for non-production use, and free in production up to monthly thresholds. See [License](/license). +ThinkWatch Enterprise is source-available under the Business Source License 1.1: free for non-production use, and free in production up to monthly thresholds. See [Pricing](/pricing). diff --git a/src/content/docs/zh-CN/overview.md b/src/content/docs/zh-CN/overview.md index e8fd327..9e2a209 100644 --- a/src/content/docs/zh-CN/overview.md +++ b/src/content/docs/zh-CN/overview.md @@ -22,4 +22,4 @@ ThinkWatch 企业版是面向组织自托管的 AI API 与 MCP 网关。组织 3. [配置说明](/zh-CN/docs/configuration):环境变量与系统设置。 4. [安全模型](/zh-CN/docs/security):认证、加密、RBAC 与加固清单。 -ThinkWatch 企业版在 Business Source License 1.1 下源码开放:非生产环境免费,生产环境在月度阈值以内免费,详见[许可证](/zh-CN/license)。 +ThinkWatch 企业版在 Business Source License 1.1 下源码开放:非生产环境免费,生产环境在月度阈值以内免费,详见[定价](/zh-CN/pricing)。 diff --git a/src/i18n/index.ts b/src/i18n/index.ts index 4917017..5d1333c 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -17,12 +17,11 @@ const dict = { thinkwatch: "Enterprise", lite: "Lite", core: "Core", - license: "Pricing", + pricing: "Pricing", how: "How it works", features: "Features", mcp: "MCP", console: "Console", - pricing: "Pricing", quickstart: "Quick start", docs: "Docs", changelog: "Changelog", @@ -248,12 +247,11 @@ const dict = { thinkwatch: "企业版", lite: "Lite", core: "Core", - license: "定价", + pricing: "定价", how: "工作原理", features: "功能特性", mcp: "MCP", console: "控制台", - pricing: "定价", quickstart: "快速开始", docs: "文档", changelog: "更新日志", diff --git a/src/i18n/pages/license.ts b/src/i18n/pages/pricing.ts similarity index 99% rename from src/i18n/pages/license.ts rename to src/i18n/pages/pricing.ts index 188e33c..e8ac5ad 100644 --- a/src/i18n/pages/license.ts +++ b/src/i18n/pages/pricing.ts @@ -1,4 +1,4 @@ -// Copy for the /license page. +// Copy for the /pricing page. // Every rule, tier, price and definition here mirrors LICENSING.md in the // ThinkWatch repository. If that file changes, update this one to match, // and keep the numbers identical across both languages. @@ -19,7 +19,7 @@ const tierNumbers = [ { name: "Enterprise", tokens: "1,000,000,001 – 10,000,000,000", calls: "1,000,001 – 10,000,000", free: false }, ] as const; -export const licenseCopy = { +export const pricingCopy = { en: { meta: { title: "Pricing · ThinkWatch", @@ -252,4 +252,4 @@ export const licenseCopy = { }, } as const; -export default licenseCopy; +export default pricingCopy; diff --git a/src/lib/lastmod.ts b/src/lib/lastmod.ts index 0c82a83..c0a41a1 100644 --- a/src/lib/lastmod.ts +++ b/src/lib/lastmod.ts @@ -112,8 +112,8 @@ export function pageSources(pathname: string): string[] { // The sections below the hero still read their copy from the shared dictionary. "src/i18n/index.ts", ]; - case "/license": - return ["src/components/pages/LicensePage.astro", "src/i18n/pages/license.ts"]; + case "/pricing": + return ["src/components/pages/PricingPage.astro", "src/i18n/pages/pricing.ts"]; case "/changelog": return ["src/components/pages/ChangelogPage.astro", "src/i18n/pages/changelog.ts", "src/content/changelog"]; case "/docs": diff --git a/src/pages/license.astro b/src/pages/license.astro deleted file mode 100644 index d47245b..0000000 --- a/src/pages/license.astro +++ /dev/null @@ -1,5 +0,0 @@ ---- -import LicensePage from "~/components/pages/LicensePage.astro"; ---- - -