模块六:运营增长与高级话题 | 第02讲:SEO 与社交分享——为什么上线后还是没人看见你?
课程项目:VibeNote 智能笔记
技术栈:Next.js、React、TypeScript
本节目标:让「能被找到」与「被愿意点开」同时成立:搜索引擎可读、社交平台可预览。
一、开场:你的产品不是「没人需要」,而是「没人读得懂」
很多 Vibe Coding 项目最大的落差来自这里:你已经在浏览器里看见了页面,但搜索引擎爬虫、微信/飞书/Slack 的链接预览机器人,看到的可能是空白标题、随机描述、甚至无法抓取。结果就是你以为上线了,其实在流量视角里等于「不存在」。
参考材料里有个很形象的对比:只发一条蓝链接,点击率往往惨淡;配上 Open Graph(OG) 大图与清晰标题,同样内容传播效率会完全不同。对 VibeNote 这种「笔记 + 知识库」型产品,单页笔记的标题/摘要/结构化信息就是增长杠杆。
本节把 SEO 与社交分享拆成可执行工程项,全部对齐 Next.js App Router 的真实写法。
二、搜索引擎如何理解你的 Next.js 应用?
把爬虫当作「只能读 HTML 与元信息的用户」。它关心三件事:
- 我能不能进来?(
robots.txt、反爬、登录墙) - 你有哪些 URL?(链接发现 +
sitemap) - 每个 URL 讲什么?(
title/description/ 结构化内容 / 性能信号)
flowchart TD
A[爬虫访问] --> B{robots 允许?}
B -- 否 --> Z[不收录/部分不收录]
B -- 是 --> C[抓取 HTML]
C --> D[解析 metadata 与正文]
D --> E[进入索引队列]
E --> F[排序受多因素影响]
对 VibeNote 的启示:公开笔记页要可抓取;私密笔记要么 noindex,要么必须登录且不要指望 SEO。
三、Next.js Metadata:把每一页变成「可被摘要」
App Router 推荐在 layout.tsx 或 page.tsx 导出 metadata 对象,或用 generateMetadata 做动态标题(例如按笔记 ID 查库)。
静态站点的根布局示例:
// app/layout.tsx
import type { Metadata } from "next";
export const metadata: Metadata = {
metadataBase: new URL(process.env.NEXT_PUBLIC_APP_URL!),
title: {
default: "VibeNote — AI 原生智能笔记",
template: "%s · VibeNote",
},
description: "用 AI 组织笔记、标签与检索,Next.js 全栈交付。",
openGraph: {
type: "website",
locale: "zh_CN",
siteName: "VibeNote",
},
twitter: {
card: "summary_large_image",
},
};
动态笔记页(伪代码):
// app/notes/[id]/page.tsx
import type { Metadata } from "next";
export async function generateMetadata(props: {
params: Promise<{ id: string }>;
}): Promise<Metadata> {
const { id } = await props.params;
const note = await getNote(id); // 你的数据层
const title = note?.title ?? "笔记未找到";
const description = note?.summary ?? "VibeNote 笔记";
return {
title,
description,
openGraph: {
title,
description,
type: "article",
publishedTime: note?.createdAt,
modifiedTime: note?.updatedAt,
images: note?.coverUrl ? [{ url: note.coverUrl }] : undefined,
},
};
}
关键点:metadataBase 决定相对路径 OG 图如何拼成绝对 URL;缺了它,很容易出现「社交平台抓不到图」。
四、Sitemap 与 Robots:别让用户猜你有哪些页面
Next.js 13+ 可以用 app/sitemap.ts 与 app/robots.ts 生成路由(具体 API 以你项目 Next 版本为准,思路一致)。
// app/sitemap.ts
import type { MetadataRoute } from "next";
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const base = process.env.NEXT_PUBLIC_APP_URL!;
const publicNotes = await listPublicNoteSlugs(); // 仅公开笔记
return [
{ url: `${base}/`, lastModified: new Date() },
{ url: `${base}/pricing`, lastModified: new Date() },
...publicNotes.map((slug) => ({
url: `${base}/notes/${slug}`,
lastModified: new Date(),
})),
];
}
// app/robots.ts
import type { MetadataRoute } from "next";
export default function robots(): MetadataRoute.Robots {
const base = process.env.NEXT_PUBLIC_APP_URL!;
return {
rules: [{ userAgent: "*", allow: "/", disallow: ["/api/", "/dashboard/"] }],
sitemap: `${base}/sitemap.xml`,
host: base.replace(/^https?:\/\//, ""),
};
}
注意:私有路由(/dashboard)、API 路由一般应 disallow 或保持不可链接,避免浪费爬虫预算。
五、Open Graph 与 Twitter Card:分享链路工程化
sequenceDiagram
participant U as 用户
participant S as 社交平台抓取服务
participant N as VibeNote(Next.js)
U->>S: 粘贴 https://notes/xxx
S->>N: GET 页面 HTML
N-->>S: 返回 meta og:title/description/image
S-->>U: 生成卡片预览
三种常见实现:
- 约定式文件:在路由段放置
opengraph-image.png/twitter-image.png(Next 会帮你生成标签,适合统一品牌图)。 - 动态 OG:用
@vercel/og或图片路由把标题渲染成图(适合「每篇笔记不同图」)。 - 手动 meta:在
metadata.openGraph.images指定绝对 URL。
设计建议:
- 图片比例与平台有关,宁可大不可糊;文案区域避开边缘裁切。
og:title与og:description不要在生产环境写「测试」「TODO」。- 笔记页若内容很长,
description用人工摘要或模型生成摘要,不要直接把 Markdown 原文塞满。
六、内容层 SEO:VibeNote 的「可索引文本」
再强的 meta 也救不了「页面上没有可读正文」。对笔记产品:
- 标题层级(
h1唯一、h2/h3有结构)帮助理解主题。 - 内部链接(相关笔记、标签聚合页)帮助发现链接。
- 避免整页都是客户端异步空白:关键文本应能在首屏 HTML 中出现(视你的渲染策略而定)。
性能与体验指标(如 Core Web Vitals)会影响排名与抓取效率:图片懒加载、字体子集化、减少长任务,都是 SEO 的「隐性项」。
七、结构化数据(可选加分项)
对文章类页面,可以引入 JSON-LD(Article / BlogPosting)。实现上可以用 app/notes/[id]/page.tsx 输出 <script type="application/ld+json">。
价值:搜索结果可能出现更丰富展示(视搜索引擎策略而定)。注意:只标记用户真实可见内容,不要堆砌虚假字段。
八、复盘清单(上线前 10 分钟过一遍)
-
metadataBase是否正确? - 公开页与私有页的
robots/noindex策略是否区分? -
sitemap.xml是否只包含该收录的 URL? - 社交平台调试工具(如各平台提供的 debugger)是否预览正常?
- 笔记分享链接是否会在登录墙后「抓不到」?若会,是否接受?
九、小结
- SEO 不是玄学,是可抓取 + 可理解 + 可发现 + 体验不差的工程组合。
- Next.js App Router 用
metadata、sitemap.ts、robots.ts把基础面一次打牢。 - 社交分享靠 OG/Twitter 决定点击率;对 VibeNote 来说,动态 generateMetadata 是笔记增长的刚需。
思考题
- 你的私密笔记如果误被收录,最可能的三条技术原因是什么?如何修复与预防?
- 动态 OG 图片与静态 OG 图片的维护成本差异是什么?你会为 VibeNote 选哪种组合?
sitemap若包含 10 万条笔记,你会如何分页与控制生成成本?
下节预告
下一讲进入 数据统计与增长:我们会把「访问量」拆成 漏斗指标与 行为事件,对比 Google Analytics 4 与 自托管统计(如 Umami) 的取舍,并给出一套 指标驱动迭代 的周报模板,让 VibeNote 的每一次发版都能回答「有没有更好」而不是「我觉得更好」。