Skip to content
Merged
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
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
},
"dependencies": {
"client-only": "^0.0.1",
"lucide-react": "^0.562.0",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"lucide-react": "^0.563.0",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"server-only": "^0.0.1",
"tailwind-merge": "^3.4.0"
},
Expand Down
45 changes: 18 additions & 27 deletions packages/site/app/[lang]/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,13 @@
* LICENSE file in the root directory of this source tree.
*/

import { source } from '@/lib/source';
import { getPageImage, source } from '@/lib/source';
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/layouts/docs/page';
import type { Metadata } from 'next';
import { DocsPage, DocsBody } from 'fumadocs-ui/page';
import { notFound } from 'next/navigation';
import { getMDXComponents } from '@/mdx-components';
import { createRelativeLink } from 'fumadocs-ui/mdx';
import { siteConfig } from '@/lib/site-config';
import defaultComponents from 'fumadocs-ui/mdx';
import { Callout } from 'fumadocs-ui/components/callout';
import { Card, Cards } from 'fumadocs-ui/components/card';
import { Steps, Step } from 'fumadocs-ui/components/steps';

const components = {
...defaultComponents,
Callout,
Card,
Cards,
Steps,
Step,
};

interface PageProps {
params: Promise<{
Expand All @@ -41,26 +30,25 @@ export default async function Page({ params }: PageProps) {
notFound();
}

const MDX = page.data.body as any;
const MDX = page.data.body;

return (
<DocsPage
toc={page.data.toc as any}
full={page.data.full as any}
lastUpdate={siteConfig.page.showLastUpdate ? (page.data as any).lastModified : undefined}
<DocsPage
toc={page.data.toc}
full={page.data.full}
tableOfContent={{
enabled: siteConfig.layout.toc.enabled,
style: siteConfig.layout.toc.depth > 2 ? 'clerk' : 'normal',
}}
editOnGithub={siteConfig.page.showEditLink ? {
owner: siteConfig.page.repoBaseUrl.split('/')[3],
repo: siteConfig.page.repoBaseUrl.split('/')[4],
sha: 'main', // Defaulting to main, could be extracted
path: siteConfig.page.repoBaseUrl.split('/').slice(7).join('/') // simplistic parsing
} : undefined}
>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDX components={components} />
<MDX
components={getMDXComponents({
a: createRelativeLink(source, page),
})}
/>
</DocsBody>
</DocsPage>
);
Expand All @@ -80,5 +68,8 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
return {
title: page.data.title,
description: page.data.description,
openGraph: {
images: getPageImage(page).url,
},
};
}
4 changes: 2 additions & 2 deletions packages/site/app/[lang]/docs/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import { source } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import type { ReactNode } from 'react';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
import { siteConfig } from '@/lib/site-config';

export default async function Layout({
Expand All @@ -24,7 +24,7 @@ export default async function Layout({
return (
<DocsLayout
tree={source.getPageTree(lang)}
{...baseOptions}
{...baseOptions()}
sidebar={{
enabled: siteConfig.layout.sidebar.enabled,
prefetch: siteConfig.layout.sidebar.prefetch,
Expand Down
14 changes: 1 addition & 13 deletions packages/site/app/[lang]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,18 @@
* LICENSE file in the root directory of this source tree.
*/

import 'fumadocs-ui/style.css';
import { RootProvider } from 'fumadocs-ui/provider/next';
import { defineI18nUI } from 'fumadocs-ui/i18n';
import { i18n } from '@/lib/i18n';
import { getTranslations } from '@/lib/translations';


const { provider } = defineI18nUI(i18n, {
translations: getTranslations(),
});

export default async function Layout({ params, children }: LayoutProps<'/[lang]'>) {
const { lang } = await params;
return (
<html lang={lang} suppressHydrationWarning>
<body
style={{
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
}}
>
<RootProvider i18n={provider(lang)}>{children}</RootProvider>
</body>
</html>
<RootProvider i18n={provider(lang)}>{children}</RootProvider>
);
}
16 changes: 7 additions & 9 deletions packages/site/app/api/search/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
*/

import { source } from '@/lib/source';
import { createSearchAPI } from 'fumadocs-core/search/server';
import { createFromSource } from 'fumadocs-core/search/server';

export const { GET } = createSearchAPI('advanced', {
indexes: source.getPages().map((page) => ({
title: page.data.title,
description: page.data.description,
url: page.url,
id: page.url,
structuredData: page.data.structuredData,
})),
export const { GET } = createFromSource(source, {
localeMap: {
en: 'english',
// Map 'cn' locale to English tokenizer since Chinese is not supported by Orama
cn: 'english',
},
});
3 changes: 3 additions & 0 deletions packages/site/app/global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
49 changes: 0 additions & 49 deletions packages/site/app/layout.config.tsx

This file was deleted.

19 changes: 2 additions & 17 deletions packages/site/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,12 @@
* LICENSE file in the root directory of this source tree.
*/

import 'fumadocs-ui/style.css';
import { RootProvider } from 'fumadocs-ui/provider/next';
import { defineI18nUI } from 'fumadocs-ui/i18n';
import { i18n } from '@/lib/i18n';
import { getTranslations } from '@/lib/translations';


const { provider } = defineI18nUI(i18n, {
translations: getTranslations(),
});
import './global.css';

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body
style={{
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
}}
>
<body className="flex flex-col min-h-screen">
{children}
</body>
</html>
Expand Down
18 changes: 18 additions & 0 deletions packages/site/app/llms-full.txt/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* ObjectDocs
* Copyright (c) 2026-present ObjectStack Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import { getLLMText, source } from '@/lib/source';

export const revalidate = false;

export async function GET() {
const scan = source.getPages().map(getLLMText);
const scanned = await Promise.all(scan);

return new Response(scanned.join('\n\n'));
}
28 changes: 28 additions & 0 deletions packages/site/app/llms.mdx/docs/[[...slug]]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* ObjectDocs
* Copyright (c) 2026-present ObjectStack Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import { getLLMText, source } from '@/lib/source';
import { notFound } from 'next/navigation';

export const revalidate = false;

export async function GET(_req: Request, { params }: RouteContext<'/llms.mdx/docs/[[...slug]]'>) {
const { slug } = await params;
const page = source.getPage(slug);
Comment on lines +14 to +16
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RouteContext is referenced in the GET handler signature but is not defined/imported anywhere in the repo, which will cause a TypeScript compile error. Replace it with an explicit context type for params (or import the correct Next-generated type if available).

Copilot uses AI. Check for mistakes.
if (!page) notFound();

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

export function generateStaticParams() {
return source.generateParams();
}
21 changes: 21 additions & 0 deletions packages/site/app/llms.txt/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* ObjectDocs
* Copyright (c) 2026-present ObjectStack Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import { source } from '@/lib/source';

export const revalidate = false;

export async function GET() {
const lines: string[] = [];
lines.push('# Documentation');
lines.push('');
for (const page of source.getPages()) {
lines.push(`- [${page.data.title}](${page.url}): ${page.data.description}`);
}
return new Response(lines.join('\n'));
}
36 changes: 36 additions & 0 deletions packages/site/app/og/docs/[...slug]/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* ObjectDocs
* Copyright (c) 2026-present ObjectStack Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import { getPageImage, source } from '@/lib/source';
import { notFound } from 'next/navigation';
import { ImageResponse } from 'next/og';
import { generate as DefaultImage } from 'fumadocs-ui/og';
import { siteConfig } from '@/lib/site-config';

export const revalidate = false;

export async function GET(_req: Request, { params }: RouteContext<'/og/docs/[...slug]'>) {
const { slug } = await params;
Comment on lines +17 to +18
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RouteContext is referenced in the GET handler signature but is not defined/imported anywhere in the repo, which will cause a TypeScript compile error. Replace it with an explicit context type (e.g., { params: { slug: string[] } } or the appropriate Next-generated type) or import the correct type if it exists.

Copilot uses AI. Check for mistakes.
const page = source.getPage(slug.slice(0, -1));
if (!page) notFound();
Comment on lines +18 to +20
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This OG route isn’t locale-aware: source.getPage(...) is called without a lang, and getPageImage() doesn’t include page.locale in the generated URL segments. For i18n pages this can return the default-language page and also causes URL collisions between locales; include locale in the OG URL/params and pass the correct language into source.getPage.

Copilot uses AI. Check for mistakes.

return new ImageResponse(
<DefaultImage title={page.data.title} description={page.data.description} site={siteConfig.meta.title} />,
{
width: 1200,
height: 630,
},
);
}

export function generateStaticParams() {
return source.getPages().map((page) => ({
lang: page.locale,
slug: getPageImage(page).segments,
}));
Comment on lines +31 to +35
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generateStaticParams() returns an extra lang field even though this route only has a [...slug] param. Next’s static params are expected to match the route’s dynamic segments; either add a [lang] segment to the route path or fold the locale into slug so the params shape matches the route.

Copilot uses AI. Check for mistakes.
}
Loading
Loading