diff --git a/apps/docs/app/[lang]/[[...slug]]/page.tsx b/apps/docs/app/[lang]/[[...slug]]/page.tsx
index f20d2604c..9fc1e7c3b 100644
--- a/apps/docs/app/[lang]/[[...slug]]/page.tsx
+++ b/apps/docs/app/[lang]/[[...slug]]/page.tsx
@@ -6,9 +6,10 @@ import Link from 'next/link'
import { notFound } from 'next/navigation'
import { PageNavigationArrows } from '@/components/docs-layout/page-navigation-arrows'
import { TOCFooter } from '@/components/docs-layout/toc-footer'
+import { LLMCopyButton } from '@/components/page-actions'
import { StructuredData } from '@/components/structured-data'
import { CodeBlock } from '@/components/ui/code-block'
-import { CopyPageButton } from '@/components/ui/copy-page-button'
+import { Heading } from '@/components/ui/heading'
import { source } from '@/lib/source'
export default async function Page(props: { params: Promise<{ slug?: string[]; lang: string }> }) {
@@ -202,7 +203,7 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
@@ -214,6 +215,12 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
components={{
...defaultMdxComponents,
CodeBlock,
+ h1: (props) =>
,
+ h2: (props) =>
,
+ h3: (props) =>
,
+ h4: (props) =>
,
+ h5: (props) =>
,
+ h6: (props) =>
,
}}
/>
diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css
index 2a3effa4a..2968717af 100644
--- a/apps/docs/app/global.css
+++ b/apps/docs/app/global.css
@@ -2,6 +2,12 @@
@import "fumadocs-ui/css/neutral.css";
@import "fumadocs-ui/css/preset.css";
+/* Prevent overscroll bounce effect on the page */
+html,
+body {
+ overscroll-behavior: none;
+}
+
@theme {
--color-fd-primary: #802fff; /* Purple from control-bar component */
--font-geist-sans: var(--font-geist-sans);
diff --git a/apps/docs/app/llms.mdx/[[...slug]]/route.ts b/apps/docs/app/llms.mdx/[[...slug]]/route.ts
index 2f143fdc4..2a58b9567 100644
--- a/apps/docs/app/llms.mdx/[[...slug]]/route.ts
+++ b/apps/docs/app/llms.mdx/[[...slug]]/route.ts
@@ -1,5 +1,6 @@
import { notFound } from 'next/navigation'
import { type NextRequest, NextResponse } from 'next/server'
+import { i18n } from '@/lib/i18n'
import { getLLMText } from '@/lib/llms'
import { source } from '@/lib/source'
@@ -7,7 +8,16 @@ export const revalidate = false
export async function GET(_req: NextRequest, { params }: { params: Promise<{ slug?: string[] }> }) {
const { slug } = await params
- const page = source.getPage(slug)
+
+ let lang: (typeof i18n.languages)[number] = i18n.defaultLanguage
+ let pageSlug = slug
+
+ if (slug && slug.length > 0 && i18n.languages.includes(slug[0] as typeof lang)) {
+ lang = slug[0] as typeof lang
+ pageSlug = slug.slice(1)
+ }
+
+ const page = source.getPage(pageSlug, lang)
if (!page) notFound()
return new NextResponse(await getLLMText(page), {
diff --git a/apps/docs/components/ui/copy-page-button.tsx b/apps/docs/components/page-actions.tsx
similarity index 65%
rename from apps/docs/components/ui/copy-page-button.tsx
rename to apps/docs/components/page-actions.tsx
index 880600d45..7c86c5392 100644
--- a/apps/docs/components/ui/copy-page-button.tsx
+++ b/apps/docs/components/page-actions.tsx
@@ -1,55 +1,50 @@
'use client'
import { useState } from 'react'
+import { useCopyButton } from 'fumadocs-ui/utils/use-copy-button'
import { Check, Copy } from 'lucide-react'
const cache = new Map
()
-interface CopyPageButtonProps {
+export function LLMCopyButton({
+ markdownUrl,
+}: {
+ /**
+ * A URL to fetch the raw Markdown/MDX content of page
+ */
markdownUrl: string
-}
-
-export function CopyPageButton({ markdownUrl }: CopyPageButtonProps) {
- const [copied, setCopied] = useState(false)
+}) {
const [isLoading, setLoading] = useState(false)
-
- const handleCopy = async () => {
+ const [checked, onClick] = useCopyButton(async () => {
const cached = cache.get(markdownUrl)
- if (cached) {
- await navigator.clipboard.writeText(cached)
- setCopied(true)
- setTimeout(() => setCopied(false), 2000)
- return
- }
+ if (cached) return navigator.clipboard.writeText(cached)
setLoading(true)
+
try {
await navigator.clipboard.write([
new ClipboardItem({
'text/plain': fetch(markdownUrl).then(async (res) => {
const content = await res.text()
cache.set(markdownUrl, content)
+
return content
}),
}),
])
- setCopied(true)
- setTimeout(() => setCopied(false), 2000)
- } catch (err) {
- console.error('Failed to copy:', err)
} finally {
setLoading(false)
}
- }
+ })
return (