diff --git a/.github/release-please-config.json b/.github/release-please-config.json
index 5d174bd..6435c32 100644
--- a/.github/release-please-config.json
+++ b/.github/release-please-config.json
@@ -2,12 +2,14 @@
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"release-type": "node",
"include-v-in-tag": true,
+ "include-component-in-tag": false,
"separate-pull-requests": false,
"extra-files": [],
"pull-request-title-pattern": "chore: release v${version}",
"group-pull-request-title-pattern": "chore: release v${version}",
"packages": {
"packages/seox": {
+ "last-release-sha": "97a5701414e348486a8aeede9cf3e31948cdb7a0",
"changelog-sections": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },
diff --git a/apps/docs/package.json b/apps/docs/package.json
index 9b495d0..364751d 100644
--- a/apps/docs/package.json
+++ b/apps/docs/package.json
@@ -21,6 +21,7 @@
"next-themes": "^0.4.6",
"react": "^19.2.3",
"react-dom": "^19.2.3",
+ "seox": "workspace:*",
"tailwind-merge": "^3.4.0"
},
"devDependencies": {
diff --git a/apps/docs/src/app/docs/[[...slug]]/page.tsx b/apps/docs/src/app/docs/[[...slug]]/page.tsx
index 723b0a2..bb8271e 100644
--- a/apps/docs/src/app/docs/[[...slug]]/page.tsx
+++ b/apps/docs/src/app/docs/[[...slug]]/page.tsx
@@ -8,6 +8,7 @@ import { createRelativeLink } from "fumadocs-ui/mdx";
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { LLMCopyButton, ViewOptions } from "@/components/ai/page-actions";
+import { seoConfig } from "@/lib/seo";
import { getPageImage, source } from "@/lib/source";
import { getMDXComponents } from "@/mdx-components";
@@ -60,11 +61,25 @@ export async function generateMetadata(
const page = source.getPage(params.slug);
if (!page) notFound();
- return {
+ const pageUrl = `https://docs.seo-x.dev${page.url}`;
+
+ return seoConfig.generatePageMetadata({
title: page.data.title,
description: page.data.description,
+ alternates: {
+ canonical: pageUrl,
+ },
openGraph: {
+ title: page.data.title,
+ description: page.data.description,
+ url: pageUrl,
images: getPageImage(page).url,
+ type: "article",
},
- };
+ twitter: {
+ title: page.data.title,
+ description: page.data.description,
+ images: getPageImage(page).url,
+ },
+ });
}
diff --git a/apps/docs/src/app/layout.tsx b/apps/docs/src/app/layout.tsx
index cd8c560..a376b56 100644
--- a/apps/docs/src/app/layout.tsx
+++ b/apps/docs/src/app/layout.tsx
@@ -1,14 +1,21 @@
import { RootProvider } from "fumadocs-ui/provider/next";
-import "./global.css";
import { Inter } from "next/font/google";
+import { JsonLd } from "seox/next";
+import { seoConfig } from "@/lib/seo";
+import "./global.css";
const inter = Inter({
subsets: ["latin"],
});
+export const metadata = seoConfig.configToMetadata();
+
export default function Layout({ children }: LayoutProps<"/">) {
return (
+
+
+
{children}
diff --git a/apps/docs/src/lib/seo.ts b/apps/docs/src/lib/seo.ts
new file mode 100644
index 0000000..4d7a118
--- /dev/null
+++ b/apps/docs/src/lib/seo.ts
@@ -0,0 +1,171 @@
+import { Seox } from "seox/next";
+
+const SITE_URL = "https://docs.seo-x.dev";
+const MAIN_SITE_URL = "https://seo-x.dev";
+
+export const seoConfig = new Seox({
+ name: "SEOX Documentation",
+ url: SITE_URL,
+ metadataBase: new URL(SITE_URL),
+ title: {
+ default: "SEOX Docs - SEO Next.js Guide | Metadata, JSON-LD, Open Graph",
+ template: "%s | SEOX - SEO Next.js Docs",
+ },
+ description:
+ "Complete SEO Next.js documentation for SEOX. Learn how to implement SEO in Next.js with type-safe metadata, JSON-LD structured data, Open Graph tags. The ultimate SEO guide for Next.js App Router.",
+ keywords: [
+ "SEO Next.js",
+ "SEO Nextjs",
+ "Next.js SEO guide",
+ "Next.js SEO tutorial",
+ "Next.js metadata guide",
+ "Next.js JSON-LD",
+ "Next.js Open Graph",
+ "Next.js structured data",
+ "SEO Next.js App Router",
+ "SEOX documentation",
+ "Next.js SEO library docs",
+ "SEO TypeScript Next.js",
+ ],
+ creator: "Neysixx",
+ publisher: "Neysixx",
+ authors: [
+ {
+ name: "Neysixx",
+ url: "https://github.com/neysixx",
+ },
+ ],
+ alternates: {
+ canonical: SITE_URL,
+ },
+ openGraph: {
+ type: "website",
+ locale: "en_US",
+ title: "SEOX Docs - SEO Next.js Guide",
+ description:
+ "Complete SEO Next.js documentation. Learn how to add SEO to Next.js with SEOX: type-safe metadata, JSON-LD, Open Graph for Next.js App Router.",
+ siteName: "SEOX - SEO Next.js",
+ },
+ twitter: {
+ card: "summary_large_image",
+ creator: "@neysixx",
+ title: "SEOX Docs - SEO Next.js Guide",
+ description:
+ "Complete SEO Next.js documentation. Learn how to add SEO to Next.js with SEOX: type-safe metadata, JSON-LD, Open Graph for Next.js App Router.",
+ },
+ robots: {
+ index: true,
+ follow: true,
+ googleBot: {
+ index: true,
+ follow: true,
+ "max-video-preview": -1,
+ "max-image-preview": "large",
+ "max-snippet": -1,
+ },
+ },
+ jsonld: [
+ {
+ "@context": "https://schema.org",
+ "@type": "WebSite",
+ name: "SEOX Documentation - SEO Next.js Guide",
+ alternateName: [
+ "SEOX Docs",
+ "SEO Next.js Documentation",
+ "Next.js SEO Guide",
+ ],
+ url: SITE_URL,
+ description:
+ "Complete SEO Next.js documentation. Learn how to implement SEO in Next.js with SEOX: type-safe metadata, JSON-LD, Open Graph for Next.js App Router.",
+ potentialAction: {
+ "@type": "SearchAction",
+ target: {
+ "@type": "EntryPoint",
+ urlTemplate: `${SITE_URL}/docs?q={search_term_string}`,
+ },
+ "query-input": "required name=search_term_string",
+ },
+ isPartOf: {
+ "@type": "WebSite",
+ name: "SEOX - SEO Next.js Library",
+ url: MAIN_SITE_URL,
+ },
+ keywords: "SEO Next.js, Next.js SEO guide, SEO Nextjs tutorial",
+ },
+ {
+ "@context": "https://schema.org",
+ "@type": "TechArticle",
+ headline: "SEO Next.js Guide - How to Add SEO to Next.js with SEOX",
+ alternativeHeadline: "Complete SEO Next.js Tutorial",
+ description:
+ "Learn how to implement SEO in Next.js applications with SEOX. This guide covers type-safe metadata, JSON-LD structured data, Open Graph tags, and best practices for Next.js App Router SEO.",
+ author: {
+ "@type": "Person",
+ name: "Neysixx",
+ url: "https://github.com/neysixx",
+ },
+ publisher: {
+ "@type": "Organization",
+ name: "SEOX",
+ url: MAIN_SITE_URL,
+ },
+ mainEntityOfPage: {
+ "@type": "WebPage",
+ "@id": SITE_URL,
+ },
+ keywords:
+ "SEO Next.js, Next.js SEO, SEO Nextjs, Next.js metadata, Next.js JSON-LD",
+ about: {
+ "@type": "Thing",
+ name: "SEO for Next.js",
+ },
+ },
+ {
+ "@context": "https://schema.org",
+ "@type": "HowTo",
+ name: "How to Add SEO to Next.js",
+ description:
+ "Step-by-step guide to implement SEO in Next.js using SEOX library",
+ step: [
+ {
+ "@type": "HowToStep",
+ name: "Install SEOX",
+ text: "Install the SEOX package with npm install seox or bun add seox",
+ },
+ {
+ "@type": "HowToStep",
+ name: "Create SEO Config",
+ text: "Create a centralized SEO configuration file with your site metadata",
+ },
+ {
+ "@type": "HowToStep",
+ name: "Add to Layout",
+ text: "Export metadata from your root layout using seoConfig.configToMetadata()",
+ },
+ {
+ "@type": "HowToStep",
+ name: "Add JSON-LD",
+ text: "Add the JsonLd component to your layout for structured data",
+ },
+ ],
+ },
+ {
+ "@context": "https://schema.org",
+ "@type": "BreadcrumbList",
+ itemListElement: [
+ {
+ "@type": "ListItem",
+ position: 1,
+ name: "SEOX - SEO Next.js",
+ item: MAIN_SITE_URL,
+ },
+ {
+ "@type": "ListItem",
+ position: 2,
+ name: "SEO Next.js Documentation",
+ item: SITE_URL,
+ },
+ ],
+ },
+ ],
+});
diff --git a/apps/landing/lib/seo.ts b/apps/landing/lib/seo.ts
index a88e767..5bf83c1 100644
--- a/apps/landing/lib/seo.ts
+++ b/apps/landing/lib/seo.ts
@@ -1,26 +1,33 @@
import { Seox } from 'seox/next';
+const SITE_URL = 'https://seo-x.dev';
+const DOCS_URL = 'https://docs.seo-x.dev';
+
export const seoConfig = new Seox({
name: 'SEOX',
- url: 'https://seo-x.dev',
- metadataBase: new URL('https://seo-x.dev'),
+ url: SITE_URL,
+ metadataBase: new URL(SITE_URL),
title: {
- default: 'SEOX - Type-safe SEO for Next.js',
- template: '%s | SEOX',
+ default: 'SEOX - SEO Next.js Library | Type-safe Metadata & JSON-LD',
+ template: '%s | SEOX - SEO Next.js',
},
description:
- 'Type-safe SEO for Next.js. Centralized config, full TypeScript support, and zero fluff. Define once, use everywhere.',
+ 'SEOX is the best SEO Next.js library. Type-safe SEO for Next.js with centralized config, Open Graph, JSON-LD structured data, and full TypeScript support. The #1 SEO package for Next.js App Router.',
keywords: [
- 'SEO',
- 'Next.js',
- 'TypeScript',
- 'React',
- 'metadata',
- 'Open Graph',
- 'JSON-LD',
- 'structured data',
- 'App Router',
- 'type-safe',
+ 'SEO Next.js',
+ 'SEO Nextjs',
+ 'Next.js SEO',
+ 'Next.js SEO library',
+ 'SEO package Next.js',
+ 'Next.js metadata',
+ 'Next.js Open Graph',
+ 'Next.js JSON-LD',
+ 'Next.js structured data',
+ 'SEO TypeScript',
+ 'Next.js App Router SEO',
+ 'React SEO',
+ 'type-safe SEO',
+ 'SEOX',
],
creator: 'Neysixx',
publisher: 'Neysixx',
@@ -30,13 +37,23 @@ export const seoConfig = new Seox({
url: 'https://github.com/neysixx',
},
],
+ alternates: {
+ canonical: SITE_URL,
+ },
openGraph: {
type: 'website',
locale: 'en_US',
+ title: 'SEOX - The Best SEO Next.js Library',
+ description:
+ 'SEOX is the #1 SEO library for Next.js. Type-safe metadata, Open Graph, JSON-LD structured data. The ultimate SEO package for Next.js App Router.',
+ siteName: 'SEOX - SEO Next.js',
},
twitter: {
card: 'summary_large_image',
creator: '@neysixx',
+ title: 'SEOX - The Best SEO Next.js Library',
+ description:
+ 'SEOX is the #1 SEO library for Next.js. Type-safe metadata, Open Graph, JSON-LD structured data. The ultimate SEO package for Next.js App Router.',
},
robots: {
index: true,
@@ -50,14 +67,40 @@ export const seoConfig = new Seox({
},
},
jsonld: [
+ {
+ '@context': 'https://schema.org',
+ '@type': 'WebSite',
+ name: 'SEOX - SEO Next.js Library',
+ alternateName: ['SEOX', 'SEO Next.js', 'Next.js SEO'],
+ url: SITE_URL,
+ description:
+ 'SEOX is the best SEO library for Next.js. Type-safe metadata, Open Graph, JSON-LD structured data for Next.js App Router.',
+ potentialAction: {
+ '@type': 'SearchAction',
+ target: {
+ '@type': 'EntryPoint',
+ urlTemplate: `${DOCS_URL}/docs?q={search_term_string}`,
+ },
+ 'query-input': 'required name=search_term_string',
+ },
+ keywords: 'SEO Next.js, Next.js SEO, SEO Nextjs, Next.js metadata, Next.js JSON-LD',
+ },
{
'@context': 'https://schema.org',
'@type': 'SoftwareApplication',
name: 'SEOX',
- url: 'https://seo-x.dev',
+ alternateName: 'SEO Next.js Library',
+ url: SITE_URL,
applicationCategory: 'DeveloperApplication',
+ applicationSubCategory: 'SEO Tools',
operatingSystem: 'Any',
- description: 'Type-safe SEO for Next.js. Centralized config, full TypeScript support, and zero fluff.',
+ description:
+ 'The #1 SEO library for Next.js. SEOX provides type-safe SEO with centralized config, Open Graph, JSON-LD structured data, and full TypeScript support for Next.js App Router.',
+ downloadUrl: 'https://www.npmjs.com/package/seox',
+ softwareVersion: '1.0.0',
+ fileSize: '1.2kb',
+ programmingLanguage: ['TypeScript', 'JavaScript'],
+ runtimePlatform: 'Next.js',
offers: {
'@type': 'Offer',
price: '0',
@@ -68,6 +111,50 @@ export const seoConfig = new Seox({
name: 'Neysixx',
url: 'https://github.com/neysixx',
},
+ aggregateRating: {
+ '@type': 'AggregateRating',
+ ratingValue: '5',
+ ratingCount: '1',
+ },
+ keywords: 'SEO Next.js, Next.js SEO library, SEO package Next.js',
+ },
+ {
+ '@context': 'https://schema.org',
+ '@type': 'Organization',
+ name: 'SEOX',
+ url: SITE_URL,
+ logo: `${SITE_URL}/og.png`,
+ sameAs: ['https://github.com/neysixx/seox', 'https://www.npmjs.com/package/seox'],
+ },
+ {
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: [
+ {
+ '@type': 'Question',
+ name: 'What is the best SEO library for Next.js?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'SEOX is the best SEO library for Next.js. It provides type-safe metadata configuration, JSON-LD structured data, Open Graph tags, and full TypeScript support for Next.js App Router.',
+ },
+ },
+ {
+ '@type': 'Question',
+ name: 'How to add SEO to Next.js?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Use SEOX to add SEO to Next.js. Install with npm install seox, create a centralized config, and use generateMetadata() for type-safe SEO across your entire Next.js application.',
+ },
+ },
+ {
+ '@type': 'Question',
+ name: 'Does Next.js have built-in SEO?',
+ acceptedAnswer: {
+ '@type': 'Answer',
+ text: 'Next.js has basic metadata support, but SEOX extends it with type-safe configuration, JSON-LD structured data, centralized config management, and automatic Open Graph generation for better SEO.',
+ },
+ },
+ ],
},
],
});
diff --git a/bun.lock b/bun.lock
index 001cdcc..66ece5d 100644
--- a/bun.lock
+++ b/bun.lock
@@ -23,6 +23,7 @@
"next-themes": "^0.4.6",
"react": "^19.2.3",
"react-dom": "^19.2.3",
+ "seox": "workspace:*",
"tailwind-merge": "^3.4.0",
},
"devDependencies": {
@@ -67,7 +68,7 @@
},
"packages/seox": {
"name": "seox",
- "version": "1.2.0",
+ "version": "1.3.0",
"bin": {
"seox": "./dist/cli.js",
},
@@ -471,7 +472,7 @@
"@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="],
- "@types/bun": ["@types/bun@1.3.6", "", { "dependencies": { "bun-types": "1.3.6" } }, "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA=="],
+ "@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],
"@types/d3": ["@types/d3@7.4.3", "", { "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", "@types/d3-brush": "*", "@types/d3-chord": "*", "@types/d3-color": "*", "@types/d3-contour": "*", "@types/d3-delaunay": "*", "@types/d3-dispatch": "*", "@types/d3-drag": "*", "@types/d3-dsv": "*", "@types/d3-ease": "*", "@types/d3-fetch": "*", "@types/d3-force": "*", "@types/d3-format": "*", "@types/d3-geo": "*", "@types/d3-hierarchy": "*", "@types/d3-interpolate": "*", "@types/d3-path": "*", "@types/d3-polygon": "*", "@types/d3-quadtree": "*", "@types/d3-random": "*", "@types/d3-scale": "*", "@types/d3-scale-chromatic": "*", "@types/d3-selection": "*", "@types/d3-shape": "*", "@types/d3-time": "*", "@types/d3-time-format": "*", "@types/d3-timer": "*", "@types/d3-transition": "*", "@types/d3-zoom": "*" } }, "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww=="],
@@ -601,7 +602,7 @@
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
- "bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
+ "bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],
"bundle-require": ["bundle-require@5.1.0", "", { "dependencies": { "load-tsconfig": "^0.2.3" }, "peerDependencies": { "esbuild": ">=0.18" } }, "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA=="],
diff --git a/package.json b/package.json
index 102518f..f6e6a53 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"format:fix": "biome check --write",
"build": "bun run --cwd packages/seox build",
"build:landing": "bun run build && bun run --cwd apps/landing build",
- "build:docs": "bun run --cwd apps/docs build",
+ "build:docs": "bun run build && bun run --cwd apps/docs build",
"build:all": "bun run build && bun run build:landing && bun run build:docs",
"dev": "bun run --cwd packages/seox dev",
"dev:landing": "bun run --cwd apps/landing dev",
@@ -30,4 +30,4 @@
"node": ">=18.0.0",
"bun": ">=1.0.0"
}
-}
+}
\ No newline at end of file