Skip to content

Commit 73709f2

Browse files
committed
docs(seo): metadataBase, OG/Twitter, JSON-LD, per-page canonical+description, sitemap, robots, manifest, llms.txt + dynamic llms-full.txt
1 parent 82363ce commit 73709f2

26 files changed

Lines changed: 411 additions & 7 deletions

docs/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ node_modules/
33
out/
44
next-env.d.ts
55
.DS_Store
6+
7+
# auto-generated by prebuild (scripts/gen-llms-full.mjs)
8+
public/llms-full.txt

docs/app/[[...mdxPath]]/page.jsx

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
import { generateStaticParamsFor, importPage } from 'nextra/pages'
22
import { useMDXComponents as getMDXComponents } from '../../mdx-components'
33

4+
const SITE_URL = process.env.DOCS_SITE_URL ?? 'https://zeative.github.io/zaileys'
5+
const OG_IMAGE = 'https://repository-images.githubusercontent.com/982777390/83fdf9a5-8357-4a53-ade6-883355d77051'
6+
47
export const generateStaticParams = generateStaticParamsFor('mdxPath')
58

9+
const pageUrl = (mdxPath) => {
10+
const slug = (mdxPath ?? []).join('/')
11+
return slug ? `${SITE_URL}/${slug}` : SITE_URL
12+
}
13+
14+
const titleText = (metadata) => {
15+
const t = metadata?.title
16+
if (typeof t === 'string') return t
17+
if (t && typeof t === 'object') return t.absolute ?? t.default ?? 'Zaileys'
18+
return 'Zaileys'
19+
}
20+
621
export async function generateMetadata(props) {
722
const params = await props.params
823
const { metadata } = await importPage(params.mdxPath)
9-
return metadata
24+
const url = pageUrl(params.mdxPath)
25+
return {
26+
...metadata,
27+
alternates: { ...metadata?.alternates, canonical: url },
28+
openGraph: { ...metadata?.openGraph, url, type: 'article', images: [{ url: OG_IMAGE, width: 1280, height: 640, alt: 'Zaileys' }] },
29+
twitter: { ...metadata?.twitter, card: 'summary_large_image', images: [OG_IMAGE] },
30+
}
1031
}
1132

1233
const Wrapper = getMDXComponents().wrapper
@@ -15,9 +36,44 @@ export default async function Page(props) {
1536
const params = await props.params
1637
const result = await importPage(params.mdxPath)
1738
const { default: MDXContent, toc, metadata, sourceCode } = result
39+
const url = pageUrl(params.mdxPath)
40+
const name = titleText(metadata)
41+
const isHome = !(params.mdxPath ?? []).length
42+
43+
const jsonLd = {
44+
'@context': 'https://schema.org',
45+
'@graph': [
46+
{
47+
'@type': 'TechArticle',
48+
'@id': `${url}#article`,
49+
headline: name,
50+
name,
51+
description: metadata?.description,
52+
url,
53+
inLanguage: 'en',
54+
isPartOf: { '@id': `${SITE_URL}/#website` },
55+
publisher: { '@id': `${SITE_URL}/#org` },
56+
mainEntityOfPage: { '@type': 'WebPage', '@id': url },
57+
},
58+
{
59+
'@type': 'BreadcrumbList',
60+
'@id': `${url}#breadcrumb`,
61+
itemListElement: isHome
62+
? [{ '@type': 'ListItem', position: 1, name: 'Home', item: SITE_URL }]
63+
: [
64+
{ '@type': 'ListItem', position: 1, name: 'Docs', item: SITE_URL },
65+
{ '@type': 'ListItem', position: 2, name, item: url },
66+
],
67+
},
68+
],
69+
}
70+
1871
return (
19-
<Wrapper toc={toc} metadata={metadata} sourceCode={sourceCode}>
20-
<MDXContent {...props} params={params} />
21-
</Wrapper>
72+
<>
73+
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
74+
<Wrapper toc={toc} metadata={metadata} sourceCode={sourceCode}>
75+
<MDXContent {...props} params={params} />
76+
</Wrapper>
77+
</>
2278
)
2379
}

docs/app/layout.jsx

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,115 @@ import 'nextra-theme-docs/style.css'
55

66
const GA_ID = 'G-B76YYS1K85'
77
const basePath = process.env.DOCS_BASE_PATH ?? '/zaileys'
8+
const SITE_URL = process.env.DOCS_SITE_URL ?? 'https://zeative.github.io/zaileys'
89
const logoSrc = `${basePath}/zaileys-clean.png`
10+
const ogImage = 'https://repository-images.githubusercontent.com/982777390/83fdf9a5-8357-4a53-ade6-883355d77051'
11+
const logoUrl = `${SITE_URL}/zaileys-clean.png`
12+
13+
const DESCRIPTION =
14+
'Zaileys is a type-safe, batteries-included WhatsApp bot framework for Node.js and TypeScript built on Baileys — send messages, interactive buttons, AIRich markdown, run commands, broadcast, and persist sessions with pluggable storage.'
915

1016
export const metadata = {
17+
metadataBase: new URL(SITE_URL),
1118
title: {
12-
default: 'Zaileys — Simplified WhatsApp API',
19+
default: 'Zaileys — Simplified WhatsApp API for Node.js & TypeScript',
1320
template: '%s — Zaileys',
1421
},
15-
description: 'Type-safe, batteries-included WhatsApp bot framework for Node.js / TypeScript built on Baileys.',
16-
icons: { icon: logoSrc, apple: logoSrc },
22+
description: DESCRIPTION,
23+
applicationName: 'Zaileys',
24+
generator: 'Nextra',
25+
authors: [{ name: 'zaadevofc', url: 'https://github.com/zeative' }],
26+
creator: 'zaadevofc',
27+
publisher: 'Zeative Labs',
28+
category: 'technology',
29+
keywords: [
30+
'zaileys',
31+
'whatsapp',
32+
'whatsapp api',
33+
'whatsapp bot',
34+
'baileys',
35+
'whatsapp typescript',
36+
'whatsapp nodejs',
37+
'whatsapp library',
38+
'whatsapp automation',
39+
'whatsapp framework',
40+
'multi-device whatsapp',
41+
],
42+
icons: { icon: logoSrc, apple: logoSrc, shortcut: logoSrc },
43+
manifest: `${basePath}/manifest.webmanifest`,
44+
alternates: { canonical: SITE_URL },
45+
openGraph: {
46+
type: 'website',
47+
locale: 'en_US',
48+
url: SITE_URL,
49+
siteName: 'Zaileys',
50+
title: 'Zaileys — Simplified WhatsApp API for Node.js & TypeScript',
51+
description: DESCRIPTION,
52+
images: [{ url: ogImage, width: 1280, height: 640, alt: 'Zaileys — Simplified WhatsApp API' }],
53+
},
54+
twitter: {
55+
card: 'summary_large_image',
56+
title: 'Zaileys — Simplified WhatsApp API for Node.js & TypeScript',
57+
description: DESCRIPTION,
58+
images: [ogImage],
59+
},
60+
robots: {
61+
index: true,
62+
follow: true,
63+
googleBot: {
64+
index: true,
65+
follow: true,
66+
'max-image-preview': 'large',
67+
'max-snippet': -1,
68+
'max-video-preview': -1,
69+
},
70+
},
1771
verification: {
1872
google: 'k0WKK9pKRwONXog26MOpUJG9e3FNniwBf0SaR9OD4pw',
1973
},
2074
}
2175

76+
const jsonLd = {
77+
'@context': 'https://schema.org',
78+
'@graph': [
79+
{
80+
'@type': 'Organization',
81+
'@id': `${SITE_URL}/#org`,
82+
name: 'Zaileys',
83+
url: SITE_URL,
84+
logo: logoUrl,
85+
sameAs: [
86+
'https://github.com/zeative/zaileys',
87+
'https://discord.gg/KBHhTTVUc5',
88+
'https://www.npmjs.com/package/zaileys',
89+
],
90+
},
91+
{
92+
'@type': 'WebSite',
93+
'@id': `${SITE_URL}/#website`,
94+
url: SITE_URL,
95+
name: 'Zaileys',
96+
description: DESCRIPTION,
97+
publisher: { '@id': `${SITE_URL}/#org` },
98+
inLanguage: 'en',
99+
},
100+
{
101+
'@type': 'SoftwareApplication',
102+
'@id': `${SITE_URL}/#software`,
103+
name: 'Zaileys',
104+
description: DESCRIPTION,
105+
applicationCategory: 'DeveloperApplication',
106+
operatingSystem: 'Node.js, Bun, Deno',
107+
programmingLanguage: 'TypeScript',
108+
url: SITE_URL,
109+
downloadUrl: 'https://www.npmjs.com/package/zaileys',
110+
license: 'https://github.com/zeative/zaileys/blob/main/LICENSE',
111+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' },
112+
publisher: { '@id': `${SITE_URL}/#org` },
113+
},
114+
],
115+
}
116+
22117
const navbar = (
23118
<Navbar
24119
logo={
@@ -57,6 +152,7 @@ export default async function RootLayout({ children }) {
57152
/>
58153
</Head>
59154
<body>
155+
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
60156
<Layout
61157
navbar={navbar}
62158
footer={footer}

docs/app/manifest.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { MetadataRoute } from 'next'
2+
3+
const basePath = process.env.DOCS_BASE_PATH ?? '/zaileys'
4+
5+
export const dynamic = 'force-static'
6+
7+
export default function manifest(): MetadataRoute.Manifest {
8+
return {
9+
name: 'Zaileys — Simplified WhatsApp API',
10+
short_name: 'Zaileys',
11+
description:
12+
'Type-safe, batteries-included WhatsApp bot framework for Node.js and TypeScript built on Baileys.',
13+
start_url: `${basePath}/`,
14+
scope: `${basePath}/`,
15+
display: 'standalone',
16+
background_color: '#0a0a0a',
17+
theme_color: '#0a0a0a',
18+
icons: [
19+
{ src: `${basePath}/zaileys-clean.png`, sizes: '512x512', type: 'image/png', purpose: 'any' },
20+
{ src: `${basePath}/zaileys-clean.png`, sizes: '512x512', type: 'image/png', purpose: 'maskable' },
21+
],
22+
}
23+
}

docs/app/robots.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { MetadataRoute } from 'next'
2+
3+
const SITE_URL = process.env.DOCS_SITE_URL ?? 'https://zeative.github.io/zaileys'
4+
5+
export const dynamic = 'force-static'
6+
7+
export default function robots(): MetadataRoute.Robots {
8+
const aiBots = [
9+
'GPTBot',
10+
'OAI-SearchBot',
11+
'ChatGPT-User',
12+
'ClaudeBot',
13+
'Claude-Web',
14+
'anthropic-ai',
15+
'PerplexityBot',
16+
'Google-Extended',
17+
'CCBot',
18+
'Applebot-Extended',
19+
'cohere-ai',
20+
'Bytespider',
21+
]
22+
return {
23+
rules: [
24+
{ userAgent: '*', allow: '/' },
25+
...aiBots.map((userAgent) => ({ userAgent, allow: '/' })),
26+
],
27+
sitemap: `${SITE_URL}/sitemap.xml`,
28+
host: SITE_URL,
29+
}
30+
}

docs/app/sitemap.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import type { MetadataRoute } from 'next'
2+
3+
const SITE_URL = process.env.DOCS_SITE_URL ?? 'https://zeative.github.io/zaileys'
4+
5+
const PAGES = [
6+
'',
7+
'installation',
8+
'getting-started',
9+
'configuration',
10+
'client',
11+
'events',
12+
'sending-messages',
13+
'media',
14+
'interactive',
15+
'rich-responses',
16+
'commands',
17+
'automation',
18+
'storage',
19+
'error-handling',
20+
'runtimes',
21+
'troubleshooting',
22+
'api-reference',
23+
]
24+
25+
export const dynamic = 'force-static'
26+
27+
export default function sitemap(): MetadataRoute.Sitemap {
28+
const lastModified = new Date()
29+
return PAGES.map((slug) => ({
30+
url: slug ? `${SITE_URL}/${slug}` : SITE_URL,
31+
lastModified,
32+
changeFrequency: slug ? 'weekly' : 'daily',
33+
priority: slug ? (['getting-started', 'installation'].includes(slug) ? 0.9 : 0.8) : 1,
34+
}))
35+
}

docs/content/api-reference.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
description: "Zaileys API reference — every public export grouped by area: Client, auth and message stores, builder, events, commands, automation, domain, media, and errors."
3+
---
4+
15
import { Callout, Tabs } from 'nextra/components'
26

37
# API Reference

docs/content/automation.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
description: "Automate WhatsApp at scale with Zaileys — broadcast to many recipients with rate limiting and progress callbacks, and schedule messages for a future time."
3+
---
4+
15
import { Callout, Tabs, Steps } from 'nextra/components'
26

37
# Broadcast & Schedule

docs/content/client.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
description: "The Zaileys Client: connection lifecycle, autoConnect, send/edit/react/delete/forward, and the group, presence, privacy, newsletter and community namespaces."
3+
---
4+
15
import { Callout, Tabs, Steps } from 'nextra/components'
26

37
# Client & Lifecycle

docs/content/commands.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
description: "Build a command bot with Zaileys — set a commandPrefix, register commands with aliases, parse arguments, and chain middleware with a typed context."
3+
---
4+
15
import { Callout, Tabs, Steps } from 'nextra/components'
26

37
# Commands

0 commit comments

Comments
 (0)