Framework Adapters
One SEO document model, multiple framework outputs. Every adapter implements:
interface SEOAdapter<TOutput> {
id: string
toFramework(seo: SEO): TOutput
}
Adapter Matrix
| Framework | Package | Output | Status |
|---|---|---|---|
| Next.js (App Router) | @better-seo/next |
Metadata |
✅ Shipped |
| Next.js (Pages Router) | @better-seo/next |
<NextSeo /> patterns |
✅ Documented |
| React (SPA / Vite) | @better-seo/react |
Helmet props | ✅ Shipped |
| Remix | @better-seo/remix |
meta / links |
Planned |
| Astro | @better-seo/astro |
Frontmatter | Planned |
| Nuxt | @better-seo/nuxt |
useHead bridge |
Planned |
| Vanilla | @better-seo/core |
renderTags() |
✅ Shipped |
Explicit Registration (Production)
import { registerAdapter, seoForFramework } from "@better-seo/core"
import { adapter as nextAdapter } from "@better-seo/next"
registerAdapter("next", nextAdapter)
const metadata = seoForFramework("next", { title: "Home" })
Auto-Registration (Dev Convenience)
import { seo } from "@better-seo/next" // self-registers
export const metadata = seo({ title: "Home" })
Vanilla / Non-Framework
import { createSEO, renderTags } from "@better-seo/core"
const seo = createSEO({ title: "Home" }, config)
const tags = renderTags(seo)
// → [{ kind: "meta", name: "title", content: "Home" }, ...]
Building a Custom Adapter
import type { SEOAdapter, SEO } from "@better-seo/core"
const myAdapter: SEOAdapter<string> = {
id: "my-framework",
toFramework(seo: SEO): string {
return generateHeadTags(seo)
},
}
registerAdapter("my-framework", myAdapter)
See Adding frameworks for the full guide.