Rechercher

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 Étoiles du dépôt0 Forks du dépôt

Installation

Suivez les instructions du dépôt pour votre agent. Consultez les fichiers et dépendances avant l’installation.

Voir la source ↗Guides

Instructions

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.

Exemples

Consultez les exemples du dépôt source.

Voir la source ↗

Historique source

Date d’indexation
2026-01-20
Mise à jour de l’index
2026-01-26
Branch
main

Les dates concernent ce répertoire. Consultez le dépôt pour l’historique du code.

GitHub ↗

chat Comments (0)

chat_bubble_outline

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