搜索

PythonReactSEOPDF
GitHub Skill

add-seo

Add SEO meta tags, Open Graph tags, and structured data to routes. Use when optimizing pages for search engines or social sharing.

tech-with-seth☆ 1 仓库 Stars0 仓库 Forks

安装与使用

请根据来源仓库和你的 AI 工具说明安装此技能。先阅读技能文件和依赖要求,再添加到工作流。

查看来源 ↗使用指南

技能说明

Add SEO

Adds SEO optimization including meta tags, Open Graph, Twitter cards, and structured data using React 19 patterns.

When to Use

  • Adding page titles and descriptions
  • Setting up Open Graph for social sharing
  • Adding Twitter card metadata
  • Implementing structured data (JSON-LD)
  • User asks to "add SEO", "add meta tags", or "optimize for search"

React 19 Meta Pattern

Use native JSX tags, NOT meta() export.

import type { Route } from './+types/product';

export default function ProductPage({ loaderData }: Route.ComponentProps) {
    const { product } = loaderData;

    return (
        <>
            {/* Required */}
            <title>{product.name} | Iridium</title>
            <meta name="description" content={product.description} />

            {/* Open Graph */}
            <meta property="og:title" content={product.name} />
            <meta property="og:description" content={product.description} />
            <meta property="og:image" content={product.imageUrl} />
            <meta property="og:type" content="product" />
            <meta property="og:url" content={`https://example.com/products/${product.id}`} />

            {/* Twitter Card */}
            <meta name="twitter:card" content="summary_large_image" />
            <meta name="twitter:title" content={product.name} />
            <meta name="twitter:description" content={product.description} />
            <meta name="twitter:image" content={product.imageUrl} />

            {/* Page content */}
            <Container>
                <h1>{product.name}</h1>
            </Container>
        </>
    );
}

Basic Page SEO

export default function AboutPage() {
    return (
        <>
            <title>About Us | Iridium</title>
            <meta name="description" content="Learn about our mission, team, and values." />
            <meta name="robots" content="index, follow" />

            <Container>
                {/* Page content */}
            </Container>
        </>
    );
}

Dynamic SEO from Loader Data

import type { Route } from './+types/blog-post';

export async function loader({ params }: Route.LoaderArgs) {
    const post = await getPost(params.slug);
    return { post };
}

export default function BlogPost({ loaderData }: Route.ComponentProps) {
    const { post } = loaderData;
    const canonicalUrl = `https://example.com/blog/${post.slug}`;

    return (
        <>
            <title>{post.title} | Blog | Iridium</title>
            <meta name="description" content={post.excerpt} />
            <link rel="canonical" href={canonicalUrl} />

            {/* Article-specific Open Graph */}
            <meta property="og:type" content="article" />
            <meta property="og:title" content={post.title} />
            <meta property="og:description" content={post.excerpt} />
            <meta property="og:image" content={post.featuredImage} />
            <meta property="og:url" content={canonicalUrl} />
            <meta property="article:published_time" content={post.publishedAt} />
            <meta property="article:author" content={post.author.name} />

            <Container>
                <article>
                    <h1>{post.title}</h1>
                    {/* Post content */}
                </article>
            </Container>
        </>
    );
}

Structured Data (JSON-LD)

import type { Route } from './+types/product';

export default function ProductPage({ loaderData }: Route.ComponentProps) {
    const { product } = loaderData;

    const structuredData = {
        '@context': 'https://schema.org',
        '@type': 'Product',
        name: product.name,
        description: product.description,
        image: product.imageUrl,
        offers: {
            '@type': 'Offer',
            price: product.price,
            priceCurrency: 'USD',
            availability: 'https://schema.org/InStock',
        },
    };

    return (
        <>
            <title>{product.name} | Iridium</title>
            <meta name="description" content={product.description} />

            {/* Structured Data */}
            <script
                type="application/ld+json"
                dangerouslySetInnerHTML={{
                    __html: JSON.stringify(structuredData),
                }}
            />

            <Container>
                {/* Product content */}
            </Container>
        </>
    );
}

Organization Structured Data

const organizationData = {
    '@context': 'https://schema.org',
    '@type': 'Organization',
    name: 'Iridium',
    url: 'https://example.com',
    logo: 'https://example.com/logo.png',
    sameAs: [
        'https://twitter.com/iridium',
        'https://github.com/iridium',
    ],
};

Breadcrumb Structured Data

const breadcrumbData = {
    '@context': 'https://schema.org',
    '@type': 'BreadcrumbList',
    itemListElement: [
        {
            '@type': 'ListItem',
            position: 1,
            name: 'Home',
            item: 'https://example.com',
        },
        {
            '@type': 'ListItem',
            position: 2,
            name: 'Products',
            item: 'https://example.com/products',
        },
        {
            '@type': 'ListItem',
            position: 3,
            name: product.name,
            item: `https://example.com/products/${product.id}`,
        },
    ],
};

No-Index Pages

For pages that shouldn't appear in search:

export default function PrivatePage() {
    return (
        <>
            <title>Private Page | Iridium</title>
            <meta name="robots" content="noindex, nofollow" />
            {/* Content */}
        </>
    );
}

SEO Checklist

  • Unique <title> for each page (50-60 chars)
  • <meta name="description"> (150-160 chars)
  • Open Graph tags for social sharing
  • Twitter Card tags
  • Canonical URL for duplicate content
  • Structured data where appropriate
  • No-index on private pages

Anti-Patterns

  • Using meta() export (old pattern)
  • Duplicate titles across pages
  • Missing descriptions
  • Descriptions over 160 characters
  • Missing Open Graph image
  • Using same meta on all pages

Full Reference

See .github/instructions/seo.instructions.md for comprehensive documentation.

使用示例

查看来源仓库中的使用示例与配置说明。

查看来源 ↗

来源历史

收录时间
2026-01-20
索引更新时间
2026-01-26
Branch
main

收录与同步日期属于本站记录。源码修改历史请查看来源仓库。

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!