@ripp/seo-head
v1.0.0
Published
TypeScript library for managing SEO meta tags in the document head with automatic platform-specific tag mapping.
Readme
@ripp/seo-head
A Zero-Dependency, SSR-friendly, TypeScript library for managing SEO meta tags. Automatically maps standard SEO keys to platform-specific tags (Open Graph, Twitter/X, etc.).
Also see the Playground UI and UI Quick Start
Installation
npm install @ripp/seo-headQuick Start
import { SeoHead } from "@ripp/seo-head";
// Initialize once with site defaults
const seoHead = new SeoHead({
defaults: {
siteName: "My Site",
robots: "index, follow",
},
});
// Update tags as you navigate
seoHead.update({
title: "Home Page",
description: "Welcome to my awesome page",
canonical: "https://example.com/",
image: "https://example.com/og-image.jpg",
});That's it! The library automatically creates and updates <meta>, <link>, and <title> tags for:
- Standard SEO (title, description, canonical)
- Open Graph (Facebook, LinkedIn)
- Twitter/X Cards
- And more...
API Methods
// Get current SEO context
const current = seoHead.getCurrent();
// Reset to defaults (useful for navigation)
seoHead.reset();
// Clear all SEO tags
seoHead.clear();
// Clear specific key
seoHead.clearKey('title');
// Inspect current state (for debugging)
const { context, tags } = seoHead.inspect();Advanced Features
Title Templates
// String template
const seoHead = new SeoHead({
titleTemplate: '%s | My Site',
});
seoHead.update({ title: 'Home' }); // → "Home | My Site"
// Functional template
const seoHead = new SeoHead({
titleTemplate: (title, context) => {
return context.type === 'article'
? `${title} - Blog`
: `${title} | Site`;
},
});URL Pattern Matching
Match routes dynamically using glob patterns or RegExp:
const seoHead = new SeoHead({
// Exact match (backward compatible)
urlMapping: {
'/about': { type: 'website' },
},
// Pattern matching
urlPatterns: [
{ pattern: '/blog/*', context: { type: 'article' } },
{ pattern: /^\/user\/\d+$/, context: { type: 'profile' } },
],
});Validation & Diagnostics
const seoHead = new SeoHead({
validate: true, // Enable all validations
onValidationWarning: (warning) => {
console.warn(`SEO Issue: ${warning.key}`, warning.message);
},
});
// Or enable specific validations
const seoHead = new SeoHead({
validate: {
title: true,
description: true,
images: false,
canonical: false,
},
});Validates:
- Title length (10-60 chars recommended)
- Description length (50-160 chars recommended)
- Missing images on articles
- Missing alt text on images
- Missing canonical on articles
PWA & Performance Tags
seoHead.update({
// PWA
themeColor: '#00695c',
manifestUrl: '/manifest.json',
appleTouchIcon: '/apple-touch-icon.png',
appleStatusBarStyle: 'black-translucent',
// Performance
preconnect: ['https://fonts.googleapis.com'],
dnsPrefetch: ['https://fonts.gstatic.com'],
preload: [
{ href: '/fonts/main.woff2', as: 'font', type: 'font/woff2', crossorigin: 'anonymous' },
],
});Event Callbacks
const seoHead = new SeoHead({
onUpdate: (context) => {
console.log('SEO updated:', context);
},
onTagsChanged: ({ added, removed, updated }) => {
console.log('Tags changed:', { added, removed, updated });
},
});JSON-LD Structured Data
seoHead.update({
title: "Article Title",
jsonLdScripts: [
{
"@context": "https://schema.org",
"@type": "Article",
headline: "Article Title",
datePublished: "2024-01-01",
},
],
});Custom Tag Mappings
const seoHead = new SeoHead({
tagMapping: {
customKey: [
{
tag: "meta",
selector: 'meta[name="custom-key"]',
attrs: { name: "custom-key", content: (value) => value },
},
],
},
});Fallback to Existing DOM Elements
const seoHead = new SeoHead({
fallbackTitle: true, // Use existing <title> if no title provided
fallbackDescription: true, // Use existing meta description
fallbackIcon: true, // Use existing favicon
});Features
- Automatic tag mapping: One object updates multiple platform-specific tags (OG, X/Twitter, etc.)
- Title templates: Format titles consistently with templates or functions
- URL pattern matching: Dynamic route-based SEO with glob patterns or RegExp
- Validation: Built-in SEO best practice validation with warnings
- PWA support: Theme colors, manifest, and Apple-specific tags
- Performance optimization: Preconnect, DNS prefetch, and preload tags
- Event callbacks: React to SEO updates with custom handlers
- JSON-LD support: Built-in structured data handling
- API methods: Get, reset, clear, and inspect SEO state
- Lazy loading: Elements created only when needed
- Memory efficient: Cleans up unused references automatically
- Type-safe: Full TypeScript support with comprehensive types
Use Cases
Single Page Applications (SPAs)
Update SEO tags dynamically as users navigate between routes without page reloads.
// React Router example
router.subscribe((route) => {
seoHead.update({
title: route.meta.title,
description: route.meta.description,
canonical: `https://example.com${route.path}`,
});
});Server-Side Rendering (SSR)
Set SEO tags during server-side rendering for optimal initial page load and crawler support.
// Next.js, Remix, or similar
export async function loader() {
const data = await fetchPageData();
seoHead.update({
title: data.title,
description: data.description,
image: data.ogImage,
});
return { data };
}Content Management Systems
Manage SEO for dynamic content like blog posts, products, or articles with consistent tag generation.
// Blog post example
function renderPost(post) {
seoHead.update({
title: post.title,
description: post.excerpt,
type: "article",
contentAuthor: post.author.name,
contentPublishedAt: post.publishedAt,
jsonLdScripts: [{
"@context": "https://schema.org",
"@type": "BlogPosting",
headline: post.title,
datePublished: post.publishedAt,
}],
});
}