引子:一个前端开发者的疑问
你有没有想过:掘金、CSDN 这些老牌内容站,流量从哪来?答案几乎都是 SEO。
再看另一边,市面上多如牛毛的 AI Agent 产品官网,清一色 Next.js。为什么?答案就藏在 SPA 的一个老毛病里------SEO 几乎为零。
这篇文章把我最近理清楚的整条线记录下来:SPA 为什么 SEO 差 → Next.js 怎么解决 → App Router 的约定 → SEO / GEO 的基本语法。写给同样在大前端圈子里挣扎的朋友。
一、Next.js 是什么
一句话:Next.js 是 React 全栈框架,Vue 生态对应的就是 Nuxt.js。
- 可以写页面(前端)
- 也可以写 API(后端)
- 背靠 Vercel,部署体验极佳
- SEO 做得非常棒,很多 AI 产品用它做官网
创建项目:
bash
npx create-next-app@latest
选默认配置,一键包含全家桶:
| 依赖 | 作用 |
|---|---|
| React / React-DOM | 界面 |
| TypeScript | 类型安全 |
| Tailwind CSS | 样式 |
| ESLint | 代码规范 |
二、SPA 的辉煌与短板
先给 SPA 正名:它的体验是真的好。
- 组件在前端挂载,
useEffect异步请求数据,不需要刷新页面 - 前端路由让页面切换快、顺滑
- 抄原生 App 的体验,WebView 一包,Android / iOS 一套代码全搞定
- 移动端时代,超级 App 里 80% 的页面都是 SPA,只有 20% 是原生
原生要写两套(Android + iOS),SPA 只需要写一次 HTML。这个账,前端赢麻了。
但短板同样致命:没有 SEO。
SPA 服务器返回的 index.html 是这样的:
html
<div id="root"></div>
<script src="main.jsx"></script>
真正的页面内容呢?要等浏览器下载 JS → React 挂载到 #root → useEffect 发请求拿数据 → 才能渲染出来。
搜索引擎爬虫(百度、Google、Bing)根本不等你的 JS 跑完,抓到 HTML 就走了,看到的只有一个空的 #root。PC 时代,搜索引擎就是流量入口,SEO 就是命。没有内容可索引,等于网站对搜索引擎隐身。
三、CSR vs SSR:组件到底在哪里渲染
这是 SEO 问题的根本------组件到底在哪里渲染:
- CSR(Client Side Rendering):浏览器渲染,也就是 SPA
- SSR(Server Side Rendering):服务器渲染,也就是 Next.js
用一条公式看透:
css
JSX 组件(模板) + 数据 = HTML(渲染结果)
同一个 React 组件、同样的数据,公式在哪里执行,决定了爬虫看到什么:
| CSR | SSR | |
|---|---|---|
| 等式执行位置 | 浏览器(客户端) | 服务器(Node) |
| 返回给浏览器 | 空 #root + JS |
完整 HTML |
| 爬虫看到 | 空壳 | 标题 / 正文 / 链接 |
| SEO | 几乎为零 | 优秀 |
四、SSR 怎么实现的:JSX + 数据 = HTML
原理其实很朴素:React 组件本质是个函数,只是个模板。只要不监听事件、不用 useEffect,组件函数 + 数据就能在 Node 环境里直接编译成 HTML 字符串------服务器上没有 DOM,输出的是字符串格式化。
tsx
// app/todos/page.tsx ------ 这个组件在服务器上渲染
export default async function TodosPage() {
const todos = await getTodos() // 服务器端拿数据
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}
浏览器收到的不是空壳,而是:
html
<ul>
<li>写一篇掘金博客</li>
<li>学完 Next.js 基础</li>
</ul>
爬虫一抓一个准。然后浏览器端的 JS 再做 hydrate(注水),把静态 HTML 接管成可交互的 React 应用------SSR 之后体验依然和 SPA 一样好。鱼和熊掌兼得。
五、Next.js App Router:约定大于一切
Next.js 的路由不需要配置,文件就是路由,这是它「开箱即用」的底气。
text
app/
├── layout.tsx # 共享布局(导航、页脚),包裹所有页面
├── page.tsx # → /
├── about/
│ └── page.tsx # → /about
└── post/
└── [id]/
└── page.tsx # → /post/123(动态路由)
渲染规则:请求 /about 时,先执行 layout.tsx 布局,再执行 about/page.tsx 组件,把 tsx 编译成 HTML。
layout.tsx 长这样:
tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="zh-CN">
<body>
<nav>...导航...</nav>
{children}
<footer>...页脚...</footer>
</body>
</html>
)
}
动态路由 [id] 是重点------一个文件,服务千万篇内容:
tsx
// app/post/[id]/page.tsx
export default async function PostPage({
params,
}: {
params: { id: string }
}) {
const post = await getPost(params.id)
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
)
}
/post/123、/post/456......每一篇都是 SSR 渲染出来的完整 HTML,整站被搜索引擎收录,流量自然来。
六、SEO 的基本语法
SEO 分两层:
第一层:告诉搜索引擎「你是谁」 (<head> 里的元信息)
Next.js App Router 里直接导出 metadata:
tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: '我的 AI 产品官网',
description: '一句话说清提供什么价值',
keywords: ['AI', '助手', '工具'],
}
生成的 HTML:
html
<head>
<title>我的 AI 产品官网</title>
<meta name="description" content="一句话说清提供什么价值" />
<meta name="keywords" content="AI, 助手, 工具" />
</head>
第二层:做内容。用户访问你的原因,也是搜索引擎收录的主体。title 写得再好,没有内容也是空架子。SSR 的价值就在这里------内容以完整 HTML 的形式送到爬虫嘴里。
七、GEO:AI 时代的新战场
传统 SEO 是给搜索引擎爬虫看的。但 AI 时代来了,用户入口从百度变成了豆包、ChatGPT、Perplexity。
GEO(Generative Engine Optimization):让 AI 在生成回答时,带上你的内容和购买链接。
| SEO | GEO | |
|---|---|---|
| 对象 | 搜索引擎爬虫 | AI 大模型 |
| 机制 | 抓取 HTML 索引 | 读取内容,生成回答时引用 |
| 目标 | 搜索结果排名靠前 | 回答中出现你的内容 + 链接 |
| 前提 | SSR 输出完整 HTML | 内容结构化、权威、可被 AI 理解 |
为什么 AI 产品官网用 Next.js?因为 GEO 时代 AI 同样要读你的网页------如果还是 SPA 的空 #root,AI 一样读不到。一份 SSR 的完整 HTML,爬虫(SEO)和 AI(GEO)通吃,一份投资,双重收益。
八、总结
把整条线串起来:
text
SPA(#root 空壳)── SEO 差 ──→ 需要 SSR 让爬虫看到内容
└→ Next.js(React 全栈框架)
├─ 文件即路由(App Router)
├─ JSX + 数据 = HTML(服务器执行)
├─ meta 标签告诉搜索引擎你是谁
└─ 完整 HTML 同时喂给爬虫(SEO)和 AI(GEO)
大前端手里不止有 SPA。掌握 Next.js,等于同时拿到前端体验、后端能力、SEO 流量三张牌。下一个 AI 产品官网,不妨就从这行命令开始:
bash
npx create-next-app@latest