npm package: @rankworks/next-seo
Description: Next.js SDK for RankWorks SEO platform — fetch content, apply SEO metadata, and validate webhooks
Latest version: 0.2.1

# @rankworks/next-seo

The official Next.js SDK for [RankWorks](https://rankworks.com) — everything you need to manage SEO, structured data, analytics, and content optimization in your Next.js app.

## Why @rankworks/next-seo?

- **Zero-config SEO metadata** — Generate meta tags, Open Graph, and canonical URLs from your RankWorks dashboard with a single function call.
- **Structured data (JSON-LD)** — Render rich snippets for posts and local businesses automatically.
- **Webhook revalidation** — Keep pages fresh with secure, signature-verified revalidation webhooks.
- **Analytics tracking script** — Drop in the RankWorks tracking component with automatic deduplication.
- **Sitemap generation** — Build sitemaps from your published content using Next.js conventions.
- **Managed redirects** — Sync redirects from RankWorks directly into your `next.config.mjs`.
- **Draft preview mode** — Preview unpublished content with token-based authentication.
- **Business profile & reviews** — Display Google Business Profile data and recent reviews with structured data.
- **Keyword rankings** — Access tracked keyword positions, search volume, and trend data.
- **Page analytics** — Pull page-level GA4 metrics to power data-driven features like "Popular Posts."
- **Content scoring** — Score pages for SEO quality (readability, keyword usage, structure) in CI or at build time.
- **Internal link suggestions** — Automatically enhance content with relevant internal links.
- **Image alt text audit** — Find missing or generic alt text across your site with suggested improvements.

## Supported Versions

| Next.js | Status |
|---------|--------|
| 15.x | Fully supported |
| 14.2+ | Fully supported |
| 14.0–14.1 | Not supported |

App Router is the primary target. Pages Router is supported via `toHeadProps`.

## Quick Start

Install the package and add `RANKWORKS_API_KEY` to your `.env.local`:

    npm install @rankworks/next-seo

Then fetch and apply SEO metadata in any page:

```ts
import { createClient, toNextMetadata } from '@rankworks/next-seo';
const client = createClient({ api_key: process.env.RANKWORKS_API_KEY! });
const seo = await client.getPostSEO({ slug: 'my-post' });
export const metadata = toNextMetadata(seo);
```

That's it — your pages now have managed SEO metadata.

## Features at a Glance

| Feature | Method / Export |
|---|---|
| SEO metadata (App Router) | `toNextMetadata(seo)` |
| SEO metadata (Pages Router) | `toHeadProps(seo)` |
| JSON-LD structured data | `<JsonLd data={...} />` |
| Local business structured data | `<LocalBusinessJsonLd profile={...} />` |
| Tracking script | `<RankWorksScript code={...} domain={...} />` |
| Webhook revalidation | `revalidateHandler(options)` |
| Sitemap entries | `client.getSitemapEntries()` |
| Redirects | `client.getRedirects()` / `withRankWorksRedirects(client)` |
| Draft preview | `client.getPostBySlug(slug, { preview: true, previewToken })` |
| Business profile | `client.getBusinessProfile()` |
| Reviews | `client.getReviews({ limit })` |
| Keyword rankings | `client.getKeywordRankings({ domain, limit })` |
| Page analytics | `client.getPageAnalytics({ path, limit })` |
| Content scoring | `client.getContentScore({ url, title, content })` |
| Internal links | `client.getInternalLinks({ content, topic, ... })` |
| Image alt audit | `client.getImageAudit(domain)` |

## Full API Reference

### Client

`createClient(config)` — Create a RankWorks client instance.

| Option | Required | Default | Description |
|---|---|---|---|
| `api_key` | Yes | — | Your RankWorks API key |
| `base_url` | No | `https://api.rankworks.com` | Custom API endpoint (must be `*.rankworks.com` unless `allowCustomBaseUrl` is set) |
| `timeout` | No | `10000` | Request timeout in milliseconds |
| `retries` | No | `1` | Retry count for GET requests on 5xx errors |
| `allowCustomBaseUrl` | No | `false` | Allow non-RankWorks base URLs |

### Content Methods

- `getPostBySlug(slug, options?)` — Fetch a published post by slug (pass `{ preview, previewToken }` for drafts)
- `listPosts(params)` — List posts with cursor-based pagination
- `getPostSEO({ slug })` — Get SEO metadata for a post
- `getSEO({ url, title?, content?, excerpt? })` — Evaluate SEO for any page URL

### SEO & Structured Data

- `toNextMetadata(seo)` — Convert SEO response to Next.js App Router `Metadata`
- `toHeadProps(seo)` — Convert SEO response to Pages Router `<Head>` props
- `<JsonLd data={...} />` — Render JSON-LD structured data
- `<LocalBusinessJsonLd profile={...} type? />` — Render LocalBusiness schema.org JSON-LD

### Site Management

- `getSitemapEntries()` — Get published URLs with last-modified dates for sitemap generation
- `getRedirects()` — Get configured redirects
- `withRankWorksRedirects(client)` — Returns a function compatible with `next.config.mjs` `redirects`
- `toNextRedirects(redirects)` — Transform redirect data to Next.js format

### Tracking & Webhooks

- `<RankWorksScript code? domain? src? nonce? />` — Inject the RankWorks analytics script
- `getScriptConfig()` — Fetch tracking script configuration
- `revalidateHandler(options)` — Factory for a revalidation webhook Route Handler
- `verifyWebhookSignature(headers, body, secret, options?)` — Manually verify webhook signatures

### Analytics & Insights

- `getBusinessProfile()` — Fetch Google Business Profile data
- `getReviews({ limit? })` — Fetch recent reviews with summary stats
- `getKeywordRankings({ domain?, limit? })` — Fetch tracked keyword positions and trends
- `getPageAnalytics({ path?, limit? })` — Fetch page-level GA4 metrics
- `getContentScore({ url?, title?, content? })` — Get SEO content quality score (0–100)
- `getInternalLinks({ content, topic?, title?, website?, maxLinks? })` — Enhance content with internal links
- `getImageAudit(domain)` — Audit images for alt text quality

### Error Classes

- `RankWorksApiError` — Thrown on API errors (properties: `status`, `body`, `url`)
- `RankWorksTimeoutError` — Thrown on timeouts (properties: `url`, `timeoutMs`)

## Documentation

For detailed usage examples, configuration guides, and integration patterns, see the [full documentation](https://docs.rankworks.com/next-seo).

## License

MIT