feat: 服务器迁移后的全量演进(依赖升级/安全审计/设计统一/截图/SEO 底座化)
在原仓库历史之上同步本服务器上的全部演进: - 迁移至新服务器并重建 PG 数据库 + ddnc 开发域名绑定 - 全部依赖升级至最新(Next 16.3.5 / React 19.3 / better-auth 1.7.5 / Drizzle 0.45 / TS 7), overrides 消除已知 CVE,安全审计 19 项发现全部修复闭环 - 设计统一:各站宽度 token(--container + site-container)、classic hero 重设计、 头部换行修复、页面过渡与 View Transitions - 截图功能:api.adx9.com 截图服务接入(ow=800 本地化 webp、cf=1、去重/限流/占位图) - SEO 底座化:canonical/hreflang/sitemap/JSON-LD/robots 全部收进 core,新站自动继承 - 加载体验:五站五形态路由骨架(data-theme 切换、shimmer 微光、延迟淡入)+ 过滤 useTransition 交叉淡入淡出(card-enter 错峰入场) - 构建:experimental.cpus 限流防 PG 连接打满;清理死组件链
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/layout.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/layout";
|
||||
export { default, metadata } from "@aidir/core/pages/[locale]/(admin)/layout";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// 自动生成:[locale]/(auth)/layout.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(auth)/layout";
|
||||
export { default, metadata } from "@aidir/core/pages/[locale]/(auth)/layout";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// 自动生成:[locale]/(protected)/layout.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(protected)/layout";
|
||||
export { default, metadata } from "@aidir/core/pages/[locale]/(protected)/layout";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// 自动生成:[locale]/layout.tsx 的薄路由
|
||||
export { default, generateStaticParams } from "@aidir/core/pages/[locale]/layout";
|
||||
export { default, generateMetadata, generateStaticParams } from "@aidir/core/pages/[locale]/layout";
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/screenshots/[slug]/route.ts 的薄路由
|
||||
export { GET } from "@aidir/core/pages/api/screenshots/[slug]/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:robots.ts 的薄路由
|
||||
export { default } from "@aidir/core/pages/robots";
|
||||
@@ -6,49 +6,20 @@ import { ToolCardGrid } from "@/components/tool-card";
|
||||
import { LocaleLink } from "@/components/locale-link";
|
||||
import { getHomeDataSafe } from "@/kit/home-data";
|
||||
|
||||
/** Minimal:极简 AI 搜索引擎(一个框,一个任务) */
|
||||
|
||||
|
||||
const navItems = [
|
||||
{ label: "Search", href: "/tools" },
|
||||
{ label: "Use Cases", href: "/ai-tools-for" },
|
||||
{ label: "Rankings", href: "/rankings" },
|
||||
{ label: "Submit", href: "/submit" },
|
||||
];
|
||||
|
||||
const footerGroups = [
|
||||
{
|
||||
title: "Search",
|
||||
links: [
|
||||
{ label: "All Tools", href: "/tools" },
|
||||
{ label: "Use Cases", href: "/ai-tools-for" },
|
||||
{ label: "Rankings", href: "/rankings" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "About",
|
||||
links: [
|
||||
{ label: "Submit a Tool", href: "/submit" },
|
||||
{ label: "Privacy", href: "/privacy" },
|
||||
{ label: "Terms", href: "/terms" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const popularSearches = [
|
||||
"write a blog post",
|
||||
"generate video",
|
||||
"code assistant",
|
||||
"make a logo",
|
||||
"edit photos",
|
||||
"transcribe meetings",
|
||||
];
|
||||
|
||||
async function SiteHome({ locale }: { locale: string }) {
|
||||
const t = await getTranslations("siteHome");
|
||||
const th = await getTranslations("hero");
|
||||
const data = await getHomeDataSafe(6);
|
||||
|
||||
const popularSearches = [
|
||||
"write a blog post",
|
||||
"generate video",
|
||||
"code assistant",
|
||||
"make a logo",
|
||||
"edit photos",
|
||||
"transcribe meetings",
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col bg-background">
|
||||
{/* 极简搜索首屏 */}
|
||||
@@ -56,8 +27,8 @@ async function SiteHome({ locale }: { locale: string }) {
|
||||
<LocaleLink href="/" className="text-3xl font-bold tracking-tight text-foreground">
|
||||
{siteConfig.brand.name}
|
||||
</LocaleLink>
|
||||
<p className="mt-1 text-xs uppercase tracking-[0.35em] text-muted-foreground">
|
||||
AI tool search
|
||||
<p className="mt-1.5 text-sm text-muted-foreground">
|
||||
{siteConfig.brand.tagline.replace(/\.$/, "")}
|
||||
</p>
|
||||
|
||||
<form action={`/${locale}/tools`} className="mt-10 w-full max-w-xl">
|
||||
@@ -67,19 +38,18 @@ async function SiteHome({ locale }: { locale: string }) {
|
||||
name="search"
|
||||
autoFocus
|
||||
placeholder={t("minimalPlaceholder")}
|
||||
className="h-14 w-full rounded-full border border-border bg-background pl-14 pr-6 text-base text-foreground shadow-lg shadow-black/[0.03] placeholder:text-muted-foreground focus:border-primary/50 focus:outline-none focus:ring-4 focus:ring-primary/10"
|
||||
className="h-14 w-full rounded-xl border border-border bg-background pl-14 pr-6 text-base text-foreground shadow-sm placeholder:text-muted-foreground focus:border-primary/50 focus:outline-none focus:ring-4 focus:ring-primary/10"
|
||||
aria-label="Search AI tools"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="mx-auto mt-10 max-w-md border-t border-border/60 pt-5" />
|
||||
<div className="mt-6 flex flex-wrap items-center justify-center gap-2">
|
||||
<div className="mt-8 flex flex-wrap items-center justify-center gap-x-5 gap-y-2">
|
||||
{popularSearches.map((q) => (
|
||||
<LocaleLink
|
||||
key={q}
|
||||
href={`/tools?search=${encodeURIComponent(q)}`}
|
||||
className="rounded-full px-3 py-1.5 text-xs text-muted-foreground transition-colors hover:bg-secondary hover:text-foreground"
|
||||
className="text-xs text-muted-foreground underline-offset-4 transition-colors hover:text-foreground hover:underline"
|
||||
>
|
||||
{q}
|
||||
</LocaleLink>
|
||||
@@ -89,23 +59,20 @@ async function SiteHome({ locale }: { locale: string }) {
|
||||
|
||||
{/* 搜索之下:Trending */}
|
||||
{data.trending.length > 0 && (
|
||||
<section className="mx-auto w-full max-w-3xl px-4 pb-20 sm:px-6">
|
||||
<h2 className="mb-4 text-center text-xs font-medium uppercase tracking-[0.25em] text-muted-foreground">
|
||||
Trending now
|
||||
</h2>
|
||||
<ToolCardGrid tools={data.trending.slice(0, 4)} locale={locale} />
|
||||
<div className="mt-6 text-center">
|
||||
<section className="site-container px-4 pb-20 sm:px-6">
|
||||
<div className="mb-4 flex items-baseline justify-between border-b border-border pb-3">
|
||||
<h2 className="text-sm font-semibold text-foreground">Trending now</h2>
|
||||
<LocaleLink
|
||||
href="/rankings"
|
||||
className="text-xs font-medium text-muted-foreground hover:text-primary"
|
||||
className="text-xs text-muted-foreground underline-offset-4 hover:text-foreground hover:underline"
|
||||
>
|
||||
{t("seeRankings")}
|
||||
</LocaleLink>
|
||||
</div>
|
||||
<ToolCardGrid tools={data.trending.slice(0, 4)} locale={locale} />
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export { SiteHome };
|
||||
|
||||
Reference in New Issue
Block a user