From 78e0cf8945231595eccb4240aad159e91dab0a6b Mon Sep 17 00:00:00 2001
From: Fuma Nama
Components
@@ -71,22 +67,15 @@ export default function Layout({ children }: LayoutProps<'/'>) {
OpenAPI
- Generate interactive playgrounds and docs for your OpenAPI - schema. + Generate interactive playgrounds and docs for your OpenAPI schema.
Markdown
diff --git a/apps/docs/app/(home)/marquee.tsx b/apps/docs/app/(home)/marquee.tsx index 939b56b01..4a73e91fd 100644 --- a/apps/docs/app/(home)/marquee.tsx +++ b/apps/docs/app/(home)/marquee.tsx @@ -57,9 +57,7 @@ export function Marquee({ key={i} className={cn( 'flex shrink-0 justify-around [gap:var(--gap)]', - vertical - ? 'animate-marquee-vertical flex-col' - : 'animate-marquee flex-row', + vertical ? 'animate-marquee-vertical flex-col' : 'animate-marquee flex-row', pauseOnHover && 'group-hover:[animation-play-state:paused]', reverse && '[animation-direction:reverse]', )} diff --git a/apps/docs/app/(home)/page.client.tsx b/apps/docs/app/(home)/page.client.tsx index 83e8f9762..8acd34daf 100644 --- a/apps/docs/app/(home)/page.client.tsx +++ b/apps/docs/app/(home)/page.client.tsx @@ -127,9 +127,7 @@ export function CreateAppAnimation() { lines.push( {installCmd.substring(0, tick)} - {tick < timeCommandEnter && ( - - )} + {tick < timeCommandEnter && } , ); @@ -176,8 +174,7 @@ export function CreateAppAnimation() { )}
- {' '}
- Terminal
+ Terminal
@@ -206,17 +203,14 @@ function LaunchAppWindow(props: HTMLAttributes) {
);
}
-const previewButtonVariants = cva(
- 'w-20 h-8 text-sm font-medium transition-colors rounded-full',
- {
- variants: {
- active: {
- true: 'text-fd-primary-foreground',
- false: 'text-fd-muted-foreground',
- },
+const previewButtonVariants = cva('w-20 h-8 text-sm font-medium transition-colors rounded-full', {
+ variants: {
+ active: {
+ true: 'text-fd-primary-foreground',
+ false: 'text-fd-muted-foreground',
},
},
-);
+});
export function PreviewImages(props: ComponentProps<'div'>) {
const [active, setActive] = useState(0);
const previews = [
@@ -261,9 +255,7 @@ export function PreviewImages(props: ComponentProps<'div'>) {
alt="preview"
className={cn(
'col-start-1 row-start-1 select-none',
- active === i
- ? 'animate-in fade-in slide-in-from-bottom-12 duration-800'
- : 'invisible',
+ active === i ? 'animate-in fade-in slide-in-from-bottom-12 duration-800' : 'invisible',
)}
/>
))}
@@ -291,8 +283,7 @@ export function Writing({
}: {
tabs: Record<(typeof WritingTabs)[number]['value'], ReactNode>;
}) {
- const [tab, setTab] =
- useState<(typeof WritingTabs)[number]['value']>('writer');
+ const [tab, setTab] = useState<(typeof WritingTabs)[number]['value']>('writer');
return (
@@ -300,8 +291,8 @@ export function Writing({
Anybody can write.
- Native support for Markdown & MDX, offering intuitive, convenient and
- extensive syntax for non-dev writers, developers, and AI agents.
+ Native support for Markdown & MDX, offering intuitive, convenient and extensive syntax for
+ non-dev writers, developers, and AI agents.
{WritingTabs.map((item) => (
@@ -355,9 +346,7 @@ export function AgnosticBackground() {
);
}
-export function ContentAdoptionBackground(
- props: ComponentProps,
-) {
+export function ContentAdoptionBackground(props: ComponentProps) {
const { resolvedTheme } = useTheme();
return (
@@ -376,10 +365,7 @@ export function ContentAdoptionBackground(
}
let observer: IntersectionObserver;
-const observerTargets = new WeakMap<
- Element,
- (entry: IntersectionObserverEntry) => void
->();
+const observerTargets = new WeakMap void>();
function useIsVisible(ref: RefObject) {
const [visible, setVisible] = useState(false);
diff --git a/apps/docs/app/(home)/page.tsx b/apps/docs/app/(home)/page.tsx
index e0896d764..548ae7045 100644
--- a/apps/docs/app/(home)/page.tsx
+++ b/apps/docs/app/(home)/page.tsx
@@ -39,8 +39,7 @@ const buttonVariants = cva(
variants: {
variant: {
primary: 'bg-brand text-brand-foreground hover:bg-brand-200',
- secondary:
- 'border bg-fd-secondary text-fd-secondary-foreground hover:bg-fd-accent',
+ secondary: 'border bg-fd-secondary text-fd-secondary-foreground hover:bg-fd-accent',
},
},
defaultVariants: {
@@ -77,20 +76,14 @@ export default function Page() {
your style.
-
+
Getting Started
Open CodeSandbox
@@ -99,14 +92,11 @@ export default function Page() {
- Fumadocs is a React.js{' '}
- documentation framework for{' '}
- Developers,
- beautifully designed by{' '}
- Fuma Nama. Bringing
- powerful features for your docs workflows, with high customizability
- to fit your preferences, works seamlessly with any React.js framework,
- CMS — anything.
+ Fumadocs is a React.js documentation
+ framework for Developers, beautifully
+ designed by Fuma Nama. Bringing powerful
+ features for your docs workflows, with high customizability to fit your preferences, works
+ seamlessly with any React.js framework, CMS — anything.
@@ -145,18 +135,13 @@ function Aesthetics() {
-
+
Minimal aesthetics, Maximum customizability.
- Fumadocs offer well-designed themes, with a headless mode to plug your
- own UI.
-
-
- Pro designer? Customise the theme using Fumadocs CLI.
+ Fumadocs offer well-designed themes, with a headless mode to plug your own UI.
+ Pro designer? Customise the theme using Fumadocs CLI.
Choose a layout to customise...`}
lang="bash"
@@ -191,16 +176,11 @@ return 0;
lang="mdx"
/>
-
+
The familiar syntax.
- It is just Markdown, with additional features seamlessly
- composing into the syntax.
+ It is just Markdown, with additional features seamlessly composing into the syntax.
- Markdown features, including images
@@ -242,23 +222,15 @@ And re-use content:
lang="mdx"
/>
-
+
Extensive but simple.
-
- MDX for developers authoring content, use JavaScript in content.
-
+ MDX for developers authoring content, use JavaScript in content.
- JavaScript + JSX syntax
- Custom Components
- Include/Embed Content
- -
- TypeScript Twoslash: show type information in codeblocks.
-
+ - TypeScript Twoslash: show type information in codeblocks.
- Shiki Notations
- Extend via remark, rehype plugins
@@ -286,25 +258,17 @@ export async function DataView() {
/>
-
+
Content, always up-to-date.
- Combining the power of MDX and React Server Components, use the
- latest data from database, server — anywhere, to be part of your
- content.
+ Combining the power of MDX and React Server Components, use the latest data from
+ database, server — anywhere, to be part of your content.
- Works on React Server Components
- Display data from database, CMS, anything
- -
- auto-type-table for documenting types based on TypeScript
- Compiler
-
+ - auto-type-table for documenting types based on TypeScript Compiler
- OpenAPI playground for documenting your APIs
@@ -350,14 +314,12 @@ function Feedback() {
return (
<>
-
+
A framework people love.
- Loved by teams and developers from startups like Unkey, Vercel, Orama
- — evolving everyday to be your favourite docs framework.
+ Loved by teams and developers from startups like Unkey, Vercel, Orama — evolving everyday
+ to be your favourite docs framework.
Showcase
@@ -391,9 +353,7 @@ function Feedback() {
/>
{item.user}
-
- {item.role}
-
+ {item.role}
@@ -418,12 +378,7 @@ function ForEngineers() {
Docs For Engineers.
-
+
- Official support for Next.js, Tanstack Start, React Router, Waku —
- portable to any React.js framework.
+ Official support for Next.js, Tanstack Start, React Router, Waku — portable to any
+ React.js framework.
Next.js
-
+
-
+
A truly composable framework.
Separated as Content →{' '}
- Core →{' '}
- UI, offering the high
- composability that engineers love — you can use Fumadocs as a library,
+ Core → UI,
+ offering the high composability that engineers love — you can use Fumadocs as a library,
without adapting the entire framework.
@@ -501,8 +449,7 @@ function ForEngineers() {
},
{
name: 'fumadocs-core',
- description:
- 'Headless library for building docs + handling content.',
+ description: 'Headless library for building docs + handling content.',
},
{
name: 'fumadocs-ui',
@@ -528,15 +475,12 @@ function ForEngineers() {
-
+
Adopts your content.
- Designed to integrate with any{' '}
- content source, Fumadocs works on
- MDX, Content Collections, and even your own CMS.
+ Designed to integrate with any content source,
+ Fumadocs works on MDX, Content Collections, and even your own CMS.
{[
@@ -579,30 +523,24 @@ export const source = loader({
lang="ts"
/>
-
+
My CMS
- {['My Page', 'Another Page', 'Components', 'Getting Started'].map(
- (page) => (
-
-
- {page}
-
- Article
-
+ {['My Page', 'Another Page', 'Components', 'Getting Started'].map((page) => (
+
+
+ {page}
+
+ Article
- ),
- )}
+
+ ))}
@@ -621,14 +559,10 @@ This is my first document.`}
-
+
Enhance your search experience.
-
- Integrate with Orama Search and Algolia Search in your docs easily.
-
+ Integrate with Orama Search and Algolia Search in your docs easily.
-
+
The shadcn/ui for docs
- Fumadocs CLI creates interactive components for your docs, offering
- a rich experience to your users.
+ Fumadocs CLI creates interactive components for your docs, offering a rich experience to
+ your users.
-
+
Commands
-
+
>
);
}
-const searchItemVariants = cva(
- 'rounded-md p-2 text-sm text-fd-popover-foreground',
-);
+const searchItemVariants = cva('rounded-md p-2 text-sm text-fd-popover-foreground');
function Search() {
return (
@@ -685,20 +606,13 @@ function Search() {
['MDX Content', 'Using MDX for content.'],
['User Guide', 'How to use Fumadocs.'],
].map(([title, description], i) => (
-
+
{title}
- {i === 7 && (
- Open
- )}
+ {i === 7 && Open
}
-
- {description}
-
+ {description}
))}
@@ -732,14 +646,9 @@ function OpenSource() {
>
Made Possible by You.
-
- Fumadocs is 100% powered by passion and open source community.
-
+ Fumadocs is 100% powered by passion and open source community.
-
+
Sponsors
-
- The docs framework designed with care.
-
+ The docs framework designed with care.
- A list of beautiful open-source projects with their docs powered by
- Fumadocs.
+ A list of beautiful open-source projects with their docs powered by Fumadocs.
-
- Fumadocs can power your blog, too.
-
+ Fumadocs can power your blog, too.
{blogs.map((showcase) => (
@@ -431,9 +423,7 @@ function ShowcaseItem({ name, url, image }: ShowcaseObject) {
rel="noreferrer noopener"
className="flex aspect-[1.91/1] flex-col border border-dashed p-4 transition-all hover:bg-fd-accent"
>
-
- {new URL(url).hostname}
-
+ {new URL(url).hostname}
{name}
);
diff --git a/apps/docs/app/(home)/sponsors/data.tsx b/apps/docs/app/(home)/sponsors/data.tsx
index 92291e859..9c7d584e0 100644
--- a/apps/docs/app/(home)/sponsors/data.tsx
+++ b/apps/docs/app/(home)/sponsors/data.tsx
@@ -47,11 +47,7 @@ export const organizationAsUserSponsors = [
asUser: 'marclave',
logo: (
<>
-
+
{
- const entity = organizationAsUserSponsors.find(
- (entity) => entity.asUser === v.login,
- );
+ const entity = organizationAsUserSponsors.find((entity) => entity.asUser === v.login);
if (entity) {
return {
login: entity.github,
@@ -62,8 +60,7 @@ export default async function Page() {
/>
Support Fumadocs
- Your sponsorship means a lot to open-source projects, including
- Fumadocs.
+ Your sponsorship means a lot to open-source projects, including Fumadocs.
Sponsor
-
+
-
+
@@ -158,13 +145,7 @@ export default async function Page() {
animationDelay: `${(Math.pow(2, i) * 360).toString()}ms`,
}}
/>
-
+
))}
@@ -177,13 +158,7 @@ export default async function Page() {
filter: 'drop-shadow(2px 0px 8px rgb(255, 100, 255))',
}}
/>
-
+
Fumadocs
@@ -192,9 +167,7 @@ export default async function Page() {
{sponsors
.filter((sponsor) => sponsor.__typename === 'Organization')
.map((sponsor) => {
- const tier = tiers.find(
- (tier) => sponsor.tier.monthlyPriceInDollars >= tier.min,
- );
+ const tier = tiers.find((tier) => sponsor.tier.monthlyPriceInDollars >= tier.min);
return (
)}
- {tier && (
- {tier.name}
- )}
+ {tier && {tier.name}
}
);
})}
Hosting Sponsor
-
+
-
+
Fumadocs is the framework for building documentation with{' '}
-
- anime and fuwa fuwa power
-
- . Using the power of weebs and waifus.
+ anime and fuwa fuwa power. Using the power
+ of weebs and waifus.
Getting Started
diff --git a/apps/docs/app/docs/[...slug]/page.tsx b/apps/docs/app/docs/[[...slug]]/page.tsx
similarity index 82%
rename from apps/docs/app/docs/[...slug]/page.tsx
rename to apps/docs/app/docs/[[...slug]]/page.tsx
index 4c40d8bb5..79d809651 100644
--- a/apps/docs/app/docs/[...slug]/page.tsx
+++ b/apps/docs/app/docs/[[...slug]]/page.tsx
@@ -10,11 +10,7 @@ import { Wrapper } from '@/components/preview/wrapper';
import { Mermaid } from '@/components/mdx/mermaid';
import { Feedback } from '@/components/feedback';
import { onRateAction, owner, repo } from '@/lib/github';
-import {
- HoverCard,
- HoverCardContent,
- HoverCardTrigger,
-} from '@/components/ui/hover-card';
+import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card';
import Link from 'fumadocs-core/link';
import { getPageTreePeers } from 'fumadocs-core/page-tree';
import { Card, Cards } from 'fumadocs-ui/components/card';
@@ -23,13 +19,9 @@ import { LLMCopyButton, ViewOptions } from '@/components/ai/page-actions';
import { Banner } from 'fumadocs-ui/components/banner';
import { Installation } from '@/components/preview/installation';
import { Customisation } from '@/components/preview/customisation';
-import {
- DocsBody,
- DocsPage,
- PageLastUpdate,
-} from 'fumadocs-ui/layouts/docs/page';
+import { DocsBody, DocsPage, PageLastUpdate } from 'fumadocs-ui/layouts/docs/page';
import { NotFound } from '@/components/not-found';
-import { getSuggestions } from '@/app/docs/[...slug]/suggestions';
+import { getSuggestions } from './suggestions';
import { PathUtils } from 'fumadocs-core/source';
function PreviewRenderer({ preview }: { preview: string }): ReactNode {
@@ -43,13 +35,15 @@ function PreviewRenderer({ preview }: { preview: string }): ReactNode {
export const revalidate = false;
-export default async function Page(props: PageProps<'/docs/[...slug]'>) {
+export default async function Page(props: PageProps<'/docs/[[...slug]]'>) {
const params = await props.params;
const page = source.getPage(params.slug);
if (!page)
return (
- getSuggestions(params.slug.join(' '))} />
+ (params.slug ? getSuggestions(params.slug.join(' ')) : [])}
+ />
);
if (page.data.type === 'openapi') {
@@ -75,9 +69,7 @@ export default async function Page(props: PageProps<'/docs/[...slug]'>) {
}}
>
{page.data.title}
-
- {page.data.description}
-
+ {page.data.description}
) {
return (
{props.children}
{found.page.data.title}
-
- {found.page.data.description}
-
+ {found.page.data.description}
);
@@ -150,9 +136,7 @@ function DocsCategory({ url }: { url: string }) {
);
}
-export async function generateMetadata(
- props: PageProps<'/docs/[...slug]'>,
-): Promise {
+export async function generateMetadata(props: PageProps<'/docs/[[...slug]]'>): Promise {
const { slug = [] } = await props.params;
const page = source.getPage(slug);
if (!page)
@@ -160,8 +144,7 @@ export async function generateMetadata(
title: 'Not Found',
});
- const description =
- page.data.description ?? 'The library for building documentation sites';
+ const description = page.data.description ?? 'The library for building documentation sites';
const image = {
url: getPageImage(page).url,
diff --git a/apps/docs/app/docs/[...slug]/suggestions.ts b/apps/docs/app/docs/[[...slug]]/suggestions.ts
similarity index 100%
rename from apps/docs/app/docs/[...slug]/suggestions.ts
rename to apps/docs/app/docs/[[...slug]]/suggestions.ts
diff --git a/apps/docs/app/docs/layout.tsx b/apps/docs/app/docs/layout.tsx
index 8fd595943..665e77dd3 100644
--- a/apps/docs/app/docs/layout.tsx
+++ b/apps/docs/app/docs/layout.tsx
@@ -1,12 +1,9 @@
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { baseOptions, linkItems, logo } from '@/lib/layout.shared';
import { source } from '@/lib/source';
-import {
- AISearch,
- AISearchPanel,
- AISearchTrigger,
-} from '@/components/ai/search';
+import { AISearch, AISearchPanel, AISearchTrigger } from '@/components/ai/search';
import 'katex/dist/katex.min.css';
+import { getSection } from '@/lib/source/navigation';
export default function Layout({ children }: LayoutProps<'/docs'>) {
const base = baseOptions();
@@ -22,9 +19,7 @@ export default function Layout({ children }: LayoutProps<'/docs'>) {
title: (
<>
{logo}
-
- Fumadocs
-
+ Fumadocs
>
),
}}
@@ -33,8 +28,7 @@ export default function Layout({ children }: LayoutProps<'/docs'>) {
transform(option, node) {
const meta = source.getNodeMeta(node);
if (!meta || !node.icon) return option;
-
- const color = `var(--${meta.path.split('/')[0]}-color, var(--color-fd-foreground))`;
+ const color = `var(--${getSection(meta.path)}-color, var(--color-fd-foreground))`;
return {
...option,
diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css
index 7cc42cae6..ef29b95e5 100644
--- a/apps/docs/app/global.css
+++ b/apps/docs/app/global.css
@@ -64,10 +64,7 @@
--animate-stroke: stroke 5s linear infinite;
--color-gradient-radial: radial-gradient(circle, var(--tw-gradient-stops));
- --color-repeat-gradient-to-r: repeating-linear-gradient(
- to right,
- var(--tw-gradient-stops)
- );
+ --color-repeat-gradient-to-r: repeating-linear-gradient(to right, var(--tw-gradient-stops));
--color-repeat-gradient-to-br: repeating-linear-gradient(
to bottom right,
var(--tw-gradient-stops)
@@ -82,9 +79,14 @@
--color-fd-primary: var(--headless-color);
}
+.framework {
+ --color-fd-primary: var(--framework-color);
+}
+
:root {
--headless-color: hsl(250, 80%, 54%);
- --ui-color: hsl(41, 100%, 40%);
+ --framework-color: hsl(41, 100%, 40%);
+ --ui-color: hsl(217, 100%, 58%);
}
html {
@@ -101,7 +103,8 @@ body {
.dark {
--headless-color: hsl(250 100% 80%);
- --ui-color: #fff383;
+ --framework-color: #fff383;
+ --ui-color: #a9ceff;
}
@keyframes circuit_1 {
diff --git a/apps/docs/app/layout.client.tsx b/apps/docs/app/layout.client.tsx
index a4d24f5ce..e1835a389 100644
--- a/apps/docs/app/layout.client.tsx
+++ b/apps/docs/app/layout.client.tsx
@@ -3,24 +3,17 @@
import { useParams } from 'next/navigation';
import { type ReactNode, useId } from 'react';
import { cn } from '@/lib/cn';
+import { getSection } from '@/lib/source/navigation';
-export function Body({
- children,
-}: {
- children: ReactNode;
-}): React.ReactElement {
+export function Body({ children }: { children: ReactNode }): React.ReactElement {
const mode = useMode();
- return (
-
- {children}
-
- );
+ return {children};
}
export function useMode(): string | undefined {
- const { slug } = useParams();
- return Array.isArray(slug) && slug.length > 0 ? slug[0] : undefined;
+ const { slug = [] } = useParams();
+ if (Array.isArray(slug)) return getSection(slug[0]);
}
export function FumadocsIcon(props: React.SVGProps) {
@@ -36,10 +29,7 @@ export function FumadocsIcon(props: React.SVGProps) {
strokeWidth="1"
/>
-
+
diff --git a/apps/docs/app/layout.tsx b/apps/docs/app/layout.tsx
index 7237977a7..e2c726059 100644
--- a/apps/docs/app/layout.tsx
+++ b/apps/docs/app/layout.tsx
@@ -37,11 +37,7 @@ export const viewport: Viewport = {
export default function RootLayout({ children }: { children: ReactNode }) {
return (
-
+
diff --git a/apps/docs/app/llms.mdx/[...slug]/route.ts b/apps/docs/app/llms.mdx/[...slug]/route.ts
index a63c0863a..6546c01cf 100644
--- a/apps/docs/app/llms.mdx/[...slug]/route.ts
+++ b/apps/docs/app/llms.mdx/[...slug]/route.ts
@@ -5,10 +5,7 @@ import { notFound } from 'next/navigation';
export const revalidate = false;
-export async function GET(
- _req: NextRequest,
- { params }: RouteContext<'/llms.mdx/[...slug]'>,
-) {
+export async function GET(_req: NextRequest, { params }: RouteContext<'/llms.mdx/[...slug]'>) {
const slug = (await params).slug;
const page = source.getPage(slug);
if (!page) notFound();
diff --git a/apps/docs/app/og/[...slug]/generate.tsx b/apps/docs/app/og/[...slug]/generate.tsx
index 1ede47a63..4d6e776eb 100644
--- a/apps/docs/app/og/[...slug]/generate.tsx
+++ b/apps/docs/app/og/[...slug]/generate.tsx
@@ -31,22 +31,11 @@ export function generate({ title, description }: GenerateProps) {
const siteName = 'Fumadocs';
const primaryTextColor = 'rgb(240,240,240)';
const logo = (
-
+
-
+
diff --git a/apps/docs/app/og/[...slug]/route.tsx b/apps/docs/app/og/[...slug]/route.tsx
index 61b1e5b3f..c4c4c3029 100644
--- a/apps/docs/app/og/[...slug]/route.tsx
+++ b/apps/docs/app/og/[...slug]/route.tsx
@@ -6,19 +6,13 @@ import { getPageImage } from '@/lib/metadata';
export const revalidate = false;
-export async function GET(
- _req: Request,
- { params }: RouteContext<'/og/[...slug]'>,
-) {
+export async function GET(_req: Request, { params }: RouteContext<'/og/[...slug]'>) {
const { slug } = await params;
const page = source.getPage(slug.slice(0, -1));
if (!page) notFound();
return new ImageResponse(
- ,
+ ,
await getImageResponseOptions(),
);
}
diff --git a/apps/docs/app/provider.tsx b/apps/docs/app/provider.tsx
index 78031f438..5fea3182c 100644
--- a/apps/docs/app/provider.tsx
+++ b/apps/docs/app/provider.tsx
@@ -32,10 +32,7 @@ export function Provider({ children }: { children: ReactNode }) {
}}
>
-
+
{children}
diff --git a/apps/docs/app/static.json/route.ts b/apps/docs/app/static.json/route.ts
index 638a2995b..382666b3f 100644
--- a/apps/docs/app/static.json/route.ts
+++ b/apps/docs/app/static.json/route.ts
@@ -28,8 +28,6 @@ export async function GET(): Promise {
});
return Response.json(
- (await Promise.all(promises)).filter(
- (v) => v !== undefined,
- ) as OramaDocument[],
+ (await Promise.all(promises)).filter((v) => v !== undefined) as OramaDocument[],
);
}
diff --git a/apps/docs/components/ai/markdown.tsx b/apps/docs/components/ai/markdown.tsx
index 7c2cddc3d..67c4902f9 100644
--- a/apps/docs/components/ai/markdown.tsx
+++ b/apps/docs/components/ai/markdown.tsx
@@ -55,10 +55,7 @@ export function rehypeWrapWords() {
}
function createProcessor(): Processor {
- const processor = remark()
- .use(remarkGfm)
- .use(remarkRehype)
- .use(rehypeWrapWords);
+ const processor = remark().use(remarkGfm).use(remarkRehype).use(rehypeWrapWords);
return {
async process(content) {
diff --git a/apps/docs/components/ai/page-actions.tsx b/apps/docs/components/ai/page-actions.tsx
index 5a67305bb..73241c4a1 100644
--- a/apps/docs/components/ai/page-actions.tsx
+++ b/apps/docs/components/ai/page-actions.tsx
@@ -1,20 +1,10 @@
'use client';
import { useMemo, useState } from 'react';
-import {
- Check,
- ChevronDown,
- Copy,
- ExternalLinkIcon,
- MessageCircleIcon,
-} from 'lucide-react';
+import { Check, ChevronDown, Copy, ExternalLinkIcon, MessageCircleIcon } from 'lucide-react';
import { cn } from '@/lib/cn';
import { useCopyButton } from 'fumadocs-ui/utils/use-copy-button';
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from 'fumadocs-ui/components/ui/popover';
+import { Popover, PopoverContent, PopoverTrigger } from 'fumadocs-ui/components/ui/popover';
import { cva } from 'class-variance-authority';
const cache = new Map();
@@ -88,9 +78,7 @@ export function ViewOptions({
}) {
const items = useMemo(() => {
const fullMarkdownUrl =
- typeof window !== 'undefined'
- ? new URL(markdownUrl, window.location.origin)
- : 'loading';
+ typeof window !== 'undefined' ? new URL(markdownUrl, window.location.origin) : 'loading';
const q = `Read ${fullMarkdownUrl}, I want to ask questions about it.`;
return [
diff --git a/apps/docs/components/ai/search.tsx b/apps/docs/components/ai/search.tsx
index ece5a8ee5..be9f6b6e0 100644
--- a/apps/docs/components/ai/search.tsx
+++ b/apps/docs/components/ai/search.tsx
@@ -41,11 +41,7 @@ function Header() {
Ask AI
@@ -112,9 +108,7 @@ function SearchAIActions() {
const StorageKeyInput = '__ai_search_input';
function SearchAIInput(props: ComponentProps<'form'>) {
const { status, sendMessage, stop } = useChatContext();
- const [input, setInput] = useState(
- () => localStorage.getItem(StorageKeyInput) ?? '',
- );
+ const [input, setInput] = useState(() => localStorage.getItem(StorageKeyInput) ?? '');
const isLoading = status === 'streaming' || status === 'submitted';
const onStart = (e?: SyntheticEvent) => {
e?.preventDefault();
@@ -129,11 +123,7 @@ function SearchAIInput(props: ComponentProps<'form'>) {
}, [isLoading]);
return (
-