SEO 优化
Next.js 15+ App Router 的 SEO 最佳实践 - 元数据API、站点地图、robots.txt 和结构化数据
SEO 优化
使用 Next.js 15+ 优化技术让你的 ProductReady 应用在搜索引擎中获得更好的排名。学习如何通过现代 Next.js 功能优化元数据、站点地图和结构化数据。
Next.js 15+ SEO: App Router 通过元数据 API 提供内置的 SEO 功能,使 SEO 配置类型安全且简单明了。
快速概览
你将学到:
- ✅ 页面标题和描述的元数据 API
- ✅ Open Graph 和 Twitter Card 优化
- ✅ 数据库驱动内容的动态元数据
- ✅ 站点地图生成
- ✅ Robots.txt 配置
- ✅ 结构化数据(JSON-LD)
- ✅ SEO 性能优化
为什么 SEO 重要:
- 🎯 自然流量 - 无需付费广告即可被发现
- 📈 更好排名 - 在搜索结果中排名更高
- 🔗 社交分享 - Twitter、LinkedIn 等平台的丰富预览
- 💰 降低获客成本 - 免费的营销渠道
元数据 API 基础
静态元数据
为任何页面添加 SEO 元数据的最简单方法:
// src/app/about/page.tsx
import { Metadata } from 'next';
export const metadata: Metadata = {
title: '关于我们 - ProductReady',
description: '了解 ProductReady - 构建 AI 驱动的 SaaS 应用的最快方式。',
keywords: ['AI', 'SaaS', 'Next.js', '模板'],
};
export default function AboutPage() {
return <div>关于页面内容...</div>;
}布局元数据(共享)
在 layout.tsx 中设置默认元数据,应用于所有页面:
// src/app/layout.tsx
import { Metadata } from 'next';
export const metadata: Metadata = {
title: {
default: 'ProductReady - 快速构建 AI 应用',
template: '%s | ProductReady', // 页面标题 | ProductReady
},
description: '构建生产级的、文档健全的、市场材料完备的、AI Agent 装配好的智能应用。',
keywords: ['Next.js', 'AI', 'SaaS', 'TypeScript', 'tRPC', 'Drizzle'],
authors: [{ name: '您的名字' }],
creator: '您的公司',
// 验证令牌
verification: {
google: 'your-google-verification-code',
},
category: 'technology',
};动态元数据
对于数据库驱动的内容(博客文章、产品、用户资料):
// src/app/posts/[slug]/page.tsx
import { Metadata } from 'next';
import { db } from '~/db';
import { posts } from '~/db/schema';
import { eq } from 'drizzle-orm';
type Props = {
params: { slug: string };
};
export async function generateMetadata({ params }: Props): Promise<Metadata> {
// 从数据库获取文章
const post = await db.query.posts.findFirst({
where: eq(posts.slug, params.slug),
});
if (!post) {
return {
title: '文章未找到',
};
}
return {
title: post.title,
description: post.excerpt || post.content.substring(0, 160),
authors: [{ name: post.authorName }],
// Open Graph
openGraph: {
title: post.title,
description: post.excerpt,
type: 'article',
publishedTime: post.createdAt.toISOString(),
authors: [post.authorName],
images: [
{
url: post.coverImage || '/og-default.png',
width: 1200,
height: 630,
alt: post.title,
},
],
},
// Twitter Card
twitter: {
card: 'summary_large_image',
title: post.title,
description: post.excerpt,
images: [post.coverImage || '/og-default.png'],
},
};
}
export default function PostPage({ params }: Props) {
// 页面组件...
}Open Graph 和社交分享
完整的 Open Graph 设置
// src/app/layout.tsx 或特定页面
export const metadata: Metadata = {
openGraph: {
type: 'website',
locale: 'zh_CN',
url: 'https://productready.com',
siteName: 'ProductReady',
title: 'ProductReady - 快速构建 AI 应用',
description: '构建生产级的、文档健全的、市场材料完备的、AI Agent 装配好的智能应用。',
images: [
{
url: 'https://productready.com/og-image.png',
width: 1200,
height: 630,
alt: 'ProductReady - 快速构建 AI 应用',
},
],
},
twitter: {
card: 'summary_large_image',
site: '@yourhandle',
creator: '@yourhandle',
title: 'ProductReady - 快速构建 AI 应用',
description: '构建生产级的、文档健全的、市场材料完备的、AI Agent 装配好的智能应用。',
images: ['https://productready.com/og-image.png'],
},
};站点地图生成
自动站点地图
在应用目录中创建 sitemap.ts:
// src/app/sitemap.ts
import { MetadataRoute } from 'next';
import { db } from '~/db';
import { posts } from '~/db/schema';
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const baseUrl = 'https://productready.com';
// 静态页面
const staticPages: MetadataRoute.Sitemap = [
{
url: baseUrl,
lastModified: new Date(),
changeFrequency: 'daily',
priority: 1,
},
{
url: `${baseUrl}/about`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.8,
},
{
url: `${baseUrl}/pricing`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.9,
},
];
// 从数据库获取动态页面
const allPosts = await db.select({
slug: posts.slug,
updatedAt: posts.updatedAt,
}).from(posts);
const postPages: MetadataRoute.Sitemap = allPosts.map((post) => ({
url: `${baseUrl}/posts/${post.slug}`,
lastModified: post.updatedAt,
changeFrequency: 'weekly',
priority: 0.7,
}));
return [...staticPages, ...postPages];
}生成的站点地图将在 /sitemap.xml 可用
Robots.txt
静态 Robots.txt
// src/app/robots.ts
import { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
return {
rules: [
{
userAgent: '*',
allow: '/',
disallow: ['/api/', '/admin/', '/dashboard/'],
},
],
sitemap: 'https://productready.com/sitemap.xml',
};
}结构化数据(JSON-LD)
为更好的搜索结果添加丰富片段:
组织架构
// src/components/structured-data/organization.tsx
export function OrganizationSchema() {
const schema = {
'@context': 'https://schema.org',
'@type': 'Organization',
name: 'ProductReady',
url: 'https://productready.com',
logo: 'https://productready.com/logo.png',
description: '构建生产级的、文档健全的、市场材料完备的、AI Agent 装配好的智能应用',
sameAs: [
'https://twitter.com/productready',
'https://github.com/productready/productready',
],
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}性能和 Core Web Vitals
SEO 排名考虑页面速度和用户体验:
图片优化
import Image from 'next/image';
// ✅ 好:使用 Next.js Image 自动优化
<Image
src="/hero.png"
alt="ProductReady 仪表板"
width={1200}
height={630}
priority // 用于首屏图片
/>
// ❌ 坏:常规 img 标签
<img src="/hero.png" alt="仪表板" />字体优化
// src/app/layout.tsx
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap', // 防止不可见文本闪烁
variable: '--font-inter',
});SEO 检查清单
启动前
- 设置 Google Search Console
- 添加验证元标签
- 创建
sitemap.xml - 创建
robots.txt - 添加 Open Graph 图片
- 添加结构化数据(JSON-LD)
- 设置规范 URL
- 优化图片(WebP,懒加载)
- 优化字体(next/font)
每个页面
- 唯一、描述性标题(50-60 字符)
- 元描述(150-160 字符)
- Open Graph 元数据
- Twitter Card 元数据
- 规范 URL
- 所有图片的 alt 文本
- 适当的标题层次(H1 → H2 → H3)
下一步
- 监控 - 设置 Google Search Console 和 Analytics
- 优化 - 使用 PageSpeed Insights 改善 Core Web Vitals
- 内容 - 编写高质量、关键词丰富的内容
SEO 是一场马拉松,不是短跑。专注于优质内容、快速性能和良好的用户体验 - 排名会随之而来。