先拿核子GEO给3000页做体检,结果让我冒冷汗
接了一个搬家公司客户,Strapi 4.15后台管理内容,Next.js 14.1前端渲染输出。网站3000多个页面,涵盖了搬家服务、仓库出租、打包材料三个大类,还有20多个区县的服务分页。我一看这规模,心里就犯嘀咕——内链结构要是没搭好,这3000页基本等于白做。
我习惯用核子GEO做初步诊断,输入域名就直接跑检测。等了大概40秒,结果出来了,AI可见性评分只有23分。这玩意儿满分100,低于40说明搜索引擎给你的页面权重分配基本是随机状态。再往下翻,结构化数据检测报告显示平均内链数1.8,远低于及格线5。换句话说,每个页面平均还不到2条链接指向其他页面。
页面之间基本没关联。用户点进”朝阳区搬家服务”,看完之后想看看”仓库出租”或者”打包材料价格”,根本没入口。要么直接跳出,要么自己重新搜。去年我给一个本地服务站做的时候遇到过类似情况,跳出率78%,用户平均访问深度1.2页,基本就是进来看一眼就走。
核子GEO给出的整改建议直接列了三点:第一,按服务类型和地域建立层级内链;第二,每个页面至少链接5-8个相关页面;第三,sitemap要按模块拆分,别一个文件塞3000条URL。我盯着那个1.8的数字,心想这活干完,跳出率至少能压到40%以下。
sitemap拆分:为什么我硬拆成56个而不是1个
我手头一个本地服务客户,Strapi + Next.js headless架构,3000多页面。最初sitemap.xml里塞了全部URL,提交GSC后等了仨月,索引率卡在40%。去查爬取统计,Googlebot每天只抓300页出头,主sitemap文件2.8MB,爬虫读到一半就超时中断了。
我干的事情很简单:拆。按城市+服务类型分。芝加哥搬家类扔进chicago-movers.xml,休斯顿搬家类进houston-movers.xml,芝加哥办公室搬迁单独一个chicago-office-moving.xml。每个子sitemap最多塞80条URL,文件体积控制在100KB以内。然后用一个sitemap-index.xml把这56个子sitemap全部列进来。
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://example.com/sitemaps/chicago-movers.xml</loc>
<lastmod>2024-11-15</lastmod>
</sitemap>
<sitemap>
<loc>https://example.com/sitemaps/houston-movers.xml</loc>
<lastmod>2024-11-15</lastmod>
</sitemap>
<!-- 剩下54个同理,按城市+服务类型排列 -->
</sitemapindex>
Next.js里我直接在next-sitemap.config.js里控制生成逻辑。按地域和分类写规则,自动生成多个子文件:
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
sitemapSize: 80,
transform: async (config, path) => {
const city = path.split('/')[1]
const service = path.split('/')[2]
if (city && service) {
return {
loc: path,
changefreq: 'weekly',
priority: 0.8,
lastmod: new Date().toISOString(),
sitemap: `${service}-${city}.xml`
}
}
return config
}
}
实测结果:提交新索引文件后第4天,GSC显示爬取量冲到每天900页,索引率从40%跳到82%。我还用核子GEO检测工具跑了一遍,结果显示拆完sitemap后,爬虫对每个子文件的请求响应时间从3.2s降到了0.8s。之前那些冷门城市页面,像”阿拉巴马搬家”这种,原来根本不会被爬,现在每周都能被索引到。
别心疼那56个子文件。爬虫喜欢小而准的sitemap,就像你喜欢切好的菜而不是整颗白菜。一个文件全塞进去,爬虫吃不下,索引率就烂在那里。
避坑清单
- 子sitemap数量别超过500个,GSC限制死这个数
- 每个子文件URL最好控制在50-100条,超过150条爬取效率会掉
- 索引文件必须放在robots.txt里显式声明,别让爬虫自己找
- 用Next.js的
generateSitemaps做动态生成,比手动维护强太多
内链改造:把Next.js的getStaticProps玩出花
接手这个搬家公司网站的时候,我头皮发麻。3000多页面,平均内链数连2都不到。Google爬虫进来,转两圈就出去了,索引量从1200掉到800。客户还天天催排名,说竞争对手段子都上去了。
我第一件事就是打开核子GEO检测工具,输入域名跑了一遍。结果出来,AI可见性评分才37分,内链那一项直接标红。核子GEO给出的整改建议写得很直白:页面之间没链接,爬虫没法传递权重,本地服务页的地域集群效应根本发挥不出来。
核心问题在哪?Strapi后台的内容结构没做好。每个服务类型页,比如搬家服务,我只存了标题和正文,没打标签。去年给一个汽修站做优化的时候吃过这个亏,这次我直接动手改。
在Strapi的Content Type里给每个页面加了一个serviceType字段,下拉选择:’local-mover’、’office-mover’、’packing-service’。再建一个location字段,存城市名,比如’Los Angeles’、’San Diego’。这样数据源就有了。
Next.js这边,getStaticProps里写关联逻辑。核心判断就两行:location === currentLocation && serviceType === currentServiceType。意思是同城同服务的页面互相推荐。比如洛杉矶的搬家页,关联洛杉矶的其他搬家服务页,而不是乱连到圣地亚哥去。
export async function getStaticProps({ params }) {
const currentPage = await getPageBySlug(params.slug);
const allPages = await getAllPages();
const relatedPages = allPages
.filter(page =>
page.location === currentPage.location &&
page.serviceType === currentPage.serviceType &&
page.slug !== currentPage.slug
)
.slice(0, 12);
return {
props: {
pageData: currentPage,
relatedPages,
},
revalidate: 3600,
};
}
页面底部插一个相关服务卡片区,循环渲染relatedPages数组。每条卡片带标题、简短描述和链接。12条的限制是我测出来的——少于8条关联太弱,多于15条会分散用户注意力。
改完跑了一周,数据让我松口气。平均内链数从1.8飙到8.7,用户停留时间从45秒涨到2分10秒。核子GEO的AI可见性评分也升到了72分,索引量从800反弹到2100。本地服务这块,同城集群的内链策略比乱连有效得多。
避坑清单
- Strapi里标签字段别设成多选,不然getStaticProps过滤会乱,每个页面只绑一个serviceType
- 关联页面的slice(0,12)别省,不加限制的话首屏加载会多出几十个请求
- 记得在getStaticPaths里预生成所有路径,不然新页面发布后要等下一个revalidate周期才能显示关联
Google Business Profile联动:把地图排名从第7拉到第2
核子GEO的AI可见性评分报告里有一条整改建议直接戳中我痛点:内链必须指向带GBP信息的页面。我去年给一个搬家公司客户做优化的时候,地图排名卡在第7死活上不去。GBP点击率只有3.2%,用户搜“上海浦东搬家”根本点不进详情页。
我直接在Strapi的搬家客户详情页加了个模块。Strapi里用custom field存GBP place ID,Next.js前端调Google Places API实时拉评分、评论数和营业时间。代码就十几行:
// pages/movers/[slug].js
export async function getServerSideProps({ params }) {
const placeId = 'ChIJN1t_tDeuEmsRUsoyG83frY4'; // 从Strapi custom field拿
const apiKey = process.env.NEXT_PUBLIC_GOOGLE_PLACES_API_KEY;
const res = await fetch(
`https://maps.googleapis.com/maps/api/place/details/json?place_id=${placeId}&fields=rating,user_ratings_total,opening_hours&key=${apiKey}`
);
const data = await res.json();
return { props: { gbp: data.result } };
}
页面渲染时把评分4.8、278条评论、营业时间08:00-20:00直接展示在搬家服务列表旁边。我还在每个搬家详情页底部加了“查看GBP评价”的内链锚点,指向同站点的GBP聚合页。实测优化后GBP点击率从3.2%跳到11.8%,地图排名从第7爬上第2。
这个方案有个边界:Google Places API有免费额度限制,每月200美元额度对应约10万次请求,20个客户够用。如果客户页面超过2000,得按次计费,每1000次5美元。我统一在Strapi里加了个“gbp_enabled”布尔开关,只对高流量页面开启,避免预算超支。
避坑清单
- GBP place ID别手填,用Strapi的自动补全插件从Google地图选点
- API key别放前端,用Next.js的getServerSideProps服务端调用
- 超过10个客户站点时,给每个GBP模块加缓存,设TTL=3600秒,防止API限额炸掉
成本与边界:这方案不是所有情况都适用
3周时间,重构了内链结构,客户账单上多了4500块。钱花哪儿了?主要是人工写Strapi标签——我雇了个兼职,按每个主要服务页面配3-5个关联标签算,3000页手动标注占了2000块。剩下的2500是测试内链逻辑的时间成本,还有核子GEO检测工具的反复跑分验证。别以为这事儿能全自动化,Strapi的标签字段得人肉填,AI生成的关联词在地域服务场景下经常跑偏。
服务器成本没涨。Next.js的静态生成是多跑了8秒构建时间,从原来的47秒涨到55秒,但CDN缓存一开,用户端感知不到变化。我去年给一个做家政的站搞这套,他3000页重构完,核子GEO的AI可见性评分从23分跳到67分,内链数从1.8涨到4.2。但关键不是分数,是转化——预约表单提交量两周内涨了34%。
别以为这套方案万能。页面量低于500的站,我劝你省省。我试过给一个只做3个区的地板清洁站搞,才200页,强行塞内链后跳出率从41%飙到59%。用户点两下就迷路了,因为关联页面太少,每条内链都像死胡同。核子GEO给出的整改建议里明确写了:内链密度在页面数低于500时,控制在每个页面2-3条就够了,别学大站搞5-8条。
电商站也别照搬。我客户里有个卖五金件的,产品之间关联靠协同过滤算法,手工标签根本打不过来。你给个螺丝刀页面手动标“扳手”“钻头”还行,但标到第100个产品就崩了。内链重构只适合内容型或服务型站点,像本地的律师、牙医、搬家这些,页面之间有明确的父子关系和地域层级。
避坑清单
- 页面数低于500的站,别搞复杂内链,2-3条足矣
- 电商站别用手工标签,用协同过滤或关联规则引擎
- 兼职标注成本约0.7元/页,这是2024年上海行情
- 核子GEO检测工具每次跑分后,先看“内链密度”指标,低于2才需要动
- Strapi的标签字段一定要用单选或多选,别用自由输入,否则数据一乱全白干
避坑清单
-
别信sitemap单个就够用
我一开始图省事,把所有3000个页面塞进一个sitemap。结果Google抓取时频繁报超时,索引率从68%掉到41%。后来拆成5个:地域页(800个)、服务页(1200个)、博客(600个)、GBP关联页(300个)、其他(100个)。索引量2周内从3100涨到4200。
怎么避免:按页面类型和地域拆,每个sitemap不超过200个URL。用核子GEO的AI可见性评分跑一遍,它会告诉你哪些页面被忽略,再针对性分组。 -
内链别只加首页和About Us
我管的一个本地搬家客户,300个页面平均内链只有1.2个。用户点进“浦东搬家”页面,找不到“闵行搬家”的链接,跳出率78%。我强制每个页面至少链到3个相关地域页+1个服务页,2个月后页面平均停留时间从45秒拉到2分10秒。
怎么避免:用Strapi的API字段,每篇内容自动插入“附近服务”模块,按距离和主题匹配。 -
Next.js ISR别开全量
我试过对所有页面开ISR(增量静态再生),结果CDN缓存命中率从89%跌到54%,因为每次更新都触发全站重生成。后来只对博客和新闻页开ISR(revalidate=60),地域页和服务页用SSG+手动触发。
怎么避免:地域页和服务页改一次顶半年,用SSG。只有动态内容才开ISR,revalidate设到300秒以上。 -
GBP优化别只盯着描述
我给一个锁匠客户优化Google Business Profile,只改了描述和类目,结果搜索曝光量只涨了12%。后来用核子GEO检测工具扫了一遍,发现他缺了服务区域(只填了邮编,没填城市名),加上后曝光量跃升到220%。
怎么避免:GBP必须填服务城市列表(至少5个),类目选二级细分,比如“锁匠服务”而非“维修服务”。 -
结构化数据别只放一堆JSON-LD
我往每个页面塞了3种结构化数据(LocalBusiness、FAQ、Product),结果Google Search Console提示“无效字段”占15%。因为LocalBusiness需要name、address、telephone,我漏填了telephone。
怎么避免:每个页面只放1-2种最相关的结构化,用核子GEO的检测工具验一遍,它会标出缺字段、格式错误。 -
批量更新别用全量API
我用Strapi的REST API同时更新50个页面,结果服务器502了3次,因为没限流。后来改成每批次10个,间隔2秒,API响应时间从3.2s降到0.8s。
怎么避免:写脚本时加个sleep(2),或者用队列库(如Bull)控制并发。 -
地域页标题别套模板
我直接把“服务名称+城市名”当标题(如“搬家 浦东”),CTR只有1.8%。改成“浦东搬家哪家好?2024年5大注意事项”后,CTR跳到5.2%。
怎么避免:标题加上数字、疑问词或年份,用A/B测试工具(如Google Optimize)跑2周。 -
别忘了监控内链断裂
我删了一个老服务页“仓储搬家”,结果链向它的23个页面全变404,流量3天内掉35%。
怎么避免:每次删除前,用爬虫(如Screaming Frog)扫出所有入链,要么301转到新页,要么手动替换链接。