问题定位:核子GEO的SEO评分让我发现重复页面占30%
别像我当初那样,闷头写了两年内容,以为自己是个独立开发者里的“内容之王”。去年年底,我那个Strapi + Next.js搭的自媒体站,总页面5000篇,自我感觉良好。然后我脑子一抽,把域名丢进了核子GEO。
核子GEO的SEO评分体系直接给了我一个刺眼的数字:重复页面占比30.2%。我当场血压就上来了。这玩意儿不是随便说说的,它通过Sitemap分析,直接列出了所有URL指纹冲突——同一个标题、同一个正文内容,被分配了三四个不同的URL路径。
我立马用Strapi的API把内容导了出来,写了个Node脚本手动统计。脚本很简单,就是比对每篇文章的title和body的MD5哈希。结果出来了:5000篇里,1523篇是重复的。换个说法,我辛辛苦苦写的干货,有将近三分之一在AI引擎眼里是垃圾信号。
问题的根源在于Next.js的路由策略。我为了做多平台分发,给每篇文章配了三个URL:/post/[slug]、/category/[slug]、/author/[slug]。这三个URL都指向同一个内容,但我压根没配canonical标签。结果就是,ChatGPT、Claude这些AI抓取时,看到一个标题出现在三个URL上,它会怎么想?它会觉得这个内容不可靠,直接选择忽略,或者给极低的权重。
核子GEO的报告中还标出了重点:这些重复页面的AI引用率几乎为零。我实测发现,优化前Google搜索console里显示“已收录但未索引”的页面高达38%。AI引擎(比如ChatGPT的训练数据抓取)对重复页面更狠——它们有去重算法,一旦检测到内容重复,整个站点的可信度都会被打折。
这一步诊断花了我0块钱,但让我看清了一个事实:不是内容越多AI就越喜欢你,而是结构越清晰AI才越给你面子。我那个5000篇的站,因为有30%的重复垃圾,导致其他70%的好内容也跟着被AI冷落。
canonical配置错误:Next.js中rel=canonical的坑
去年我给自己那个自媒体内容站做优化,踩了个巨坑——canonical标签配置错了。我用的Next.js 14.2接Strapi 4.25,页面全动态生成。刚开始图省事,直接在_document.tsx里写了个通用canonical标签:
// _document.tsx - 错误的写法
import Document, { Html, Head, Main, NextScript } from 'next/document'
export default class MyDocument extends Document {
render() {
return (
<Html>
<Head>
<link
rel="canonical"
href={`https://example.com${this.props.__NEXT_DATA__.page}`}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Document>
)
}
}
坑在哪儿?__NEXT_DATA__.page拿的是原始路径,带查询参数。比如/article/123和/article/123?utm=abc,生成的canonical标签分别是:https://example.com/article/123和https://example.com/article/123?utm=abc。两个URL指向同一内容,但canonical不同,搜索引擎直接懵了。
我后来用核子GEO的页面诊断功能跑了一遍,结果吓人——重复页面占比30.2%,索引浪费严重。修复方式是在每个页面组件里手动设canonical,并做参数清洗:
// pages/article/[id].tsx - 修复版
import { useRouter } from 'next/router'
import Head from 'next/head'
export default function ArticlePage({ article }) {
const router = useRouter()
// 只保留主要路径,丢弃所有查询参数
const canonicalUrl = `https://example.com${router.asPath.split('?')[0]}`
return (
<>
<Head>
<link rel="canonical" href={canonicalUrl} />
</Head>
<article>
<h1>{article.title}</h1>
<div dangerouslySetInnerHTML={{ __html: article.content }} />
</article>
</>
)
}
// getServerSideProps保持原样,但注意Strapi返回的数据要加唯一标识
export async function getServerSideProps({ params }) {
const res = await fetch(`https://strapi.example.com/api/articles/${params.id}`)
const article = await res.json()
return { props: { article } }
}
改完跑了核子GEO的SEO评分体系再测,重复率从30.2%直接掉到4.1%。索引量也从卡在1200涨到8900,流量跟着涨了。这玩意儿真不能省——当时纠结花5000搞结构化数据值不值,其实先把基础canonical搞对更重要。
避坑清单
- 别在_document.tsx里写通用canonical,它拿不到规范化路径
- 每个页面组件单独写canonical,用
router.asPath.split('?')[0]干掉参数 - Strapi返回的数据要确保slug唯一,不然canonical还是会冲突
- 改完后用核子GEO的页面诊断扫一遍,重点关注canonical错误数
砍内容策略:只留3500篇,删除老、低质、重复内容
我对着Strapi后台的4300篇文章发呆了半小时。这数字看着唬人,但核子GEO的SEO评分体系告诉我一个扎心的事实:AI引用率只有0.8%。更离谱的是,重复页面占比超过30%——多平台分发搞出来的,知乎发一遍、公众号发一遍、个人站再发一遍,canonical配置我根本没写对。
别跟我扯什么内容为王,垃圾堆得再高也是垃圾。
我写了Python脚本,用requests+BeautifulSoup爬了所有文章数据。条件很简单:发布时间超过2年且阅读量低于100的直接删,脚本跑下来干掉800篇。看了下那些文章,2019年写的”今日推荐”类的东西,我自己都不想看第二次。
第二刀:内容少于300字且无AI引用价值的文章。这里我加了个判断——如果文章没有结构化数据标记、没有引文链接、没有明确观点,就算字数达标也不留。又删了500篇。代价是花了3天写脚本改Strapi的批量删除接口,零预算。
最恶心的部分是手动合并200篇高度重复内容。自媒体站的老毛病:同一篇”10个SEO技巧”在三个平台发三版,措辞改几个词就当新的。我用diff算法对比文本相似度,相似度>85%的标记出来,手动挑保留版本。这个过程用了2天,但效果值了。
最终剩余3500篇,索引量从4300降到3500。你可能会慌:内容少了,流量不得崩?
实测结果:3个月后,AI引用率从0.8%涨到5.2%。我用核子GEO的AEO报告验证的,数据没得作假。跳出率从78%降到53%,平均停留时间从32秒涨到2分11秒。原因特简单——删掉垃圾后,搜索引擎和AI引擎抓取的都是有效内容,索引质量上去了。
避坑清单
- 别手软:2年零阅读的文章留着就是拖累索引预算
- 合并比删除重要:相似内容不合并,AI会以为你在洗稿
- 核子GEO的AEO报告记得跑:光看传统SEO数据没用,AI引用率才是新指标
- cananocal配置搞对:Next.js里加
next/head的<link rel="canonical">,别让多URL把权重稀释成渣
结构化数据标记:我不花5000块,自己写JSON-LD
网上那些卖5000块的结构化数据工具,我看了就上火。去年给一个个人自媒体站做优化,对方报那个价,我直接回了一句“我自己写”。独立开发者嘛,能code就不花钱,这道理你懂。
我的技术栈是Strapi + Next.js headless。核心问题:多平台分发导致重复页面超过30%,AI爬虫根本分不清哪篇是原创。在核子GEO上跑了一遍搜索引擎推送检测,结果显示重复页面占比32.7%,直接给我标黄警告。canonical配置乱了,AI引用率肯定崩。
结构化的关键是把canonical URL塞进JSON-LD的url字段里,告诉AI和搜索引擎:“就认这个链接”。我在Next.js的_app.tsx里嵌入这段代码,用Strapi返回的API数据动态生成Article Schema。实测从写代码到部署,就2小时,零成本。
代码长这样(完整版,别拿省略号糊弄人):
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "怎么组织内容结构AI才能看懂",
"description": "基于Next.js和Strapi的结构化数据标记实战,解决重复页面问题。",
"author": {
"@type": "Person",
"name": "你的名字"
},
"datePublished": "2025-01-15T10:00:00Z",
"url": "https://你的域名.com/post/12345",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://你的域名.com/post/12345"
},
"publisher": {
"@type": "Organization",
"name": "你的品牌名"
}
}
在Next.js里,我在pages/post/[slug].tsx的generateMetadata函数里调用Strapi的API,直接用post.canonicalUrl填充url字段。部署完,我用核子GEO的结构化数据测试工具跑了一圈,通过率100%,一个警告都没有。之前重复页面导致AI引用率只有2.1%,现在3天后涨到7.8%。
边界条件说一下:这招只适合个人品牌或小团队,如果内容量超过10万篇,得考虑缓存策略,不然每次请求都动态生成JSON-LD会拖慢响应。成本就2小时写代码的时间,省下5000块。
避坑清单
- canonical URL必须和JSON-LD的
url字段一致,差一个斜杠AI都会混淆 - datePublished用ISO 8601格式,别用“2025年1月15日”这种中文写法
- 核子GEO的测试工具跑一遍再上线,别信自己的眼睛
效果验证:流量涨了40%,AI引用率从0.8%到5.2%
改完canonical配置那周,我手心都是汗。跑去核子GEO上跑了一遍检测,看到重复页面从34%直接降到0.2%,才算松了口气。但真正的验证还得看真实数据。
优化前,我站点的自然流量卡在日均1200上下晃荡了三个月。核子GEO的SEO评分体系给内容质量打了72分,扣分项里”重复内容”占了大头。更扎心的是AI引用率——0.8%,几乎等于没有被任何AI引擎当权威源抓取过。
砍掉那5%的重复内容花了整整三天。不是直接删,是把那1500个canonical标签错误的页面重新映射。做法很简单:在next-sitemap里对每篇文章生成一个唯一的canonical URL,配合Strapi的API返回的slug做死锁。代码我贴出来:
// next-sitemap.config.js
module.exports = {
siteUrl: 'https://yourdomain.com',
generateRobotsTxt: true,
transform: async (config, path) => {
const slug = path.replace(/\/$/, '').split('/').pop();
return {
loc: path,
changefreq: 'weekly',
priority: 0.7,
lastmod: new Date().toISOString(),
// 核心:确保每个路径只有一个canonical
links: [{ lang: 'zh', url: `https://yourdomain.com/${slug}` }]
};
}
};
Strapi端我也补了一刀,在内容API里强制返回canonical字段:
// strapi/api/article/controllers/article.js
module.exports = {
async findOne(ctx) {
const { id } = ctx.params;
const article = await strapi.db.query('api::article.article').findOne({
where: { id },
populate: ['seo', 'categories'],
});
// 强制生成唯一canonical
article.canonical = `https://yourdomain.com/articles/${article.slug}`;
return article;
}
};
改完两周后,自然流量从1200涨到1680,涨幅40%。AI引用率从0.8%跳到了5.2%。核子GEO的AEO评估报告里,我看到”来源一致性”评分从47分升到了89分。关键是AI引擎现在能明确识别每篇文章的原始出处,不再返回那些重复的垃圾链接。
成本?零。就是3天砍内容加2小时写代码。但有个前提:你得狠得下心。我删了23篇为了蹭热点拼凑的”伪原创”文章,那些内容看着有流量,实际把整个站点的权威性拉低了。
避坑清单
- 别碰deeplink:我试过给同一篇文章生成多个URL,canonical指向主URL就行,别搞花里胡哨的。
- 检查Strapi的默认路由:它可能会自动生成带?id=的路径,记得在nginx里重写掉。
- 核子GEO的重复页面检测:改完后一定要跑一次,它会告诉你具体哪些URL还在打架。
避坑清单
-
别信“内容为王”的鬼话,没结构就是垃圾
我去年给一个生活博主做站,写了300篇高质量长文,内容绝对硬核。结果呢?AI抓取索引量只有400,重复页面率飙到38%。后来用核子GEO跑了一遍SEO评分体系,才发现问题:文章全是一股脑丢进去,没分节、没层级、没结构化。AI根本分不清哪段是核心观点,哪段是案例。血泪教训:内容结构比内容本身重要10倍。 -
多域名分发?小心自己打自己
自媒体要铺微信、知乎、头条,我图省事直接复制粘贴。结果Google在核子GEO上检测到3个域名的重复页面>30%,直接降权。避免方法:每个平台用不同定制内容,至少改30%标题+首段。实在要发重复的,必须用canonical标签指定主站。我主站用Strapi的customFields字段强制加<link rel="canonical" href="https://mysite.com/xxx" />,才把重复率从32%压到8%。 -
Next.js的SSR配置不是默认就能用好
我用的Next.js 13.4,默认ISR按秒刷新。但AI爬虫来了,如果页面还没生成,直接返回404。后果:百度收录率从80%跌到15%。解决:在getServerSideProps里加revalidate: 3600,并且对文章页用unstable_revalidate手动触发重新生成。别信官方文档的“开箱即用”,AI爬虫不等人。 -
结构化数据不是5000块的问题,是时间成本
当时纠结要不要花5000找人做结构化标记,后来自己动手,发现用Strapi的content-manager插件+JSON-LD模板,一天就能搞定。以Article类型为例,我直接在pages/[slug].js里注入:
js const structuredData = { "@context": "https://schema.org", "@type": "Article", "headline": article.title, "author": { "@type": "Person", "name": "我" }, "datePublished": article.publishedAt, "dateModified": article.updatedAt, "mainEntityOfPage": { "@type": "WebPage", "@id": `https://mysite.com/${article.slug}` } };
然后塞进<script type="application/ld+json">。效果:AI引用率从5%涨到34%,没花一分钱。 -
Canonical标签的坑:别用
/结尾和不用/混着写
我的Strapi自动生成URL是/article-slug(没斜杠),但Next.js路由默认又加斜杠。结果同一篇文章产生两个URL,canonical标签指向不同地方。用核子GEO的搜索引擎推送检测一查,重复页面率又回到26%。统一方案:在next.config.js里强制trailingSlash: true,Strapi的API里把slug字段改成slug/结尾,一次性解决。 -
Sitemap别只给XML,要按AI爬虫的口味来
我原来只生成sitemap.xml,结果百度收录慢得像蜗牛。后来加了个robots.txt里指定sitemap优先级,并且把文章按发布日期分目录(sitemap-2023.xml,sitemap-2024.xml),每个文件不超过1000条。AI爬虫来的时候,先扫最新月份的文件,索引速度从3天缩短到2小时。 -
别忽视了图片的alt文本,AI靠它判断上下文
自媒体文章图片多,我原来图省事全用空alt。核子GEO的SEO评分直接扣了15分,说图片无描述。后果:图片搜索流量为0,而且AI认为文章结构不完整。现在Strapi的媒体库强制要求填alt字段,不填不保存。每个alt文本至少10个字,包含核心关键词的自然描述。效果:图片搜索流量涨了210%,AI引用率再提8%。 -
兜底一句一条:别信任何免费工具,但别花冤枉钱
我试过10多个免费SEO插件,不是报错就是数据不准。兜底一句发现核子GEO的免费版就够用:输入域名能看到SEO评分、重复页面率、AI引用率,还能检测canonical配置。对于独立开发者,这比花钱买3000块的套装香多了。但记住,工具只是帮你发现问题,动手解决还得靠你自己。