nextjs-seo-toolkit
βType-safe SEO metadata and JSON-LD generation for Next.js App Routerβ
A TypeScript-first library for generating Next.js Metadata objects and JSON-LD structured data. Centralises all SEO concerns β meta tags, Open Graph, Twitter cards, and schema.org markup β into a clean, type-safe API.
Installation
Requirements
App Router required
Strongly recommended for full type safety
npm install
Install nextjs-seo-toolkit from npm
npm install nextjs-seo-toolkitQuick Start
Add type-safe SEO to your Next.js app in 2 steps
Install the package
Install via npm
npm install nextjs-seo-toolkitπ‘ Tips
- β’Requires Next.js 14+ with App Router
- β’TypeScript 5+ recommended
Generate metadata in your page
Replace inline Metadata objects with generateMetadata() calls
import { generateBlogMetadata } from 'nextjs-seo-toolkit';
export async function generateMetadata({ params }) {
const { slug } = await params;
const post = await getPostBySlug(slug);
return generateBlogMetadata({
title: post.title,
description: post.excerpt,
slug: post.slug,
publishedAt: post.publishedAt,
tags: post.tags.map(t => t.name),
coverImage: post.coverImage,
});
}You're all set! Check out the detailed usage guide below for more advanced features.
Usage Guide
Blog post metadata
Generate article metadata with Open Graph and Twitter card
import { generateBlogMetadata } from 'nextjs-seo-toolkit';
import type { Metadata } from 'next';
export async function generateMetadata(): Promise<Metadata> {
return generateBlogMetadata({
title: 'How I Built a Real-Time Chat App',
description: 'A deep dive into WebSocket architecture with Go.',
slug: 'how-i-built-chat-app',
publishedAt: '2025-01-15T10:00:00Z',
tags: ['go', 'websockets', 'real-time'],
siteUrl: 'https://manishh.in',
});
}JSON-LD structured data
Generate schema.org Article markup for blog posts
import { generateBlogJsonLd } from 'nextjs-seo-toolkit';
export default async function BlogPostPage({ params }) {
const post = await getPostBySlug(await params.slug);
const jsonLd = generateBlogJsonLd(post, 'https://manishh.in');
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<article>{/* post content */}</article>
</>
);
}Examples
Real-world code examples and use cases
Root layout metadata
beginnerSet up root layout metadata with site-level defaults
import { generateRootMetadata } from 'nextjs-seo-toolkit';
export const metadata = generateRootMetadata({
siteName: 'My Portfolio',
siteUrl: 'https://mysite.com',
description: 'Full-stack engineer. Writing about Go and Next.js.',
defaultOgImage: { src: '/og-default.jpg', alt: 'My Portfolio', width: 1200, height: 630 },
twitterHandle: '@myhandle',
});Project page metadata
intermediateMetadata for a project detail page with schema.org SoftwareApplication
import { generateProjectMetadata } from 'nextjs-seo-toolkit';
export async function generateMetadata({ params }) {
const project = await getProjectBySlug(await params.slug);
return generateProjectMetadata({
title: project.title,
description: project.description,
slug: project.slug,
siteUrl: 'https://mysite.com',
techStack: project.techStack.map(t => t.name),
liveUrl: project.liveUrl,
});
}Frequently Asked Questions
2 questions answered
Still have questions?
Check out the source code or open an issue on GitHub
Related Content
Explore related articles, projects, and tools.