fix: 语言切换全面修复 —— 品牌层/主题首页/详情区块/404 全量 i18n(zh 矩阵 13/13)
- 站点品牌双语:每站 brandZh(品牌名/标语/hero/导航/页脚/搜索占位)由生成器写入 站点 messages 的 zh 覆盖;SiteChrome 改为 async getTranslations 按语言渲染 - 五套主题首页接线 siteHome/hero 命名空间(新增 wire-theme-i18n.py 一次性接线脚本, 仅处理组件函数体、hook 自动插入、hero 用 th 命名空间) - 详情页 Use cases/Good for/FAQ/reviewCta、用例与合集索引与详情、提交页、 对比页、Alternatives 表头与 FAQ 全部走 next-intl - 404 双语言:locale 内走 next-intl,根级按 Accept-Language - 修复 zh.json 中 84 处 zhXxx 旁挂键归位 + en.json 残留清理(i18n 694 键一致) - 回归:/zh 下 13 页全中文无英文残留、无横向溢出;五站 /zh lang=zh 全部正确
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/not-found.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/not-found";
|
||||
@@ -6,13 +6,25 @@ import { locales, defaultLocale, type Locale } from "@aidir/core/i18n.config";
|
||||
const brandMessages = {
|
||||
en: {
|
||||
seo: { home: {"title":"DevAI.tools — AI Tools for Developers","description":"Code assistants, DevOps automation and testing copilots — the AI tools developers actually upvote, ranked daily.","ogImage":"/og-image.png"} },
|
||||
hero: { title: "DevAI.tools — AI Tools for Developers", description: "Code assistants, DevOps automation and testing copilots — the AI tools developers actually upvote, ranked daily." },
|
||||
hero: { title: "AI tools for developers", description: "Code assistants, DevOps automation, testing copilots and everything else you ship with." },
|
||||
common: { brand: { name: "DevAI.tools", tagline: "AI tools for developers — curated, tested, ranked by the community." } },
|
||||
navigation: {
|
||||
main: { tools: "Tools", blog: "Blog" },
|
||||
site: { items: ["Tools","Workflows","Use Cases","Rankings","Submit"], hrefs: ["/tools","/best","/ai-tools-for","/rankings","/submit"] },
|
||||
},
|
||||
siteFooter: { groups: [{"title":"Directory","links":[{"label":"All Tools","href":"/tools"},{"label":"Rankings","href":"/rankings"},{"label":"Use Cases","href":"/ai-tools-for"}]},{"title":"Build","links":[{"label":"Workflows","href":"/best"},{"label":"Submit a Tool","href":"/submit"},{"label":"Blog","href":"/blog"}]},{"title":"Legal","links":[{"label":"Terms","href":"/terms"},{"label":"Privacy","href":"/privacy"}]}] },
|
||||
siteHeader: { searchPlaceholder: "Search dev tools..." },
|
||||
},
|
||||
zh: {
|
||||
seo: { home: {"title":"DevAI.tools — 开发者 AI 工具","description":"面向开发者的 AI 工具目录:代码助手、运维自动化、测试副驾驶,由社区每日排名。","ogImage":"/og-image.png"} },
|
||||
hero: { title: "DevAI.tools — 开发者 AI 工具", description: "面向开发者的 AI 工具目录:代码助手、运维自动化、测试副驾驶,由社区每日排名。" },
|
||||
common: { brand: { name: "DevAI.tools", tagline: "AI tools for developers — curated, tested, ranked by the community." } },
|
||||
hero: { title: "开发者的 AI 工具", description: "代码助手、运维自动化、测试副驾驶,你上手的一切。" },
|
||||
common: { brand: { name: "DevAI.tools", tagline: "面向开发者的 AI 工具——精选、实测、社区排名。" } },
|
||||
navigation: {
|
||||
main: { tools: "工具", blog: "博客" },
|
||||
site: { items: ["工具","工作流","用例","排行榜","提交"], hrefs: ["/tools","/best","/ai-tools-for","/rankings","/submit"] },
|
||||
},
|
||||
siteFooter: { groups: [{"title":"目录","links":[{"label":"All Tools","href":"/tools"},{"label":"Rankings","href":"/rankings"},{"label":"Use Cases","href":"/ai-tools-for"}]},{"title":"构建","links":[{"label":"Workflows","href":"/best"},{"label":"Submit a Tool","href":"/submit"},{"label":"Blog","href":"/blog"}]},{"title":"法律","links":[{"label":"Terms","href":"/terms"},{"label":"Privacy","href":"/privacy"}]}] },
|
||||
siteHeader: { searchPlaceholder: "搜索开发者工具..." },
|
||||
},
|
||||
} as const;
|
||||
|
||||
|
||||
@@ -2,6 +2,25 @@ import type { SiteConfig } from "@/kit/types";
|
||||
|
||||
// DevAI.tools —— 独立站点的全部品牌/导航/页脚配置
|
||||
export const siteConfig: SiteConfig = {
|
||||
"brandZh": {
|
||||
"name": "DevAI.tools",
|
||||
"tagline": "面向开发者的 AI 工具——精选、实测、社区排名。",
|
||||
"headline": "开发者的 AI 工具",
|
||||
"subheadline": "代码助手、运维自动化、测试副驾驶,你上手的一切。",
|
||||
"nav": [
|
||||
"工具",
|
||||
"工作流",
|
||||
"用例",
|
||||
"排行榜",
|
||||
"提交"
|
||||
],
|
||||
"footer": [
|
||||
"目录",
|
||||
"构建",
|
||||
"法律"
|
||||
],
|
||||
"searchPlaceholder": "搜索开发者工具..."
|
||||
},
|
||||
"accent": "150 60% 30%",
|
||||
"port": 3004,
|
||||
"brand": {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 自动生成:站点首页组件(源自底座 niche 形态,品牌来自 @/site/brand)
|
||||
import { siteConfig } from "@/site/brand";
|
||||
import { Code2, Terminal, Workflow, Layers } from "lucide-react";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { ToolCard } from "@/components/tool-card";
|
||||
import { LocaleLink } from "@/components/locale-link";
|
||||
import { SectionHeader } from "@/kit/section";
|
||||
@@ -44,6 +45,8 @@ const footerGroups = [
|
||||
];
|
||||
|
||||
async function SiteHome({ locale }: { locale: string }) {
|
||||
const t = await getTranslations("siteHome");
|
||||
const th = await getTranslations("hero");
|
||||
const data = await getHomeDataSafe(6);
|
||||
|
||||
return (
|
||||
@@ -65,10 +68,10 @@ async function SiteHome({ locale }: { locale: string }) {
|
||||
</p>
|
||||
<p className="flex items-center gap-2 text-foreground">
|
||||
<Terminal className="h-3.5 w-3.5 text-emerald-600 dark:text-emerald-400" />
|
||||
{siteConfig.brand.headline}
|
||||
{th("title")}
|
||||
</p>
|
||||
<p className="text-xs leading-relaxed text-muted-foreground">
|
||||
{siteConfig.brand.subheadline}
|
||||
{th("description")}
|
||||
</p>
|
||||
<p className="pt-2">
|
||||
<LocaleLink
|
||||
@@ -88,10 +91,10 @@ async function SiteHome({ locale }: { locale: string }) {
|
||||
{data.useCases.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader
|
||||
title="Ship faster with AI"
|
||||
subtitle="Pick your workflow — we ranked the tools for it"
|
||||
title={t("shipTitle")}
|
||||
subtitle={t("shipSubtitle")}
|
||||
viewAllHref="/ai-tools-for"
|
||||
viewAllLabel="All use cases"
|
||||
viewAllLabel={t("useCasesViewAll")}
|
||||
/>
|
||||
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{data.useCases.slice(0, 6).map((uc) => (
|
||||
@@ -119,7 +122,7 @@ async function SiteHome({ locale }: { locale: string }) {
|
||||
{data.trending.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader
|
||||
title="Most upvoted this week"
|
||||
title={t("upvotedTitle")}
|
||||
viewAllHref="/rankings?board=trending"
|
||||
/>
|
||||
<div className="grid gap-3 md:grid-cols-2">
|
||||
@@ -139,10 +142,10 @@ async function SiteHome({ locale }: { locale: string }) {
|
||||
{data.collections.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader
|
||||
title="Workflows & stacks"
|
||||
subtitle="Batteries-included tool stacks for common dev tasks"
|
||||
title={t("workflowsTitle")}
|
||||
subtitle={t("workflowsSubtitle")}
|
||||
viewAllHref="/best"
|
||||
viewAllLabel="All workflows"
|
||||
viewAllLabel={t("workflowsViewAll")}
|
||||
/>
|
||||
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{data.collections.slice(0, 3).map((col) => (
|
||||
@@ -167,7 +170,7 @@ async function SiteHome({ locale }: { locale: string }) {
|
||||
{/* Categories */}
|
||||
{data.categories.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader title="Browse by category" viewAllHref="/tools" />
|
||||
<SectionHeader title={t("categoriesTitle")} viewAllHref="/tools" />
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{data.categories.slice(0, 14).map((cat) => (
|
||||
<LocaleLink
|
||||
|
||||
Reference in New Issue
Block a user