# Frontend Next SEO

> Next.js SEO: generateMetadata, JSON-LD structured data, sitemap, OpenGraph, hreflang alternates, ISR revalidation. Use when adding SEO, metadata, sitemap, or structured data to Next.js pages.

- Skill: `xmuhameed/frontend-next-seo` (Agent Skill)
- Install (CLI): `npx skillmds@latest add xmuhameed/frontend-next-seo`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xmuhameed/frontend-next-seo/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Marketing & Growth
- Author: xmuhameed (https://skillmd.com/u/xmuhameed)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/xmuhameed/frontend-next-seo

---


# SEO

## Per-Page Metadata

```typescript
export async function generateMetadata({ params }): Promise<Metadata> {
  const { locale, productSlug } = await params;
  const product = await getProduct(productSlug);
  const name = locale.includes('ar') ? product.name_ar : product.name_en;
  return {
    title: name,
    description: locale.includes('ar') ? product.metaDescription_ar : product.metaDescription_en,
    openGraph: { type: 'website', images: [getMediaUrl(product.imageUrl)] },
    alternates: {
      canonical: `${BASE_URL}/${locale}/products/${productSlug}`,
      languages: { 'en-ae': '...', 'ar-ae': '...', 'en-gl': '...', 'ar-gl': '...', 'x-default': '...' },
    },
  };
}
```

## Helpers

`lib/seo.ts` — `generateSEOMetadata()`, `generateProductSEO()`, `getKeywords()`

## JSON-LD (PDP)

```tsx
<script type="application/ld+json" dangerouslySetInnerHTML={{
  __html: JSON.stringify({
    '@context': 'https://schema.org',
    '@type': 'Product',
    name, image, offers: { '@type': 'Offer', price, priceCurrency: 'AED' },
  }),
}} />
```

## ISR Revalidation

| Page | revalidate |
|------|------------|
| Homepage | 300s |
| PDP | 900s |
| Server product fetch | 300s |

## Sitemap

`app/sitemap.ts` — `MetadataRoute.Sitemap` with hreflang for all 4 locales.

## Robots

Middleware sets `X-Robots-Tag: noindex` for checkout, auth, profile pages.

## Static Params

```typescript
export async function generateStaticParams() {
  const products = await getAllSlugs();
  return locales.flatMap(locale => products.map(p => ({ locale, productSlug: p.slug })));
}
```

## Env

`NEXT_PUBLIC_BASE_URL`, `GOOGLE_SITE_VERIFICATION`

