Files
better-auth/docs/app/docs/[[...slug]]/page.tsx
2024-12-14 21:30:42 +03:00

141 lines
3.3 KiB
TypeScript

import { source, openapi } from "@/app/source";
import { DocsPage, DocsBody, DocsTitle } from "fumadocs-ui/page";
import { notFound } from "next/navigation";
import { absoluteUrl } from "@/lib/utils";
import DatabaseTable from "@/components/mdx/database-tables";
import { cn } from "@/lib/utils";
import { Step, Steps } from "fumadocs-ui/components/steps";
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
import { GenerateSecret } from "@/components/generate-secret";
import { AnimatePresence } from "@/components/ui/fade-in";
import { TypeTable } from "fumadocs-ui/components/type-table";
import { Features } from "@/components/blocks/features";
import { ForkButton } from "@/components/fork-button";
import Link from "next/link";
import defaultMdxComponents from "fumadocs-ui/mdx";
import { File, Folder, Files } from "fumadocs-ui/components/files";
import { createTypeTable } from "fumadocs-typescript/ui";
import { Accordion, Accordions } from "fumadocs-ui/components/accordion";
const { AutoTypeTable } = createTypeTable();
export default async function Page({
params,
}: {
params: Promise<{ slug?: string[] }>;
}) {
const { slug } = await params;
const page = source.getPage(slug);
if (page == null) {
notFound();
}
const MDX = page.data.body;
return (
<DocsPage
toc={page.data.toc}
full={page.data.full}
editOnGithub={{
owner: "better-auth",
repo: "better-auth",
path: "/docs/content/docs",
}}
tableOfContent={{
style: "clerk",
header: <div className="w-10 h-4"></div>,
}}
footer={{
enabled: false,
}}
>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsBody>
<MDX
components={{
...defaultMdxComponents,
Link: ({
className,
...props
}: React.ComponentProps<typeof Link>) => (
<Link
className={cn(
"font-medium underline underline-offset-4",
className,
)}
{...props}
/>
),
Step,
Steps,
File,
Folder,
Files,
Tab,
Tabs,
AutoTypeTable,
GenerateSecret,
AnimatePresence,
TypeTable,
Features,
ForkButton,
DatabaseTable,
Accordion,
Accordions,
iframe: (props) => (
<iframe {...props} className="w-full h-[500px]" />
),
}}
/>
</DocsBody>
</DocsPage>
);
}
export async function generateStaticParams() {
const res = source.getPages().map((page) => ({
slug: page.slugs,
}));
return source.generateParams();
}
export async function generateMetadata({
params,
}: { params: Promise<{ slug?: string[] }> }) {
const { slug } = await params;
const page = source.getPage(slug);
if (page == null) notFound();
const baseUrl = process.env.NEXT_PUBLIC_URL || process.env.VERCEL_URL;
const url = new URL(`${baseUrl}/api/og`);
const { title, description } = page.data;
const pageSlug = page.file.path;
url.searchParams.set("type", "Documentation");
url.searchParams.set("mode", "dark");
url.searchParams.set("heading", `${title}`);
return {
title,
description,
openGraph: {
title,
description,
type: "website",
url: absoluteUrl(`docs/${pageSlug}`),
images: [
{
url: url.toString(),
width: 1200,
height: 630,
alt: title,
},
],
},
twitter: {
card: "summary_large_image",
title,
description,
images: [url.toString()],
},
};
}