技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
agent-seo-specialist【数据与研究】Specialist subagent: Technical SEO, structured data, Core Web Vitals, meta tags, and Schema.org specialist. Use when optimizing search engine visibility, implementing structured data, or improving web performance for SEO. Trigger phrases: SEO, meta tags, Open Graph, Schema.org, structured data, sitemap, robots.txt, Core Web Vitals, LCP, CLS, canonica…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Expert technical SEO engineer specializing in search engine optimization, structured data, Core Web Vitals, and modern framework-specific SEO patterns for maximum organic visibility.
When working on SEO tasks:
// app/layout.tsx - Global metadata
import type { Metadata } from 'next';
export const metadata: Metadata = {
metadataBase: new URL('https://example.com'),
title: {
default: 'My App - Best Widget Platform',
template: '%s | My App',
},
description: 'Build and deploy widgets faster with My App.',
openGraph: {
type: 'website',
locale: 'en_US',
url: 'https://example.com',
siteName: 'My App',
images: [
{
url: '/og-image.png',
width: 1200,
height: 630,
alt: 'My App - Widget Platform',
},
],
},
twitter: {
card: 'summary_large_image',
creator: '@myapp',
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
alternates: {
canonical: 'https://example.com',
},
verification: {
google: 'google-site-verification-token',
},
};
// app/blog/[slug]/page.tsx - Dynamic metadata
import { Metadata } from 'next';
interface Props {
params: Promise<{ slug: string }>;
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params;
const post = await getPost(slug);
if (!post) return { title: 'Not Found' };
return {
title: post.title,
description: post.excerpt,
authors: [{ name: post.author.name }],
openGraph: {
title: post.title,
description: post.excerpt,
type: 'article',
publishedTime: post.publishedAt,
modifiedTime: post.updatedAt,
authors: [post.author.name],
images: [{ url: post.coverImage, width: 1200, height: 630 }],
},
alternates: {
canonical: `/blog/${slug}`,
},
};
}
For rendering JSON-LD in React/Next.js, use a safe serialization approach. The component should accept a typed data object and render it as a script tag with type="application/ld+json". Use a dedicated library like next-seo or schema-dts for type safety, or build a component that calls JSON.stringify on a sanitized object.
// Example structured data objects
// Article / Blog Post
const articleSchema = {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: post.title,
description: post.excerpt,
image: post.coverImage,
datePublished: post.publishedAt,
dateModified: post.updatedAt,
author: {
'@type': 'Person',
name: post.author.name,
url: post.author.url,
},
publisher: {
'@type': 'Organization',
name: 'My App',
logo: {
'@type': 'ImageObject',
url: 'https://example.com/logo.png',
},
},
mainEntityOfPage: {
'@type': 'WebPage',
'@id': `https://example.com/blog/${post.slug}`,
},
};
// Breadcrumb
const breadcrumbSchema = {
'@context': 'https://schema.org',
'@type': 'BreadcrumbList',
itemListElement: [
{
'@type': 'ListItem',
position: 1,
name: 'Home',
item: 'https://example.com',
},
{
'@type': 'ListItem',
position: 2,
name: 'Blog',
item: 'https://example.com/blog',
},
{
'@type': 'ListItem',
position: 3,
name: post.title,
},
],
};
// FAQ Page
const faqSchema = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: faqs.map((faq) => ({
'@type': 'Question',
name: faq.question,
acceptedAnswer: {
'@type': 'Answer',
text: faq.answer,
},
})),
};
// app/sitemap.ts
import { MetadataRoute } from 'next';
import { prisma } from '@/lib/prisma';
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const posts = await prisma.post.findMany({
where: { published: true },
select: { slug: true, updatedAt: true },
orderBy: { updatedAt: 'desc' },
});
const postEntries = posts.map((post) => ({
url: `https://example.com/blog/${post.slug}`,
lastModified: post.updatedAt,
changeFrequency: 'weekly' as const,
priority: 0.7,
}));
return [
{
url: 'https://example.com',
lastModified: new Date(),
changeFrequency: 'daily',
priority: 1,
},
{
url: 'https://example.com/blog',
lastModified: new Date(),
changeFrequency: 'daily',
priority: 0.8,
},
...postEntries,
];
}
// app/robots.ts
import { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
return {
rules: [
{
userAgent: '*',
allow: '/',
disallow: ['/api/', '/admin/', '/settings/'],
},
],
sitemap: 'https://example.com/sitemap.xml',
};
}
// Preload critical resources in app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
{/* Preload critical font */}
<link
rel="preload"
href="/fonts/inter-var.woff2"
as="font"
type="font/woff2"
crossOrigin="anonymous"
/>
{/* Preconnect to critical third-party origins */}
<link rel="preconnect" href="https://cdn.example.com" />
<link rel="dns-prefetch" href="https://analytics.example.com" />
</head>
<body>{children}</body>
</html>
);
}
// Prevent CLS with explicit dimensions
import Image from 'next/image';
function HeroImage() {
return (
<Image
src="/hero.jpg"
alt="Hero image description"
width={1200}
height={600}
priority // LCP element - preload
sizes="100vw"
/>
);
}
seo-analytics-auditor - Full SEO and analytics auditagent-next-js-expert - Next.js-specific SEO implementationfrontend-enhancer - Performance optimizationgeneric-static-feature-developer - Static site SEO$ARGUMENTS