tech官小西

Next.js SEO 审计实战:从空壳页面到搜索引擎友好的 7 步改造

最近我对自己的个人站点(Next.js 14 + Docker standalone 部署)做了一次完整的 SEO 改造。改造前的情况很糟糕——四个核心页面全是 'use client' 空壳,搜索引擎爬虫看到的是空白 HTML。改造后:SSR 渲染、中英双语博客路由、结构化数据、多尺寸 Favicon、Sitemap、RSS、搜索引擎验证一步到位。

这篇文章记录了每一个步骤,方便你在自己的 Next.js 项目上复现。

审计起点:问题清单

快速审计发现问题横跨四个优先级:

优先级 问题 影响
P0 首页、关于、项目、博客全部是 'use client' 爬虫看到空 HTML——零收录
P1 无自定义 404 页面 Soft 404 稀释爬取预算
P1 图片优化被禁用(unoptimized: true 无 WebP/AVIF,加载更慢
P2 中文博客内容不在 Sitemap/RSS 中 近半内容对搜索引擎不可见
P2 Person JSON-LD 字段不完整 缺少 E-E-A-T 信号
P3 无 Web Manifest,Favicon 集不完整 PWA/移动端体验差
P3 无 keywords meta,无中文 description 百度/搜狗信号缺失

第一步:客户端组件迁移为服务端组件(P0)

这是影响最大的改动。四个页面——//about/projects/blog——顶层都标了 'use client'。Googlebot 拿到的是空的 <div id="__next"> 壳子,零内容。

迁移模式:

  1. page.tsx 移除 'use client'——变成 Server Component
  2. 把所有客户端逻辑抽到兄弟文件 ClientComponent.tsx(如 HomeClient.tsx
  3. Server Component 通过 props 传递数据
  4. 国际化方面:服务端渲染默认语言,useLanguage 负责运行时切换

示例——首页:

// src/app/page.tsx(Server Component——无 'use client')
import HomeClient from './HomeClient';

export const metadata: Metadata = {
  title: '...',
  description: '...',
};

export default function HomePage() {
  return <HomeClient />;
}
// src/app/HomeClient.tsx('use client')
'use client';
// ... 所有交互逻辑在这里

迁移后运行 npm run build,确认四个页面都显示 ○ (Static)——构建时完全预渲染。

第二步:自定义 404 + 图片优化(P1)

404 页面: 创建 src/app/not-found.tsx,包含品牌化 UI 和"回到首页"链接。正确的 404 响应可以避免 soft-404 混淆。

图片优化:next.config.js 移除 images: { unoptimized: true }。Next.js 现在会自动为所有 <Image> 组件生成 WebP/AVIF。

第三步:双语博客路由 + Hreflang(P2)

博客有英文内容在 /blog/slug、中文内容在 /content/blog/zh/,但路由结构只服务 /blog/*,中文文章对爬虫完全不可见。

实施方案 B——语言前缀路由:

/en/blog/my-post      ← 英文
/zh/blog/my-post      ← 中文
/blog/my-post         → 301 重定向(永久移动) → /en/blog/my-post

关键文件:

文件 作用
src/app/[locale]/blog/[slug]/page.tsx 带语言参数的博客文章页,generateMetadata 含 hreflang
src/app/[locale]/blog/page.tsx 带语言参数的博客列表页
src/lib/i18n.ts LOCALESlocalePath()blogAlternates() 工具函数
src/middleware.ts /blog/en/blog 重定向

重定向中间件确保向后兼容:

// src/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;
  if (pathname === '/blog' || pathname === '/blog/') {
    return NextResponse.redirect(new URL('/en/blog', request.url), 301);
  }
  if (pathname.startsWith('/blog/')) {
    const slug = pathname.replace('/blog/', '');
    return NextResponse.redirect(new URL(`/en/blog/${slug}`, request.url), 301);
  }
}

Sitemap 更新为双语言 URL(hreflang alternates 通过各页面的 generateMetadata 设置)。RSS feed 分语言:/feed.xml(英文)和 /zh/feed.xml(中文)。

第四步:完善 Person JSON-LD(P2)

增强了 Person 结构化数据,补充了强化 E-E-A-T 信号的字段:

{
  "@type": "Person",
  "name": "Galen Guan",
  "image": "https://guancyxx.cn/images/profile.jpg",
  "alumniOf": { "@type": "Organization", "name": "..." },
  "knowsLanguage": ["en", "zh"],
  "sameAs": [
    "https://github.com/guancyxx",
    "https://www.linkedin.com/in/guancyxx"
  ]
}

第五步:Web Manifest + 多尺寸 Favicon(P3)

用 Pillow 从源 logo 生成全套 favicon:

from PIL import Image

img = Image.open('public/logo.png')
sizes = [(16,16), (32,32), (48,48)]
# favicon.ico, favicon-32x32.png, favicon-16x16.png,
# apple-touch-icon.png (180x180), android-chrome-192x192.png

创建了 public/site.webmanifest 支持 PWA 安装,并更新了根 layout 的 metadata.icons

第六步:Keywords Meta + 双语 Description

为所有页面添加了中英文关键词的 <meta name="keywords">

Galen Guan, 官小西, full-stack developer, AI product engineer,
React, Python, TypeScript, Next.js, open source,
AI开发, 全栈开发, 人工智能, 深度学习

Description 末尾附加了中文摘要——对百度/搜狗等中文搜索引擎至关重要:

Building AI-powered products with 10+ years of full-stack expertise...
全栈开发与AI产品工程,10年+经验,开源贡献者。

第七步:搜索引擎验证

  • Google Search Console:通过 DNS TXT 记录验证
  • Bing Webmaster Tools:在根 layout 添加 msvalidate.01 meta 标签
  • Sitemap 提交:通过 GSC 界面提交

附: src/app/robots.ts — 正确配置的 robots.txt,禁止爬取 /api//_next/,同时指向 sitemap 地址。小细节,但向爬虫传递专业信号。

改造结果

指标 改造前 改造后
可爬取页面 1(404) 10+(全部 SSR)
博客路由 3(仅英文) 6(英文 + 中文 + hreflang)
结构化数据 仅 Person Person + BlogPosting
Favicon 1(logo.png) 5(ico + 4 种 PNG 尺寸)
RSS Feed 1(英文) 2(英文 + 中文)
Keywords Meta 中英双语
搜索引擎验证 Google + Bing

核心心得

  1. SSR 优先——对任何 SPA/CSR 站点来说,这是 SEO 最大单项收益
  2. 多语言必须做 hreflang——不要在 generateMetadata 里跳过 alternates.languages
  3. 双语 description——对中日韩搜索引擎(百度、搜狗、Naver)不可或缺
  4. JSON-LD 要写完整——imagealumniOfsameAs 都影响 E-E-A-T 评分
  5. 构建验证——每次改动后跑 npm run build,确认页面是 ○ (Static)

完整的审计清单保存在项目根目录的 SEO.md。如果你也在运营一个 Next.js 个人站,建议上线前走一遍同样的流程——一天时间,省掉好几个月"为什么 Google 收录不到我"的困惑。