搜索引擎优化(SEO)
注意
想针对 AI 助手和大语言模型优化?请看生成式引擎优化(GEO)指南。
什么是真正的 SEO?
SEO(搜索引擎优化,Search Engine Optimization)常常被误解为「在 Google 上排上名」或一个库能神奇提供的选项。实际上,SEO 是一门广泛的学科,核心是交付人们需要的、有价值的内容,并让他们容易找到。
技术 SEO(Technical SEO) 是开发者接触最多的一类 SEO。它涉及使用满足搜索引擎、爬虫、排序器甚至大语言模型技术要求的工具和 API。当有人说某个框架「SEO 支持很好」时,他们通常是指它提供了让这个过程变得简单直接的工具。
TanStack Start 提供全面的技术 SEO 能力,但你仍然需要付出努力才能有效地使用它们。
TanStack Start 提供什么
TanStack Start 给了你技术 SEO 的积木:
- 服务端渲染(SSR)——确保爬虫收到完全渲染的 HTML
- 静态预渲染——预生成页面,以获得最佳性能和可爬取性
- 文档 Head 管理——对 meta 标签、标题和结构化数据的完全控制
- 性能——通过代码分割、流式传输和优化构建实现快速加载
文档 Head 管理
路由上的 head 属性是你的 SEO 主要工具。它允许你设置页面标题、meta 描述、Open Graph 标签等。
基础 Meta 标签
// src/routes/index.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/')({
head: () => ({
meta: [
{ title: 'My App - Home' },
{
name: 'description',
content: 'Welcome to My App, a platform for...',
},
],
}),
component: HomePage,
})动态 Meta 标签
用加载器数据为内容页面生成动态 meta 标签:
// src/routes/posts/$postId.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/posts/$postId')({
loader: async ({ params }) => {
const post = await fetchPost(params.postId)
return { post }
},
head: ({ loaderData }) => ({
meta: [
{ title: loaderData.post.title },
{ name: 'description', content: loaderData.post.excerpt },
],
}),
component: PostPage,
})Open Graph 与社交分享
Open Graph 标签控制你的页面在社交媒体上分享时的展示效果:
export const Route = createFileRoute('/posts/$postId')({
loader: async ({ params }) => {
const post = await fetchPost(params.postId)
return { post }
},
head: ({ loaderData }) => ({
meta: [
{ title: loaderData.post.title },
{ name: 'description', content: loaderData.post.excerpt },
// Open Graph
{ property: 'og:title', content: loaderData.post.title },
{ property: 'og:description', content: loaderData.post.excerpt },
{ property: 'og:image', content: loaderData.post.coverImage },
{ property: 'og:type', content: 'article' },
// Twitter Card
{ name: 'twitter:card', content: 'summary_large_image' },
{ name: 'twitter:title', content: loaderData.post.title },
{ name: 'twitter:description', content: loaderData.post.excerpt },
{ name: 'twitter:image', content: loaderData.post.coverImage },
],
}),
component: PostPage,
})规范 URL(Canonical URLs)
规范 URL 有助于避免重复内容问题:
export const Route = createFileRoute('/posts/$postId')({
head: ({ params }) => ({
links: [
{
rel: 'canonical',
href: `https://myapp.com/posts/${params.postId}`,
},
],
}),
component: PostPage,
})结构化数据(JSON-LD)
结构化数据帮助搜索引擎理解你的内容,并能在搜索结果中启用富结果(rich results):
export const Route = createFileRoute('/posts/$postId')({
loader: async ({ params }) => {
const post = await fetchPost(params.postId)
return { post }
},
head: ({ loaderData }) => ({
meta: [{ title: loaderData.post.title }],
scripts: [
{
type: 'application/ld+json',
children: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'Article',
headline: loaderData.post.title,
description: loaderData.post.excerpt,
image: loaderData.post.coverImage,
author: {
'@type': 'Person',
name: loaderData.post.author.name,
},
datePublished: loaderData.post.publishedAt,
}),
},
],
}),
component: PostPage,
})服务端渲染
SSR 在 TanStack Start 中默认开启。这确保搜索引擎爬虫收到完全渲染的 HTML 内容,这对 SEO 至关重要。
// SSR is automatic - your pages are rendered on the server
export const Route = createFileRoute('/about')({
component: AboutPage,
})对于不需要 SSR 的路由,你可以有选择地禁用它。但要注意,这可能会影响那些页面的 SEO:
// Only disable SSR for pages that don't need SEO
export const Route = createFileRoute('/dashboard')({
ssr: false, // Dashboard doesn't need to be indexed
component: DashboardPage,
})更多细节见选择性 SSR指南。
静态预渲染
对于不频繁变化的内容,静态预渲染在构建时生成 HTML,以获得最佳性能:
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
export default defineConfig({
plugins: [
tanstackStart({
prerender: {
enabled: true,
crawlLinks: true,
},
}),
],
})预渲染的页面加载更快,也更易爬取。配置选项见静态预渲染指南。
站点地图(Sitemaps)
内置站点地图生成
当你启用带链接爬取的预渲染时,TanStack Start 可以自动生成站点地图:
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
export default defineConfig({
plugins: [
tanstackStart({
prerender: {
enabled: true,
crawlLinks: true, // Discovers all linkable pages
},
sitemap: {
enabled: true,
host: 'https://myapp.com',
},
}),
],
})站点地图在构建时通过爬取路由中所有可发现的页面生成。这是静态或大部分静态站点的推荐做法。
静态站点地图
对于简单的站点,你也可以在 public 目录中放置一个静态的 sitemap.xml 文件:
<!-- public/sitemap.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://myapp.com/</loc>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://myapp.com/about</loc>
<changefreq>monthly</changefreq>
</url>
</urlset>当你的站点结构已知且不常变化时,这种方式很有效。
动态站点地图
对于有动态内容、无法在构建时发现的站点,你可以用服务器路由创建动态站点地图。可以考虑在你的 CDN 上缓存它以提升性能:
// src/routes/sitemap[.]xml.ts
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/sitemap.xml')({
server: {
handlers: {
GET: async () => {
const posts = await fetchAllPosts()
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://myapp.com/</loc>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
${posts
.map(
(post) => `
<url>
<loc>https://myapp.com/posts/${post.id}</loc>
<lastmod>${post.updatedAt}</lastmod>
<changefreq>weekly</changefreq>
</url>`,
)
.join('')}
</urlset>`
return new Response(sitemap, {
headers: {
'Content-Type': 'application/xml',
},
})
},
},
},
})robots.txt
静态 robots.txt
最简单的方式是在 public 目录中放置一个静态的 robots.txt 文件:
// public/robots.txt
User-agent: *
Allow: /
Sitemap: https://myapp.com/sitemap.xml这个文件会在 /robots.txt 自动被提供。这是大多数站点最常见的做法。
动态 robots.txt
对于更复杂的场景(比如每个环境不同的规则),你可以用服务器路由创建 robots.txt 文件:
// src/routes/robots[.]txt.ts
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/robots.txt')({
server: {
handlers: {
GET: async () => {
const robots = `User-agent: *
Allow: /
Sitemap: https://myapp.com/sitemap.xml`
return new Response(robots, {
headers: {
'Content-Type': 'text/plain',
},
})
},
},
},
})最佳实践
性能很重要
页面速度是一个排名因素。TanStack Start 在这些方面提供帮助:
- 自动代码分割——只为每个页面加载需要的 JavaScript
- 流式 SSR——立即开始向浏览器发送 HTML
- 预加载——在用户导航之前预取路由
内容为王
技术 SEO 只是拼图的一块。最重要的因素是:
- 优质内容——创建对用户有价值的内容
- 清晰的站点结构——逻辑地组织你的路由
- 有描述性的 URL——使用有意义的路径段(
/posts/my-great-article而不是/posts/123) - 内部链接——帮助用户和爬虫发现你的内容
测试你的实现
用这些工具验证你的 SEO 实现:
- Google Search Console——监控索引和搜索表现
- Google Rich Results Test——验证结构化数据
- Open Graph Debugger——预览社交分享卡片
- 浏览器 DevTools——检查渲染后的 HTML 和 meta 标签
追踪你的排名
要长期监控你的 SEO 表现,我们推荐 Nozzle.io。Nozzle 提供企业级的排名追踪,让你监控无限关键词、追踪 SERP 特性,并分析你与竞争对手的可见度。与传统排名追踪器不同,Nozzle 为每个查询存储完整的 SERP,给你完整的数据来了解你的页面在搜索结果中的表现。