@bliztek/seo
v1.0.1
Published
Zero-dependency SEO metadata generation and JSON-LD structured data components
Readme
@bliztek/seo
Zero-dependency SEO metadata generation and JSON-LD structured data components for Next.js.
Installation
pnpm add @bliztek/seoReact is an optional peer dependency — only required if you use the JSON-LD components.
Entry Points
| Import | What you get |
|---|---|
| @bliztek/seo | Metadata utilities + types |
| @bliztek/seo/json-ld | React JSON-LD components |
Quick Start
Site Config
Create a central config object for your site:
import type { SiteConfig } from "@bliztek/seo";
export const siteConfig: SiteConfig = {
url: "https://example.com",
titleSuffix: "My Site",
defaultImage: "/assets/cover.png",
defaultAuthor: "Jane Doe",
blogPathPrefix: "/blog/post",
icons: {
icon: "/favicon.ico",
},
};Generate Metadata
import { generateSEO } from "@bliztek/seo";
import { siteConfig } from "./seo-config";
export const metadata = generateSEO(
{
title: "About Us",
description: "Learn more about our team.",
url: "/about",
},
siteConfig
);Blog Post Metadata
import { blogPostToSEOProps, generateSEO } from "@bliztek/seo";
import { siteConfig } from "./seo-config";
const seoProps = blogPostToSEOProps(slug, postMetadata, siteConfig);
export const metadata = generateSEO(seoProps, siteConfig);Composable SEO Objects
import { createSEO } from "@bliztek/seo";
const baseSEO = {
website: "https://example.com",
url: "https://example.com",
title: "My Site",
description: "Default description",
image: "/cover.png",
};
const aboutSEO = createSEO(baseSEO, "/about", {
title: "About Us",
description: "Learn more about our team.",
});OG Image URLs
import { buildOgImageUrl } from "@bliztek/seo";
const ogUrl = buildOgImageUrl("My Page Title", {
subtitle: "Category",
type: "blog",
});
// → "/api/og?title=My+Page+Title&subtitle=Category&type=blog"JSON-LD Components
All components render a <script type="application/ld+json"> tag with XSS-safe serialization.
BreadcrumbJsonLd
import { BreadcrumbJsonLd } from "@bliztek/seo/json-ld";
<BreadcrumbJsonLd
items={[
{ name: "Home", url: "https://example.com" },
{ name: "Blog", url: "https://example.com/blog" },
]}
/>;BlogPostingJsonLd
import { BlogPostingJsonLd } from "@bliztek/seo/json-ld";
<BlogPostingJsonLd
title="My Post"
description="Post description"
date="2025-01-15"
slug="my-post"
siteUrl="https://example.com"
blogPathPrefix="/blog/post"
author={{
name: "Jane Doe",
url: "https://janedoe.com",
jobTitle: "Engineer",
}}
publisher={{
name: "My Site",
url: "https://example.com",
logoUrl: "https://example.com/logo.png",
}}
/>;FAQPageJsonLd
import { FAQPageJsonLd } from "@bliztek/seo/json-ld";
<FAQPageJsonLd
faqs={[
{ question: "What is this?", answer: "A great package." },
]}
/>;ServiceJsonLd
import { ServiceJsonLd } from "@bliztek/seo/json-ld";
<ServiceJsonLd
name="Web Development"
description="Custom web applications"
url="https://example.com/services/web"
provider="My Company"
providerUrl="https://example.com"
/>;OrganizationJsonLd
import { OrganizationJsonLd } from "@bliztek/seo/json-ld";
<OrganizationJsonLd
name="My Company"
url="https://example.com"
logo="/logo.png"
description="We build software."
sameAs={["https://twitter.com/mycompany"]}
/>;LocalBusinessJsonLd
import { LocalBusinessJsonLd } from "@bliztek/seo/json-ld";
<LocalBusinessJsonLd
name="My Company"
url="https://example.com"
logo="/logo.png"
description="Local software consultancy."
telephone="+1-555-555-5555"
email="[email protected]"
address={{
locality: "Orlando",
region: "FL",
country: "US",
}}
areaServed={[
{ type: "City", name: "Orlando", containedIn: "Florida" },
]}
sameAs={["https://twitter.com/mycompany"]}
/>;Types
All types are exported from the main entry point:
SiteConfig— Site-wide configuration for metadata generationSEOProps— Input props forgenerateSEO()SEO— Shape used bycreateSEO()FAQ— Question/answer pair forFAQPageJsonLdPostMetadata— Blog post metadata forblogPostToSEOProps()BlogPostingAuthor— Author object forBlogPostingJsonLdBlogPostingPublisher— Publisher object forBlogPostingJsonLd
Security
All JSON-LD components use safeJsonLd() to prevent XSS via </script> injection in structured data. The < character is escaped to \u003c in all serialized output.
License
MIT
