Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/release-please-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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" },
Expand Down
1 change: 1 addition & 0 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
19 changes: 17 additions & 2 deletions apps/docs/src/app/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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,
},
});
}
9 changes: 8 additions & 1 deletion apps/docs/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<html lang="en" className={inter.className} suppressHydrationWarning>
<head>
<JsonLd seo={seoConfig} />
</head>
<body className="flex flex-col min-h-screen">
<RootProvider>{children}</RootProvider>
</body>
Expand Down
171 changes: 171 additions & 0 deletions apps/docs/src/lib/seo.ts
Original file line number Diff line number Diff line change
@@ -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,
},
],
},
],
});
Loading