mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 08:03:30 +01:00
refactor: remove guide route prefix (#11146)
* refactor: remove guide route prefix * chore: implement backwards compat redirect * Change guide redirect destination and permanence Updated the redirect destination and permanence for the guide route. --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"pages": [
|
||||
"[MessageCircleQuestion][FAQ](/guide/legacy/popular-topics/faq)",
|
||||
"[ArrowDownToLine][Updating to v14](/guide/legacy/additional-info/changes-in-v14)",
|
||||
"[MessageCircleQuestion][FAQ](/legacy/popular-topics/faq)",
|
||||
"[ArrowDownToLine][Updating to v14](/legacy/additional-info/changes-in-v14)",
|
||||
"[LibraryBig][Documentation](https://discord.js.org/docs)",
|
||||
"[Info][Introduction](/guide/legacy)",
|
||||
"[Info][Introduction](/legacy)",
|
||||
"---Setup---",
|
||||
"preparations",
|
||||
"---Your App---",
|
||||
|
||||
@@ -8,7 +8,7 @@ export async function generateStaticParams() {
|
||||
return source.generateParams();
|
||||
}
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ slug?: string[] }> }) {
|
||||
export async function generateMetadata(props: { params: Promise<{ slug?: string[] }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const page = source.getPage(params.slug);
|
||||
|
||||
@@ -16,7 +16,7 @@ export async function generateMetadata(props: { params: Promise<{ slug?: string[
|
||||
notFound();
|
||||
}
|
||||
|
||||
const image = ['/docs-og', ...(params.slug ?? []), 'image.png'].join('/');
|
||||
const image = ['/og', ...(params.slug ?? []), 'image.png'].join('/');
|
||||
return {
|
||||
title: page.data.title,
|
||||
description: page.data.description,
|
||||
@@ -27,7 +27,7 @@ export async function generateMetadata(props: { params: Promise<{ slug?: string[
|
||||
card: 'summary_large_image',
|
||||
images: image,
|
||||
},
|
||||
} satisfies Metadata;
|
||||
};
|
||||
}
|
||||
|
||||
export default async function Page(props: { readonly params: Promise<{ slug?: string[] }> }) {
|
||||
@@ -1,42 +0,0 @@
|
||||
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
||||
import type { CSSProperties, ReactNode } from 'react';
|
||||
import { baseOptions } from '@/app/layout.config';
|
||||
import { source } from '@/lib/source';
|
||||
|
||||
export default function Layout({ children }: { readonly children: ReactNode }) {
|
||||
return (
|
||||
<DocsLayout
|
||||
sidebar={{
|
||||
tabs: {
|
||||
transform(option, node) {
|
||||
const meta = source.getNodeMeta(node);
|
||||
if (!meta || !node.icon) return option;
|
||||
|
||||
// category selection color based on path src/styles/base.css
|
||||
const color = `var(--${meta.path.split('/')[0]}-color, var(--color-fd-foreground))`;
|
||||
|
||||
return {
|
||||
...option,
|
||||
icon: (
|
||||
<div
|
||||
className="size-full rounded-lg text-(--tab-color) max-md:border max-md:bg-(--tab-color)/10 max-md:p-1.5 [&_svg]:size-full"
|
||||
style={
|
||||
{
|
||||
'--tab-color': color,
|
||||
} as CSSProperties
|
||||
}
|
||||
>
|
||||
{node.icon}
|
||||
</div>
|
||||
),
|
||||
};
|
||||
},
|
||||
},
|
||||
}}
|
||||
tree={source.pageTree}
|
||||
{...baseOptions}
|
||||
>
|
||||
{children}
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
import { Analytics } from '@vercel/analytics/react';
|
||||
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
||||
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 type { CSSProperties, PropsWithChildren } from 'react';
|
||||
import { Body } from '@/app/layout.client';
|
||||
import { source } from '@/lib/source';
|
||||
import { ENV } from '@/util/env';
|
||||
import { baseOptions } from './layout.config';
|
||||
|
||||
import '@/styles/base.css';
|
||||
|
||||
@@ -18,7 +21,7 @@ export const viewport: Viewport = {
|
||||
};
|
||||
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL(ENV.IS_LOCAL_DEV ? `http://localhost:${ENV.PORT}` : 'https://next.discordjs.guide'),
|
||||
metadataBase: new URL(ENV.IS_LOCAL_DEV ? `http://localhost:${ENV.PORT}` : 'https://discordjs.guide'),
|
||||
title: {
|
||||
template: '%s | discord.js',
|
||||
default: 'discord.js',
|
||||
@@ -74,7 +77,41 @@ export default async function RootLayout({ children }: PropsWithChildren) {
|
||||
return (
|
||||
<html className={`${GeistSans.variable} ${GeistMono.variable} antialiased`} lang="en" suppressHydrationWarning>
|
||||
<Body>
|
||||
<RootProvider>{children}</RootProvider>
|
||||
<RootProvider>
|
||||
<DocsLayout
|
||||
sidebar={{
|
||||
tabs: {
|
||||
transform(option, node) {
|
||||
const meta = source.getNodeMeta(node);
|
||||
if (!meta || !node.icon) return option;
|
||||
|
||||
// category selection color based on path src/styles/base.css
|
||||
const color = `var(--${meta.path.split('/')[0]}-color, var(--color-fd-foreground))`;
|
||||
|
||||
return {
|
||||
...option,
|
||||
icon: (
|
||||
<div
|
||||
className="size-full rounded-lg text-(--tab-color) max-md:border max-md:bg-(--tab-color)/10 max-md:p-1.5 [&_svg]:size-full"
|
||||
style={
|
||||
{
|
||||
'--tab-color': color,
|
||||
} as CSSProperties
|
||||
}
|
||||
>
|
||||
{node.icon}
|
||||
</div>
|
||||
),
|
||||
};
|
||||
},
|
||||
},
|
||||
}}
|
||||
tree={source.pageTree}
|
||||
{...baseOptions}
|
||||
>
|
||||
{children}
|
||||
</DocsLayout>
|
||||
</RootProvider>
|
||||
<Analytics />
|
||||
</Body>
|
||||
</html>
|
||||
|
||||
@@ -12,7 +12,7 @@ export function generateStaticParams() {
|
||||
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), {
|
||||
// const fontData = await fetch(new URL('../../assets/Geist-Regular.ttf', import.meta.url), {
|
||||
// next: { revalidate: 604_800 },
|
||||
// }).then(async (res) => res.arrayBuffer());
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
export default async function Page() {
|
||||
redirect('/guide/legacy');
|
||||
}
|
||||
@@ -15,6 +15,6 @@ export const source = loader({
|
||||
|
||||
return undefined;
|
||||
},
|
||||
baseUrl: '/guide/',
|
||||
baseUrl: '/',
|
||||
source: docs.toFumadocsSource(),
|
||||
});
|
||||
|
||||
16
apps/guide/src/middleware.ts
Normal file
16
apps/guide/src/middleware.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { NextResponse, type NextRequest } from 'next/server';
|
||||
|
||||
export function middleware(request: NextRequest) {
|
||||
// TODO: Remove this eventually
|
||||
if (request.nextUrl.pathname.startsWith('/guide/')) {
|
||||
const newUrl = request.nextUrl.clone();
|
||||
newUrl.pathname = newUrl.pathname.replace('/guide/', '/');
|
||||
return NextResponse.redirect(new URL(newUrl.pathname, request.url));
|
||||
}
|
||||
|
||||
return NextResponse.redirect(new URL('/legacy', request.url));
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ['/', '/guide/:path*'],
|
||||
};
|
||||
@@ -39,8 +39,8 @@ export default {
|
||||
},
|
||||
{
|
||||
source: '/guide/:path*',
|
||||
destination: 'https://next.discordjs.guide/guide/:path*',
|
||||
permanent: true,
|
||||
destination: 'https://discordjs.guide/:path*',
|
||||
permanent: false,
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user