mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-13 18:13:29 +01:00
docs: guide setup (#10862)
This commit is contained in:
4
apps/guide/src/app/api/search/route.ts
Normal file
4
apps/guide/src/app/api/search/route.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { createFromSource } from 'fumadocs-core/search/server';
|
||||
import { source } from '@/lib/source';
|
||||
|
||||
export const { GET } = createFromSource(source);
|
||||
36
apps/guide/src/app/docs-og/[...slug]/route.tsx
Normal file
36
apps/guide/src/app/docs-og/[...slug]/route.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { generateOGImage } from 'fumadocs-ui/og';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { source } from '@/lib/source';
|
||||
|
||||
export function generateStaticParams() {
|
||||
return source.generateParams().map((page) => ({
|
||||
...page,
|
||||
slug: [...page.slug, 'image.png'],
|
||||
}));
|
||||
}
|
||||
|
||||
export async function GET(_req: Request, { params }: { params: Promise<{ slug: string[] }> }) {
|
||||
const { slug } = await params;
|
||||
const page = source.getPage(slug.slice(0, -1));
|
||||
// const fontData = await fetch(new URL('../../../assets/Geist-Regular.ttf', import.meta.url), {
|
||||
// next: { revalidate: 604_800 },
|
||||
// }).then(async (res) => res.arrayBuffer());
|
||||
|
||||
if (!page) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
return generateOGImage({
|
||||
title: page.data.title,
|
||||
description: page.data.description,
|
||||
site: 'discord.js Guide',
|
||||
// fonts: [
|
||||
// {
|
||||
// name: 'Geist',
|
||||
// data: fontData,
|
||||
// weight: 900,
|
||||
// style: 'normal',
|
||||
// },
|
||||
// ],
|
||||
});
|
||||
}
|
||||
53
apps/guide/src/app/guide/[[...slug]]/page.tsx
Normal file
53
apps/guide/src/app/guide/[[...slug]]/page.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page';
|
||||
import type { Metadata } from 'next';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { source } from '@/lib/source';
|
||||
import { getMDXComponents } from '@/mdx-components';
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return source.generateParams();
|
||||
}
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ slug?: string[] }> }) {
|
||||
const params = await props.params;
|
||||
const page = source.getPage(params.slug);
|
||||
|
||||
if (!page) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const image = ['/docs-og', ...(params.slug ?? []), 'image.png'].join('/');
|
||||
return {
|
||||
title: page.data.title,
|
||||
description: page.data.description,
|
||||
openGraph: {
|
||||
images: image,
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
images: image,
|
||||
},
|
||||
} satisfies Metadata;
|
||||
}
|
||||
|
||||
export default async function Page(props: { readonly params: Promise<{ slug?: string[] }> }) {
|
||||
const params = await props.params;
|
||||
const page = source.getPage(params.slug);
|
||||
|
||||
if (!page) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const MDX = page.data.body;
|
||||
|
||||
return (
|
||||
<DocsPage full={page.data.full!} toc={page.data.toc}>
|
||||
<DocsTitle>{page.data.title}</DocsTitle>
|
||||
<DocsDescription>{page.data.description}</DocsDescription>
|
||||
<DocsBody>
|
||||
{/* eslint-disable-next-line @stylistic/jsx/jsx-pascal-case */}
|
||||
<MDX components={getMDXComponents()} />
|
||||
</DocsBody>
|
||||
</DocsPage>
|
||||
);
|
||||
}
|
||||
12
apps/guide/src/app/guide/layout.tsx
Normal file
12
apps/guide/src/app/guide/layout.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
||||
import type { ReactNode } from 'react';
|
||||
import { baseOptions } from '@/app/layout.config';
|
||||
import { source } from '@/lib/source';
|
||||
|
||||
export default function Layout({ children }: { readonly children: ReactNode }) {
|
||||
return (
|
||||
<DocsLayout tree={source.pageTree} {...baseOptions}>
|
||||
{children}
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
7
apps/guide/src/app/layout.config.tsx
Normal file
7
apps/guide/src/app/layout.config.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
|
||||
|
||||
export const baseOptions: BaseLayoutProps = {
|
||||
nav: {
|
||||
title: 'discord.js Guide',
|
||||
},
|
||||
};
|
||||
81
apps/guide/src/app/layout.tsx
Normal file
81
apps/guide/src/app/layout.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import { Analytics } from '@vercel/analytics/react';
|
||||
import { RootProvider } from 'fumadocs-ui/provider';
|
||||
import { GeistMono } from 'geist/font/mono';
|
||||
import { GeistSans } from 'geist/font/sans';
|
||||
import type { Metadata, Viewport } from 'next';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import { ENV } from '@/util/env';
|
||||
|
||||
import '@/styles/base.css';
|
||||
|
||||
export const viewport: Viewport = {
|
||||
themeColor: [
|
||||
{ media: '(prefers-color-scheme: light)', color: '#fbfbfb' },
|
||||
{ media: '(prefers-color-scheme: dark)', color: '#1a1a1e' },
|
||||
],
|
||||
colorScheme: 'light dark',
|
||||
};
|
||||
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL(ENV.IS_LOCAL_DEV ? `http://localhost:${ENV.PORT}` : 'https://discord.js.org'),
|
||||
title: {
|
||||
template: '%s | discord.js',
|
||||
default: 'discord.js',
|
||||
},
|
||||
icons: {
|
||||
other: [
|
||||
{
|
||||
url: '/favicon-32x32.png',
|
||||
sizes: '32x32',
|
||||
type: 'image/png',
|
||||
},
|
||||
{
|
||||
url: '/favicon-16x16.png',
|
||||
sizes: '16x16',
|
||||
type: 'image/png',
|
||||
},
|
||||
],
|
||||
apple: [
|
||||
'/apple-touch-icon.png',
|
||||
{
|
||||
url: '/safari-pinned-tab.svg',
|
||||
rel: 'mask-icon',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
manifest: '/site.webmanifest',
|
||||
|
||||
appleWebApp: {
|
||||
title: 'discord.js',
|
||||
},
|
||||
|
||||
applicationName: 'discord.js',
|
||||
|
||||
openGraph: {
|
||||
siteName: 'discord.js',
|
||||
type: 'website',
|
||||
title: 'discord.js',
|
||||
images: 'https://discordjs.dev/api/open-graph.png',
|
||||
},
|
||||
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
creator: '@iCrawlToGo',
|
||||
},
|
||||
|
||||
other: {
|
||||
'msapplication-TileColor': '#1a1a1e',
|
||||
},
|
||||
};
|
||||
|
||||
export default async function RootLayout({ children }: PropsWithChildren) {
|
||||
return (
|
||||
<html className={`${GeistSans.variable} ${GeistMono.variable} antialiased`} lang="en" suppressHydrationWarning>
|
||||
<body className="overscroll-y-none">
|
||||
<RootProvider>{children}</RootProvider>
|
||||
<Analytics />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user