网站架构技能
加载于:base.md + web-content.md
对于技术网站结构,使其能够被搜索引擎和AI爬虫(GPTBot, ClaudeBot, PerplexityBot)发现。
哲学
内容为王,架构为国。
伟大的内容如果埋没在糟糕的架构中将不会被发现。这项技能涵盖了使您的内容能够被以下发现的技术基础:
- Google, Bing(传统搜索)
- GPTBot(ChatGPT), ClaudeBot, PerplexityBot(AI助手)
- 社交平台(Open Graph, Twitter Cards)
robots.txt
基本模板
# robots.txt
# 默认允许所有爬虫
User-agent: *
Allow: /
Disallow: /api/
Disallow: /admin/
Disallow: /private/
Disallow: /_next/
Disallow: /cdn-cgi/
# 站点地图位置
Sitemap: https://yoursite.com/sitemap.xml
# 爬取延迟(可选 - 小心使用,不是所有爬虫都遵守)
# Crawl-delay: 1
AI Bot配置
# 带AI机器人规则的robots.txt
# === 搜索引擎 ===
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
# === AI助手(允许发现) ===
User-agent: GPTBot
Allow: /
User-agent: ChatGPT-User
Allow: /
User-agent: Claude-Web
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: PerplexityBot
Allow: /
User-agent: Amazonbot
Allow: /
User-agent: anthropic-ai
Allow: /
User-agent: Google-Extended
Allow: /
# === 阻止AI训练(可选 - 引用但不用于训练) ===
# 如果您想被引用但不被用于训练,请取消注释这些
# User-agent: CCBot
# Disallow: /
# User-agent: GPTBot
# Disallow: / # 阻止聊天和训练
# === 阻止刮削器 ===
User-agent: AhrefsBot
Disallow: /
User-agent: SemrushBot
Disallow: /
User-agent: MJ12bot
Disallow: /
# === 默认 ===
User-agent: *
Allow: /
Disallow: /api/
Disallow: /admin/
Disallow: /auth/
Disallow: /private/
Disallow: /*.json$
Disallow: /*?*
Sitemap: https://yoursite.com/sitemap.xml
Next.js robots.txt
// app/robots.ts
import { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
const baseUrl = process.env.NEXT_PUBLIC_URL || 'https://yoursite.com';
return {
rules: [
{
userAgent: '*',
allow: '/',
disallow: ['/api/', '/admin/', '/private/', '/_next/'],
},
{
userAgent: 'GPTBot',
allow: '/',
},
{
userAgent: 'ClaudeBot',
allow: '/',
},
{
userAgent: 'PerplexityBot',
allow: '/',
},
],
sitemap: `${baseUrl}/sitemap.xml`,
};
}
站点地图
XML站点地图模板
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
<url>
<loc>https://yoursite.com/</loc>
<lastmod>2025-01-15</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://yoursite.com/pricing</loc>
<lastmod>2025-01-10</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://yoursite.com/blog/article-slug</loc>
<lastmod>2025-01-12</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
<image:image>
<image:loc>https://yoursite.com/images/article-image.jpg</image:loc>
</image:image>
</url>
</urlset>
Next.js动态站点地图
// app/sitemap.ts
import { MetadataRoute } from 'next';
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const baseUrl = process.env.NEXT_PUBLIC_URL || 'https://yoursite.com';
// 静态页面
const staticPages = [
{ url: '/', priority: 1.0, changeFrequency: 'weekly' as const },
{ url: '/pricing', priority: 0.9, changeFrequency: 'monthly' as const },
{ url: '/about', priority: 0.8, changeFrequency: 'monthly' as const },
{ url: '/contact', priority: 0.7, changeFrequency: 'yearly' as const },
];
// 动态页面(例如,博客文章)
const posts = await getBlogPosts(); // 您的数据获取函数
const blogPages = posts.map((post) => ({
url: `/blog/${post.slug}`,
lastModified: new Date(post.updatedAt),
changeFrequency: 'monthly' as const,
priority: 0.8,
}));
return [
...staticPages.map((page) => ({
url: `${baseUrl}${page.url}`,
lastModified: new Date(),
changeFrequency: page.changeFrequency,
priority: page.priority,
})),
...blogPages.map((page) => ({
url: `${baseUrl}${page.url}`,
lastModified: page.lastModified,
changeFrequency: page.changeFrequency,
priority: page.priority,
})),
];
}
站点地图索引(大型站点)
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://yoursite.com/sitemap-pages.xml</loc>
<lastmod>2025-01-15</lastmod>
</sitemap>
<sitemap>
<loc>https://yoursite.com/sitemap-blog.xml</loc>
<lastmod>2025-01-14</lastmod>
</sitemap>
<sitemap>
<loc>https://yoursite.com/sitemap-products.xml</loc>
<lastmod>2025-01-13</lastmod>
</sitemap>
</sitemapindex>
元标签
基本元标签
<head>
<!-- 基础 -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面标题 | 品牌名称</title>
<meta name="description" content="引人入胜的150-160字符描述,包含关键词和CTA。">
<!-- 规范(防止重复内容) -->
<link rel="canonical" href="https://yoursite.com/current-page">
<!-- 语言 -->
<html lang="en">
<meta name="language" content="English">
<!-- 机器人 -->
<meta name="robots" content="index, follow">
<meta name="googlebot" content="index, follow">
<!-- 作者 -->
<meta name="author" content="作者名称">
<!-- 收藏夹图标 -->
<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/manifest.webmanifest">
</head>
Open Graph(社交分享)
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://yoursite.com/page">
<meta property="og:title" content="页面标题 - 品牌">
<meta property="og:description" content="社交分享的描述(可以更长)。">
<meta property="og:image" content="https://yoursite.com/og-image.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:site_name" content="品牌名称">
<meta property="og:locale" content="en_US">
<!-- 文章特定(博客文章) -->
<meta property="og:type" content="article">
<meta property="article:published_time" content="2025-01-15T08:00:00Z">
<meta property="article:modified_time" content="2025-01-20T10:00:00Z">
<meta property="article:author" content="https://yoursite.com/team/author">
<meta property="article:section" content="Technology">
<meta property="article:tag" content="AI, SEO, Content">
Twitter Cards
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@yourbrand">
<meta name="twitter:creator" content="@authorhandle">
<meta name="twitter:title" content="页面标题">
<meta name="twitter:description" content="Twitter的描述(最多200字符)。">
<meta name="twitter:image" content="https://yoursite.com/twitter-image.jpg">
Next.js元数据
// app/layout.tsx
import { Metadata } from 'next';
export const metadata: Metadata = {
metadataBase: new URL('https://yoursite.com'),
title: {
default: '品牌名称',
template: '%s | 品牌名称',
},
description: '您的默认站点描述。',
keywords: ['keyword1', 'keyword2', 'keyword3'],
authors: [{ name: '品牌名称', url: 'https://yoursite.com' }],
creator: '品牌名称',
publisher: '品牌名称',
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
openGraph: {
type: 'website',
locale: 'en_US',
url: 'https://yoursite.com',
siteName: '品牌名称',
title: '品牌名称',
description: '您的站点描述。',
images: [
{
url: '/og-image.jpg',
width: 1200,
height: 630,
alt: '品牌名称',
},
],
},
twitter: {
card: 'summary_large_image',
site: '@yourbrand',
creator: '@yourbrand',
},
verification: {
google: 'google-verification-code',
yandex: 'yandex-verification-code',
},
};
// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
type: 'article',
publishedTime: post.publishedAt,
modifiedTime: post.updatedAt,
authors: [post.author.name],
images: [post.coverImage],
},
};
}
URL结构
最佳实践
✅ 好的URLs:
/blog/ai-seo-best-practices
/products/pro-plan
/pricing
/about/team
❌ 坏的URLs:
/blog?id=123
/p/12345
/index.php?page=about
/Products/Pro_Plan(不一致的大小写)
URL指南
| 规则 |
示例 |
| 仅小写 |
/blog/my-post 不是 /Blog/My-Post |
| 连字符不是下划线 |
/my-page 不是 /my_page |
| 无尾斜杠 |
/about 不是 /about/ |
| 描述性slugs |
/pricing 不是 /p |
| 无查询参数内容 |
/blog/post-title 不是 /blog?id=123 |
| 最大3-4级深度 |
/blog/category/post |
重定向配置
// next.config.js
module.exports = {
async redirects() {
return [
// 将旧URL重定向到新URL
{
source: '/old-page',
destination: '/new-page',
permanent: true, // 301重定向
},
// 带通配符的重定向
{
source: '/blog/old/:slug',
destination: '/articles/:slug',
permanent: true,
},
// 尾斜杠重定向
{
source: '/:path+/',
destination: '/:path+',
permanent: true,
},
];
},
};
规范URL
实施
<!-- 即使对于主URL,也总是包括规范 -->
<link rel="canonical" href="https://yoursite.com/current-page">
何时使用
✅ 使用规范:
- 每个页面(即使只有版本存在)
- 分页内容(指向第1页或使用rel=prev/next)
- 不改变内容的URL参数(?utm_source=...)
- HTTP与HTTPS(规范到HTTPS)
- www与非www(选择一个,规范到它)
示例:/products?sort=price应该规范到/products
Next.js规范
// 在元数据中自动
export const metadata: Metadata = {
alternates: {
canonical: '/current-page',
},
};
安全头
基本头
// next.config.js
const securityHeaders = [
{
key: 'X-DNS-Prefetch-Control',
value: 'on',
},
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=()',
},
];
module.exports = {
async headers() {
return [
{
source: '/:path*',
headers: securityHeaders,
},
];
},
};
核心网页指标
目标指标
| 指标 |
良好 |
需要改进 |
差 |
| LCP(最大内容绘制) |
≤2.5s |
≤4.0s |
>4.0s |
| INP(交互到下一个绘制) |
≤200ms |
≤500ms |
>500ms |
| CLS(累积布局偏移) |
≤0.1 |
≤0.25 |
>0.25 |
优化清单
## LCP(加载)
- [ ] 优化最大图片(WebP, 适当尺寸)
- [ ] 预加载关键资产
- [ ] 使用CDN静态资产
- [ ] 启用压缩(gzip/brotli)
- [ ] 最小化渲染阻塞资源
## INP(交互性)
- [ ] 最小化JavaScript执行时间
- [ ] 分解长任务
- [ ] 使用Web Workers进行重型计算
- [ ] 优化事件处理程序
- [ ] 延迟加载非关键JS
## CLS(视觉稳定性)
- [ ] 设置图片/视频尺寸
- [ ] 为动态内容保留空间
- [ ] 避免在现有内容上方插入内容
- [ ] 使用变换进行动画
- [ ] 预加载字体
Next.js性能
// 图像优化
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="英雄图片"
width={1200}
height={630}
priority // 预加载LCP
placeholder="blur"
blurDataURL={blurDataUrl}
/>
// 字体优化
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap', // 防止FOIT
});
// 动态导入
import dynamic from 'next/dynamic';
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
loading: () => <Skeleton />,
ssr: false, // 如果需要,仅限客户端
});
内部链接
结构
## 链接架构
首页
├── /pricing (1点击)
├── /features (1点击)
├── /blog (1点击)
│ ├── /blog/category-1 (2点击)
│ │ └── /blog/category-1/post (3点击)
│ └── /blog/category-2 (2点击)
└── /about (1点击)
规则:每个页面在首页的3次点击内
最佳实践
✅ 做:
- 使用描述性锚文本
- 在内容中上下文链接
- 创建主题中心页面
- 在文章末尾链接相关内容
- 使用面包屑导航
❌ 避免:
- “点击这里”作为锚文本
- 孤立页面(无内部链接)
- 每页太多链接(>100)
- 损坏的内部链接
- 重定向链
面包屑
// components/Breadcrumbs.tsx
import Link from 'next/link';
interface BreadcrumbItem {
name: string;
href: string;
}
export function Breadcrumbs({ items }: { items: BreadcrumbItem[] }) {
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'BreadcrumbList',
itemListElement: items.map((item, index) => ({
'@type': 'ListItem',
position: index + 1,
name: item.name,
item: `https://yoursite.com${item.href}`,
})),
};
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<nav aria-label="Breadcrumb">
<ol className="flex gap-2">
{items.map((item, index) => (
<li key={item.href}>
{index > 0 && <span>/</span>}
<Link href={item.href}>{item.name}</Link>
</li>
))}
</ol>
</nav>
</>
);
}
AI爬虫处理
已知AI爬虫
| 机器人 |
用户代理 |
目的 |
| GPTBot |
GPTBot |
ChatGPT网页浏览 |
| ChatGPT-User |
ChatGPT-User |
ChatGPT用户浏览 |
| ClaudeBot |
ClaudeBot |
Claude网页访问 |
| Claude-Web |
Claude-Web |
Claude网页功能 |
| PerplexityBot |
PerplexityBot |
Perplexity搜索 |
| Google-Extended |
Google-Extended |
Gemini/Bard训练 |
| Amazonbot |
Amazonbot |
Alexa/Amazon AI |
| CCBot |
CCBot |
公共爬取(AI训练) |
允许AI发现,阻止训练(可选)
# robots.txt
# 允许GPTBot用于ChatGPT浏览
User-agent: GPTBot
Allow: /
# 阻止CCBot(用于训练数据集)
User-agent: CCBot
Disallow: /
# 阻止Google AI训练,允许搜索
User-agent: Google-Extended
Disallow: /
AI特定元标签
<!-- 阻止AI训练但允许索引 -->
<meta name="robots" content="index, follow, max-image-preview:large">
<!-- 退出AI训练(提议标准) -->
<meta name="ai-training" content="disallow">
结构化数据放置
在哪里添加模式
<!-- 选项1:在<head>中使用JSON-LD(推荐) -->
<head>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "您的公司"
}
</script>
</head>
<!-- 选项2:在</body>关闭前 -->
<body>
<!-- 页面内容 -->
<script type="application/ld+json">
{ "@context": "https://schema.org", ... }
</script>
</body>
每页多个模式
<head>
<!-- 组织(站点范围) -->
<script type="application/ld+json">
{ "@context": "https://schema.org", "@type": "Organization", ... }
</script>
<!-- BreadcrumbList(导航) -->
<script type="application/ld+json">
{ "@context": "https://schema.org", "@type": "BreadcrumbList", ... }
</script>
<!-- 文章(页面特定) -->
<script type="application/ld+json">
{ "@context": "https://schema.org", "@type": "Article", ... }
</script>
<!-- FAQPage(如果存在FAQ部分) -->
<script type="application/ld+json">
{ "@context": "https://schema.org", "@type": "FAQPage", ... }
</script>
</head>
项目结构
project/
├── public/
│ ├── robots.txt # 或动态生成
│ ├── sitemap.xml # 或动态生成
│ ├── favicon.ico
│ ├── icon.svg
│ ├── apple-touch-icon.png
│ ├── og-image.jpg # 默认OG图片(1200x630)
│ └── manifest.webmanifest
├── app/
│ ├── layout.tsx # 全局元数据
│ ├── robots.ts # 动态robots.txt
│ ├── sitemap.ts # 动态站点地图
│ └── [page]/
│ └── page.tsx # 页面特定元数据
├── components/
│ ├── SchemaMarkup.tsx
│ ├── Breadcrumbs.tsx
│ └── MetaTags.tsx
└── lib/
├── schema.ts # 模式生成器
└── seo.ts # SEO工具
验证和提交
搜索控制台设置
# 验证所有权方法
1. HTML文件上传(google*.html到public/)
2. Meta标签(添加到<head>)
3. DNS TXT记录
4. Google Analytics(如果已安装)
提交站点地图
1. Google搜索控制台
- 站点地图 → 添加新站点地图 → yoursite.com/sitemap.xml
2. Bing网站管理员工具
- 站点地图 → 提交站点地图
3. Yandex网站管理员(如果相关)
- 索引 → 站点地图文件
清单
## 技术SEO清单
### robots.txt
- [ ] 允许搜索引擎
- [ ] 允许AI机器人(GPTBot, ClaudeBot, PerplexityBot)
- [ ] 阻止admin/private区域
- [ ] 包含站点地图引用
- [ ] 使用Google的robots.txt测试器测试
### 站点地图
- [ ] 包含所有可索引页面
- [ ] 排除noindex页面
- [ ] 包含lastmod日期
- [ ] 提交给搜索控制台
- [ ] 在内容更改时自动更新
### 元标签
- [ ] 每个页面都有独特的标题(50-60字符)
- [ ] 每个页面都有独特的描述(150-160字符)
- [ ] 每个页面都有规范URL
- [ ] Open Graph标签
- [ ] Twitter Card标签
### URL结构
- [ ] 小写,连字符
- [ ] 描述性slugs
- [ ] 无查询参数内容
- [ ] 移动内容的301重定向
- [ ] 无损坏链接
### 性能
- [ ] LCP < 2.5s
- [ ] INP < 200ms
- [ ] CLS < 0.1
- [ ] 启用HTTPS
- [ ] 配置安全头
### 结构化数据
- [ ] 组织模式(首页)
- [ ] BreadcrumbList(所有页面)
- [ ] 文章模式(博客文章)
- [ ] FAQ模式(FAQ部分)
- [ ] 使用Rich Results Test验证
快速参考
文件清单
public/
├── robots.txt ✓ 必需
├── sitemap.xml ✓ 必需
├── favicon.ico ✓ 必需
├── og-image.jpg ✓ 必需(1200x630)
└── manifest.json ○ 推荐
元标签长度
| 标签 |
长度 |
| 标题 |
50-60个字符 |
| 描述 |
150-160个字符 |
| OG标题 |
60-90个字符 |
| OG描述 |
200个字符 |
| Twitter描述 |
200个字符 |
图片尺寸
| 图片 |
尺寸 |
| OG图片 |
1200 x 630 |
| Twitter图片 |
1200 x 628 |
| 收藏夹图标 |
32 x 32 |
| Apple Touch图标 |
180 x 180 |