nextjs-dynamic-seo
v1.0.0
Published
Automatic SEO management for Next.js App Router with dynamic metadata generation
Maintainers
Readme
nextjs-dynamic-seo
Automatic SEO management for Next.js App Router with dynamic metadata generation, sitemap, and schema markup.
Features
✅ Dynamic metadata generation from templates
✅ Automatic sitemap generation
✅ Schema.org markup support
✅ Robots.txt generation
✅ Template-based content with variable substitution
✅ Support for dynamic routes
✅ Zero boilerplate - just config file
Installation
npm install nextjs-dynamic-seoQuick Start
1. Create SEO Config
Create seo.config.js in your project root:
export default {
site: {
name: 'My Website',
url: 'https://mywebsite.com',
logo: '/logo.png',
defaultImage: '/og-image.jpg',
},
routes: {
'/': {
title: 'Home | My Website',
description: 'Welcome to my website',
priority: 1.0,
changefreq: 'daily',
},
'/[slug]': {
title: '{title} | My Website',
description: '{description}',
priority: 0.8,
changefreq: 'weekly',
fetchData: async (params) => {
const res = await fetch(`https://api.mysite.com/page/${params.slug}`);
return res.json();
}
},
},
sitemap: {
enabled: true,
fetchRoutes: async () => {
const res = await fetch('https://api.mysite.com/all-routes');
return res.json();
}
}
};2. Initialize in Layout
// app/layout.js
import { initSeo } from 'nextjs-dynamic-seo';
import seoConfig from '../seo.config';
initSeo(seoConfig);
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}3. Use in Pages
// app/[slug]/page.js
import { generateSeoMetadata } from 'nextjs-dynamic-seo';
export async function generateMetadata({ params }) {
return generateSeoMetadata('/[slug]', params);
}
export default function Page({ params }) {
return <div>Page: {params.slug}</div>;
}4. Generate Sitemap
// app/sitemap.js
import { generateSitemap } from 'nextjs-dynamic-seo';
import seoConfig from '../seo.config';
export default async function sitemap() {
return generateSitemap(seoConfig);
}5. Generate Robots.txt
// app/robots.js
import { generateRobots } from 'nextjs-dynamic-seo';
import seoConfig from '../seo.config';
export default function robots() {
return generateRobots(seoConfig);
}Configuration
Site Config
{
site: {
name: 'Site Name', // Required
url: 'https://site.com', // Required
logo: '/logo.png', // Optional
defaultImage: '/og.jpg', // Optional
}
}Route Config
{
routes: {
'/path': {
title: 'Page Title', // Required
description: 'Page description', // Required
keywords: 'keyword1, keyword2', // Optional
priority: 0.8, // Optional (0.0 - 1.0)
changefreq: 'weekly', // Optional
fetchData: async (params) => {...}, // Optional
}
}
}Template Variables
Use {variable} syntax in title/description:
{
title: 'Products in {city}, {state}',
description: 'Find {count} products in {city}'
}Variables are replaced with:
- Route params (e.g.,
params.city) - Data from
fetchDatafunction
Dynamic Data Fetching
{
'/[state]/[city]': {
title: 'Internet in {city}, {state}',
fetchData: async (params) => {
const res = await fetch(`/api/city/${params.city}`);
const data = await res.json();
return {
city: data.cityName,
state: data.stateName,
count: data.providerCount
};
}
}
}API Reference
initSeo(config)
Initialize SEO configuration globally.
import { initSeo } from 'nextjs-dynamic-seo';
initSeo(seoConfig);generateSeoMetadata(route, params)
Generate metadata for a specific route.
export async function generateMetadata({ params }) {
return generateSeoMetadata('/[slug]', params);
}generateSitemap(config)
Generate sitemap array for Next.js.
export default async function sitemap() {
return generateSitemap(seoConfig);
}generateRobots(config)
Generate robots.txt configuration.
export default function robots() {
return generateRobots(seoConfig);
}generateSchema(type, data, config)
Generate Schema.org markup.
import { generateSchema, SchemaMarkup } from 'nextjs-dynamic-seo';
const schema = generateSchema('organization', null, seoConfig);
// In component
<SchemaMarkup schema={schema} />Examples
Basic Static Site
// seo.config.js
export default {
site: {
name: 'My Blog',
url: 'https://myblog.com',
},
routes: {
'/': {
title: 'Home | My Blog',
description: 'Welcome to my blog',
},
'/about': {
title: 'About | My Blog',
description: 'About me',
}
}
};Dynamic E-commerce Site
// seo.config.js
export default {
site: {
name: 'My Store',
url: 'https://mystore.com',
},
routes: {
'/products/[id]': {
title: '{product.name} | My Store',
description: '{product.description}',
fetchData: async ({ id }) => {
const res = await fetch(`https://api.mystore.com/products/${id}`);
return res.json();
}
}
}
};Multi-level Dynamic Routes
// seo.config.js
export default {
site: {
name: 'City Guide',
url: 'https://cityguide.com',
},
routes: {
'/[state]': {
title: 'Cities in {stateName} | City Guide',
description: 'Explore {cityCount} cities in {stateName}',
fetchData: async ({ state }) => {
const res = await fetch(`/api/states/${state}`);
return res.json();
}
},
'/[state]/[city]': {
title: '{cityName}, {stateName} | City Guide',
description: 'Discover {cityName} with {attractionCount} attractions',
fetchData: async ({ state, city }) => {
const res = await fetch(`/api/cities/${state}/${city}`);
return res.json();
}
}
}
};License
MIT
Support
For issues and questions, visit: https://github.com/yourusername/nextjs-dynamic-seo/issues
