Skip to content
Open
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
29 changes: 29 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
# deps
node_modules

# generated content
.source

# test & build
coverage
.next/
out/
build
*.tsbuildinfo
dist

# misc
.DS_Store
*.pem
.pnp
.pnp.js
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# others
.env*.local
.vercel
next-env.d.ts

# Turborepo
.turbo
88 changes: 88 additions & 0 deletions docs/app/[lang]/(docs)/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { createRelativeLink } from 'fumadocs-ui/mdx'
import type { Metadata } from 'next'
import { notFound } from 'next/navigation'
import { AskAI } from '@/components/geistdocs/ask-ai'
import { CopyPage } from '@/components/geistdocs/copy-page'
import {
DocsBody,
DocsDescription,
DocsPage,
DocsTitle,
} from '@/components/geistdocs/docs-page'
import { EditSource } from '@/components/geistdocs/edit-source'
import { Feedback } from '@/components/geistdocs/feedback'
import { getMDXComponents } from '@/components/geistdocs/mdx-components'
import { OpenInChat } from '@/components/geistdocs/open-in-chat'
import { ScrollTop } from '@/components/geistdocs/scroll-top'
import { Separator } from '@/components/ui/separator'
import { getLLMText, getPageImage, source } from '@/lib/geistdocs/source'

const Page = async ({ params }: PageProps<'/[lang]/[[...slug]]'>) => {
const { slug, lang } = await params
const page = source.getPage(slug, lang)

if (!page) {
notFound()
}

const markdown = await getLLMText(page)
const MDX = page.data.body

return (
<DocsPage
full={page.data.full}
tableOfContent={{
style: 'clerk',
footer: (
<div className='my-3 space-y-3'>
<Separator />
<EditSource path={page.path} />
<ScrollTop />
<Feedback />
<CopyPage text={markdown} />
<AskAI href={page.url} />
<OpenInChat href={page.url} />
</div>
),
}}
toc={page.data.toc}
>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDX
components={getMDXComponents({
a: createRelativeLink(source, page),

// Add your custom components here
})}
/>
</DocsBody>
</DocsPage>
)
}

export const generateStaticParams = () => source.generateParams()

export const generateMetadata = async ({
params,
}: PageProps<'/[lang]/[[...slug]]'>) => {
const { slug, lang } = await params
const page = source.getPage(slug, lang)

if (!page) {
notFound()
}

const metadata: Metadata = {
title: page.data.title,
description: page.data.description,
openGraph: {
images: getPageImage(page).url,
},
}

return metadata
}

export default Page
10 changes: 10 additions & 0 deletions docs/app/[lang]/(docs)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { DocsLayout } from '@/components/geistdocs/docs-layout'
import { source } from '@/lib/geistdocs/source'

const Layout = async ({ children, params }: LayoutProps<'/[lang]'>) => {
const { lang } = await params

return <DocsLayout tree={source.pageTree[lang]}>{children}</DocsLayout>
}

export default Layout
29 changes: 29 additions & 0 deletions docs/app/[lang]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import "../global.css";
import { Footer } from "@/components/geistdocs/footer";
import { Navbar } from "@/components/geistdocs/navbar";
import { GeistdocsProvider } from "@/components/geistdocs/provider";
import { basePath } from "@/geistdocs";
import { mono, sans } from "@/lib/geistdocs/fonts";
import { cn } from "@/lib/utils";

const Layout = async ({ children, params }: LayoutProps<"/[lang]">) => {
const { lang } = await params;

return (
<html
className={cn(sans.variable, mono.variable, "scroll-smooth antialiased")}
lang={lang}
suppressHydrationWarning
>
<body>
<GeistdocsProvider basePath={basePath} lang={lang}>
<Navbar />
{children}
<Footer />
</GeistdocsProvider>
</body>
</html>
);
};

export default Layout;
30 changes: 30 additions & 0 deletions docs/app/[lang]/llms.mdx/[[...slug]]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { notFound } from "next/navigation";
import { getLLMText, source } from "@/lib/geistdocs/source";

export const revalidate = false;

export async function GET(
_req: Request,
{ params }: RouteContext<"/[lang]/llms.mdx/[[...slug]]">
) {
const { slug, lang } = await params;
const page = source.getPage(slug, lang);

if (!page) {
notFound();
}

return new Response(await getLLMText(page), {
headers: {
"Content-Type": "text/markdown",
},
});
}

export const generateStaticParams = async ({
params,
}: RouteContext<"/[lang]/llms.mdx/[[...slug]]">) => {
const { lang } = await params;

return source.generateParams(lang);
};
15 changes: 15 additions & 0 deletions docs/app/[lang]/llms.txt/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { NextRequest } from "next/server";
import { getLLMText, source } from "@/lib/geistdocs/source";

export const revalidate = false;

export const GET = async (
_req: NextRequest,
{ params }: RouteContext<"/[lang]/llms.txt">
) => {
const { lang } = await params;
const scan = source.getPages(lang).map(getLLMText);
const scanned = await Promise.all(scan);

return new Response(scanned.join("\n\n"));
};
Binary file added docs/app/[lang]/og/[...slug]/background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
95 changes: 95 additions & 0 deletions docs/app/[lang]/og/[...slug]/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { readFile } from "node:fs/promises";
import { join } from "node:path";
import { ImageResponse } from "next/og";
import type { NextRequest } from "next/server";
import { getPageImage, source } from "@/lib/geistdocs/source";

export const GET = async (
_request: NextRequest,
{ params }: RouteContext<"/[lang]/og/[...slug]">
) => {
const { slug, lang } = await params;
const page = source.getPage(slug.slice(0, -1), lang);

if (!page) {
return new Response("Not found", { status: 404 });
}

const { title, description } = page.data;

const regularFont = await readFile(
join(process.cwd(), "app/[lang]/og/[...slug]/geist-sans-regular.ttf")
);

const semiboldFont = await readFile(
join(process.cwd(), "app/[lang]/og/[...slug]/geist-sans-semibold.ttf")
);

const backgroundImage = await readFile(
join(process.cwd(), "app/[lang]/og/[...slug]/background.png")
);

const backgroundImageData = backgroundImage.buffer.slice(
backgroundImage.byteOffset,
backgroundImage.byteOffset + backgroundImage.byteLength
);

return new ImageResponse(
<div style={{ fontFamily: "Geist" }} tw="flex h-full w-full bg-black">
{/** biome-ignore lint/performance/noImgElement: "Required for Satori" */}
<img
alt="Vercel OpenGraph Background"
height={628}
src={backgroundImageData as never}
width={1200}
/>
<div tw="flex flex-col absolute h-full w-[750px] justify-center left-[50px] pr-[50px] pt-[116px] pb-[86px]">
<div
style={{
textWrap: "balance",
}}
tw="text-5xl font-medium text-white tracking-tight flex leading-[1.1] mb-4"
>
{title}
</div>
<div
style={{
color: "#8B8B8B",
lineHeight: "44px",
textWrap: "balance",
}}
tw="text-[32px]"
>
{description}
</div>
</div>
</div>,
{
width: 1200,
height: 628,
fonts: [
{
name: "Geist",
data: regularFont,
weight: 400,
},
{
name: "Geist",
data: semiboldFont,
weight: 500,
},
],
}
);
};

export const generateStaticParams = async ({
params,
}: RouteContext<"/[lang]/og/[...slug]">) => {
const { lang } = await params;

return source.getPages(lang).map((page) => ({
lang: page.locale,
slug: getPageImage(page).segments,
}));
};
46 changes: 46 additions & 0 deletions docs/app/[lang]/rss.xml/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Feed } from "feed";
import type { NextRequest } from "next/server";
import { title } from "@/geistdocs";
import { source } from "@/lib/geistdocs/source";

const protocol = process.env.NODE_ENV === "production" ? "https" : "http";
const baseUrl = `${protocol}://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`;

export const revalidate = false;

export const GET = async (
_req: NextRequest,
{ params }: RouteContext<"/[lang]/rss.xml">
) => {
const { lang } = await params;
const feed = new Feed({
title,
id: baseUrl,
link: baseUrl,
language: lang,
copyright: `All rights reserved ${new Date().getFullYear()}, Vercel`,
});

for (const page of source.getPages(lang)) {
feed.addItem({
id: page.url,
title: page.data.title,
description: page.data.description,
link: `${baseUrl}${page.url}`,
date: new Date(page.data.lastModified ?? new Date()),
author: [
{
name: "Vercel",
},
],
});
}

const rss = feed.rss2();

return new Response(rss, {
headers: {
"Content-Type": "application/rss+xml",
},
});
};
18 changes: 18 additions & 0 deletions docs/app/actions/feedback/emotions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const emotions = [
{
name: "cry",
emoji: "😭",
},
{
name: "sad",
emoji: "😕",
},
{
name: "happy",
emoji: "🙂",
},
{
name: "amazed",
emoji: "🤩",
},
];
Loading