From 3f01f488870b11590d8711eebd5a28d29a161b70 Mon Sep 17 00:00:00 2001 From: Joey Meng Date: Thu, 13 Nov 2025 21:59:32 -0500 Subject: [PATCH 1/6] Adding Updates Section --- docs/content/updates/meta.js | 2 + docs/package-lock.json | 32 ++-- docs/source.config.ts | 15 +- docs/src/app/updates/[...slug]/page.tsx | 188 ++++++++++++++++++++++++ docs/src/app/updates/layout.tsx | 15 ++ docs/src/app/updates/page.tsx | 86 +++++++++++ docs/src/components/CustomHeader.tsx | 73 +++++---- docs/src/lib/update-source.ts | 7 + 8 files changed, 377 insertions(+), 41 deletions(-) create mode 100644 docs/content/updates/meta.js create mode 100644 docs/src/app/updates/[...slug]/page.tsx create mode 100644 docs/src/app/updates/layout.tsx create mode 100644 docs/src/app/updates/page.tsx create mode 100644 docs/src/lib/update-source.ts diff --git a/docs/content/updates/meta.js b/docs/content/updates/meta.js new file mode 100644 index 000000000..ce7bc92ae --- /dev/null +++ b/docs/content/updates/meta.js @@ -0,0 +1,2 @@ +export default { +}; \ No newline at end of file diff --git a/docs/package-lock.json b/docs/package-lock.json index 2ef0ab2fc..62bfd69d5 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -109,6 +109,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -1856,17 +1857,6 @@ "node": ">=12.4.0" } }, - "node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/@orama/orama": { "version": "3.1.16", "resolved": "https://registry.npmjs.org/@orama/orama/-/orama-3.1.16.tgz", @@ -3386,6 +3376,7 @@ "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -3396,6 +3387,7 @@ "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -3459,6 +3451,7 @@ "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", @@ -3994,6 +3987,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4374,6 +4368,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -4540,6 +4535,7 @@ "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", "@chevrotain/gast": "11.0.3", @@ -4732,6 +4728,7 @@ "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz", "integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10" } @@ -5132,6 +5129,7 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -5757,6 +5755,7 @@ "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -5942,6 +5941,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -6453,6 +6453,7 @@ "resolved": "https://registry.npmjs.org/fumadocs-core/-/fumadocs-core-16.0.3.tgz", "integrity": "sha512-3kr1u0V0iHgIcQek+iRQKvJdbHp+Th8PAO4t74ZzgMpTbHOH6mI1zEpMEask/fTZHKOxDLSJ+q16s+1sAvC5yg==", "license": "MIT", + "peer": true, "dependencies": { "@formatjs/intl-localematcher": "^0.6.2", "@orama/orama": "^3.1.16", @@ -8202,6 +8203,7 @@ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.548.0.tgz", "integrity": "sha512-63b16z63jM9yc1MwxajHeuu0FRZFsDtljtDjYm26Kd86UQ5HQzu9ksEtoUUw4RBuewodw/tGFmvipePvRsKeDA==", "license": "ISC", + "peer": true, "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } @@ -9454,6 +9456,7 @@ "resolved": "https://registry.npmjs.org/next/-/next-16.0.0.tgz", "integrity": "sha512-nYohiNdxGu4OmBzggxy9rczmjIGI+TpR5vbKTsE1HqYwNm1B+YSiugSrFguX6omMOKnDHAmBPY4+8TNJk0Idyg==", "license": "MIT", + "peer": true, "dependencies": { "@next/env": "16.0.0", "@swc/helpers": "0.5.15", @@ -10040,6 +10043,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -10049,6 +10053,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -11128,7 +11133,8 @@ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.16.tgz", "integrity": "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==", "devOptional": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/tapable": { "version": "2.3.0", @@ -11350,6 +11356,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11892,6 +11899,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/docs/source.config.ts b/docs/source.config.ts index f11de3762..71a499c34 100644 --- a/docs/source.config.ts +++ b/docs/source.config.ts @@ -28,4 +28,17 @@ export const blog = defineDocs({ }, }); -export default defineConfig(); +// Updates collection - separate from docs +export const updates = defineDocs({ + dir: 'content/updates', + docs: { + schema: frontmatterSchema.extend({ + date: z.string().date().or(z.date()), + author: z.string().optional(), + image: z.string().optional(), + tags: z.array(z.string()).optional(), + }), + }, +}); + +export default defineConfig(); \ No newline at end of file diff --git a/docs/src/app/updates/[...slug]/page.tsx b/docs/src/app/updates/[...slug]/page.tsx new file mode 100644 index 000000000..b1ab8b386 --- /dev/null +++ b/docs/src/app/updates/[...slug]/page.tsx @@ -0,0 +1,188 @@ +import { notFound } from "next/navigation"; +import { updatesSource } from "@/lib/updates-source"; +import Link from "next/link"; +import Image from "next/image"; +import { ChevronLeft } from "lucide-react"; +import type { Metadata } from "next"; +import defaultMdxComponents from "fumadocs-ui/mdx"; +import { Pre } from "fumadocs-ui/components/codeblock"; +import Script from "next/script"; + +export function generateStaticParams() { + return updatesSource.getPages().map(page => ({ + slug: page.slugs, + })); +} + +export async function generateMetadata(props: { params: Promise<{ slug: string[] }> }): Promise { + const params = await props.params; + const page = updatesSource.getPage(params.slug); + if (!page) return {}; + + const url = `https://docs.rybbit.io/updates/${params.slug.join("/")}`; + const publishedTime = page.data.date ? new Date(page.data.date).toISOString() : undefined; + const ogImage = page.data.image || "/opengraph-image.png"; + + return { + title: page.data.title, + description: page.data.description, + alternates: { + canonical: url, + }, + openGraph: { + title: page.data.title, + description: page.data.description, + type: "article", + publishedTime, + authors: page.data.author ? [page.data.author] : undefined, + url, + images: [ + { + url: ogImage, + width: 1200, + height: 630, + alt: page.data.title, + }, + ], + siteName: "Rybbit", + locale: "en_US", + }, + twitter: { + card: "summary_large_image", + title: page.data.title, + description: page.data.description, + images: [ogImage], + creator: "@rybbitio", + }, + keywords: page.data.tags + ? [...page.data.tags, "product update", "Rybbit"] + : ["product update", "Rybbit"], + authors: page.data.author ? [{ name: page.data.author }] : undefined, + }; +} + +export default async function UpdatePostPage(props: { params: Promise<{ slug: string[] }> }) { + const params = await props.params; + const page = updatesSource.getPage(params.slug); + + if (!page) { + notFound(); + } + + const MDXContent = page.data.body; + const date = page.data.date ? new Date(page.data.date) : null; + + // Structured data for SEO + const structuredData = { + "@context": "https://schema.org", + "@type": "BlogPosting", + headline: page.data.title, + description: page.data.description, + datePublished: date?.toISOString(), + dateModified: date?.toISOString(), + author: { + "@type": "Person", + name: page.data.author || "Rybbit Team", + }, + publisher: { + "@type": "Organization", + name: "Rybbit", + logo: { + "@type": "ImageObject", + url: "https://rybbit.com/public/rybbit.svg", + }, + }, + keywords: page.data.tags?.join(", "), + }; + + return ( + <> +