项目文件夹

文件
wehub-resource-sync d68f003000
CI / Change detection (push) Has been cancelled
CI / Version drift (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Workflow RLM cache (push) Has been cancelled
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / npm wrapper smoke (push) Has been cancelled
CI / Mobile runtime smoke (push) Has been cancelled
CI / Workflow lint (push) Has been cancelled
CI / Documentation (push) Has been cancelled
Web Frontend / Lint & Type Check (push) Failing after 1s
Auto-close harvested PRs / close (push) Failing after 1s
cargo-deny / cargo-deny (bans licenses sources) (push) Failing after 1s
Security audit / cargo-audit (push) Failing after 1s
Sync to CNB / sync (push) Failing after 1s
cargo-deny / cargo-deny (advisories) (push) Failing after 3s
Web Frontend / Deploy to Cloudflare (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:08:23 +08:00

91 行
2.6 KiB
TypeScript

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
import type { Metadata } from "next";
/** Canonical origin for the production site (no trailing slash). */
export const SITE_URL = "https://codewhale.net";
export const SITE_NAME = "CodeWhale";
/** The one-line product identity, used as the default OG image alt text. */
export const IDENTITY_PHRASE =
"The calm, provider-honest terminal coding agent for any model — open models first.";
/** Shared OG card rendered by app/opengraph-image.tsx (1200×630 PNG). */
const OG_IMAGE = {
url: `${SITE_URL}/opengraph-image`,
width: 1200,
height: 630,
alt: `${SITE_NAME}${IDENTITY_PHRASE}`,
};
/**
* buildPageMetadata — per-page SEO metadata for the bilingual (en/zh) site.
*
* Produces a canonical URL for the rendered locale, hreflang alternates for
* both locales (plus `x-default` pointing at the English page), and matching
* Open Graph / Twitter card fields wired to the shared OG image.
*
* @param path Route path WITHOUT the locale prefix, with a leading
* slash: "/" for the homepage, "/install", "/docs", …
* @param locale Locale of the page being rendered: "en" | "zh".
* @param title Localized page <title> (full string; no template is applied).
* @param description Localized meta description, same locale as `title`.
*
* Usage in a page or layout:
* ```ts
* export async function generateMetadata({ params }) {
* const { locale } = await params;
* const isZh = locale === "zh";
* return buildPageMetadata({
* path: "/install",
* locale,
* title: isZh ? "安装 · CodeWhale" : "Install · CodeWhale",
* description: isZh ? "…" : "…",
* });
* }
* ```
*/
export function buildPageMetadata({
path,
locale,
title,
description,
}: {
path: string;
locale: string;
title: string;
description: string;
}): Metadata {
// "/" → "" so the homepage canonical is /en, not /en/.
const suffix = path === "/" ? "" : path.replace(/\/+$/, "");
const canonical = `${SITE_URL}/${locale}${suffix}`;
return {
metadataBase: new URL(SITE_URL),
title,
description,
alternates: {
canonical,
languages: {
en: `${SITE_URL}/en${suffix}`,
zh: `${SITE_URL}/zh${suffix}`,
"x-default": `${SITE_URL}/en${suffix}`,
},
},
openGraph: {
title,
description,
url: canonical,
siteName: SITE_NAME,
type: "website",
locale: locale === "zh" ? "zh_CN" : "en_US",
images: [OG_IMAGE],
},
twitter: {
card: "summary_large_image",
title,
description,
images: [OG_IMAGE.url],
},
};
}