SEO处理技能Skill seo-handler

SEO处理技能是一个针对Next.js框架的搜索引擎优化管理工具。它专注于站点地图管理、元数据配置、结构化数据生成、服务器端渲染优化和爬虫控制,旨在提升网站在Google、百度等搜索引擎中的排名和可见性。核心功能包括自动生成站点地图、优化OpenGraph标签、注入JSON-LD结构化数据、配置ISR缓存策略以及管理robots.txt文件。适用于前端开发者、SEO工程师和网站管理员,帮助实现技术SEO的最佳实践。

前端开发 0 次安装 2 次浏览 更新于 3/1/2026

name: seo-handler description: 管理SEO、站点地图和元数据,以实现最佳搜索引擎可见性 tools: 读取、写入、编辑 model: 继承

SEO处理技能

此技能确保您的Next.js应用程序针对搜索引擎进行优化。它涵盖站点地图、元数据(OpenGraph)、服务器端渲染(SSR/ISR)、结构化数据(JSON-LD)和robots.txt配置。

核心原则

  1. 站点地图可见性:每个公共页面必须位于src/app/sitemap.ts中。
  2. 元数据继承:在layout.tsx中设置默认值;在page.tsx中覆盖。
  3. 结构化数据:在每个内容页面上使用next-seo组件(JSON-LD)。
  4. 服务器端数据:在服务器上获取内容密集型数据(ISR)以利于SEO。
  5. 机器人控制:使用src/app/robots.ts来引导爬虫。

1. 站点地图管理

文件src/app/sitemap.ts

添加新的公共路由(例如,/features)时,将其添加到staticPages数组中。

const staticPages = [
  "", // 首页
  "/features", // 新页面
  // ...
];

拆分站点地图(大型网站)

如果您拥有超过5万个URL(例如,用户个人资料、产品),请使用generateSitemaps

文件src/app/products/sitemap.ts

import { BASE_URL } from '@/lib/constants';

export async function generateSitemaps() {
  // 获取总数并按批次大小(例如,50,000)划分
  return [{ id: 0 }, { id: 1 }];
}

export default async function sitemap({ id }: { id: { id: number } }) {
  const start = id.id * 50000;
  const products = await getProducts(start, 50000);
  
  return products.map(product => ({
    url: `${BASE_URL}/products/${product.slug}`,
    lastModified: product.updatedAt,
  }));
}

2. 元数据与OpenGraph

基础布局src/app/layout.tsx(或分组布局)定义模板。

export const metadata: Metadata = {
  title: {
    template: "%s | 我的应用",
    default: "我的应用 - 最佳SaaS",
  },
  description: "...",
  openGraph: { ... }, // 默认OG
};

页面级别src/app/blog/[slug]/page.tsx

export async function generateMetadata({ params }): Promise<Metadata> {
  const post = await getPost(params.slug);
  return {
    title: post.title,
    description: post.summary,
    openGraph: {
      images: [post.coverImage], // 覆盖默认值
    },
  };
}

3. 结构化数据(JSON-LD)

主要:Next-SEO组件

使用next-seo组件注入JSON-LD结构化数据。这有助于搜索引擎理解您的内容(文章、产品、常见问题解答等)。

页面组件src/app/blog/[slug]/page.tsx

import { ArticleJsonLd } from "next-seo";

export default function BlogPost({ post }) {
  return (
    <>
      <ArticleJsonLd
        useAppDir
        url={`https://myapp.com/blog/${post.slug}`}
        title={post.title}
        images={[post.image]}
        datePublished={post.date}
        authorName="我的应用"
        description={post.description}
      />
      <article>...</article>
    </>
  );
}

替代方案:原始JSON-LD(脚本标签)

如果特定架构不受next-seo支持,请使用原始脚本标签。如果数据获取是异步的,请用Suspense包装。

import { Suspense } from "react";

export default function Page() {
  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'CustomType',
    name: '自定义名称',
    description: '描述',
  };

  return (
    <section>
      <Suspense fallback={null}>
        <script
          type="application/ld+json"
          dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
        />
      </Suspense>
      {/* 页面内容 */}
    </section>
  );
}

4. 增量静态再生(ISR)

对于依赖数据库内容的内容页面(博客、文档、营销),使用ISR在边缘缓存它们。

页面组件

// src/app/blog/[slug]/page.tsx

// 1. 启用ISR
export const revalidate = 3600; // 每小时重新验证(以秒为单位)
// 或者使用动态参数和generateStaticParams以实现完整的静态导出行为
export const dynamicParams = true; 

export async function generateStaticParams() {
  const posts = await db.query.posts.findMany();
  return posts.map((post) => ({ slug: post.slug }));
}

export default async function BlogPost({ params }) {
  // 2. 在服务器上获取(数据根据revalidate配置缓存)
  const post = await getPost(params.slug); 
  
  return <article>{/* ... */}</article>;
}

5. Robots.txt配置

文件src/app/robots.txt

确保禁止私有路由(/api//app//admin/)以节省爬虫预算。

export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: "*",
      allow: "/",
      disallow: ["/api/", "/app/", "/super-admin/"],
    },
    sitemap: `${process.env.NEXT_PUBLIC_APP_URL}/sitemap.xml`,
  };
}