Nuxt 内容站 SEO 与静态生成踩坑

发布于2026-10-21 11:31 阅读15次 官网改成 Nuxt 后收录差、分享卡片是空的。本文复盘五个典型问题:SPA 无预渲染导致爬虫看不到内容、漏配 meta 与 OG 标签、动态路由未预渲染、sitemap 与 robots 缺失、静态生成时环境变量读不到,并给出上线前的五项验证清单。
## 需求
把公司官网从纯前端 SPA 改成 Nuxt,目标很明确:搜索引擎能正常收录、首屏快、内容站能被社交平台正确抓取。结果上线后发现收录很差,Twitter/微信分享出来的卡片是空的。排查一圈,踩了几个 Nuxt 特有的坑。
## 坑一:SPA 没预渲染,爬虫看不到内容
最早是纯 Vue 的 SPA,HTML 里只有一个空 `<div id="app">`,所有内容靠 JS 渲染。老一代爬虫不执行 JS,直接抓到一堆空标签,自然不收录。
Nuxt 的 SSR 解决了这个问题——服务端先把页面渲染成完整 HTML 再返回。但要确认运行的是 SSR 而不是 CSR:
```bash
# 看首屏 HTML 里有没有真实内容
curl -s https://your.site/ | grep '文章标题'
```
如果 grep 不到,说明还是客户端渲染,SSR 没生效,检查 `nuxt.config.ts` 的 `ssr` 是不是被关了。
## 坑二:忘了配 meta 和 OG 标签
SSR 让内容可见了,但社交分享卡片还是空的。因为爬虫看的是 `<meta property="og:title">` 这类标签,Nuxt 不会自动生成,要用 `useHead` 或 `useSeoMeta` 显式声明:
```ts
useSeoMeta({
title: '一篇文章标题',
description: '一段描述',
ogTitle: '一篇文章标题',
ogDescription: '一段描述',
ogImage: 'https://your.site/cover.webp',
twitterCard: 'summary_large_image'
});
```
每个页面都要设,否则微信/推特抓取到的就是默认标题或者空白。
## 坑三:动态路由没预渲染
内容站的页面大多是 `/article/[id]` 这种动态路由。Nuxt 默认只预渲染首页和固定页面,动态页要显式加:
```ts
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
prerender: {
routes: ['/article/1', '/article/2']
}
}
});
```
更省事的是用 `crawlLinks: true` 让它顺着链接自动预渲染:
```ts
nitro: { prerender: { crawlLinks: true, routes: ['/'] } }
```
前提是页面里的链接是真实的 `<NuxtLink>`,动态拼接的 `a href` 爬虫抓不到。
## 坑四:站点地图和 robots 缺失
再好的内容没有入口也收录慢。两个必备文件:
```ts
// 用 @nuxtjs/sitemap 模块自动生成
modules: ['@nuxtjs/sitemap'],
sitemap: { hostname: 'https://your.site' }
```
`robots.txt` 也要允许爬虫:
```
User-agent: *
Allow: /
```
## 坑五:静态生成时环境变量读不到
`nuxt generate` 是构建时执行,`.env` 里的值必须构建时就存在,否则生成出来的页面里 API 地址是空的。运行时注入(`runtimeConfig`)的变量在纯静态托管下也读不到。
解决:纯静态生成时,所有渲染需要的数据要在构建阶段就拿全;动态数据用客户端 `useFetch` 在浏览器里拉,别指望服务端。
## 上线后验证清单
1. `curl` 首屏 HTML 能看到真实标题和正文;
2. 浏览器禁用 JS 后,页面依然有完整内容;
3. 查看页面源码,`og:title`、`description`、`og:image` 都正确;
4. 提交到各搜索引擎的收录平台,并推送 sitemap;
5. 用社交平台的分享调试器(如 Facebook Sharing Debugger)测试卡片。
## 小结
Nuxt 做内容站最大的优势是 SSR 原生支持,但"能 SSR"和"SEO 做好"是两回事。meta/OG 标签、动态路由预渲染、sitemap、robots 这几件都补齐,收录和分享才会正常。少任何一件,都可能表现为"能打开但搜不到"。