From 183f76045174805c99bd1a216bcd77411ed7c410 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Sat, 12 Oct 2024 13:29:42 -0400 Subject: [PATCH 1/2] fix: rewrite 404 in middleware --- packages/ui/docs-bundle/src/middleware.ts | 17 ++++++++++++++++- packages/ui/docs-bundle/src/pages/404.tsx | 7 ++++++- .../src/server/extractNextDataPathname.ts | 6 ++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/ui/docs-bundle/src/middleware.ts b/packages/ui/docs-bundle/src/middleware.ts index b50b2628f0..15f24a3896 100644 --- a/packages/ui/docs-bundle/src/middleware.ts +++ b/packages/ui/docs-bundle/src/middleware.ts @@ -75,6 +75,21 @@ export const middleware: NextMiddleware = async (request) => { const pathname = extractNextDataPathname(request.nextUrl.pathname); + /** + * attempt to rewrite /404 and /_error data routes to the correct destination, + * otherwise nextjs will match to `__next_data_catchall`. + * + * this is important for `hardNavigate404` to work, because it relies on knowing that the destination is /404.json + */ + if ((pathname === "/404" || pathname === "/_error") && request.nextUrl.pathname.includes("/_next/data/")) { + const buildId = getBuildId(request); + nextUrl.pathname = `/_next/data/${buildId}${pathname}.json`; + if (nextUrl.pathname === request.nextUrl.pathname) { + return NextResponse.next({ request: { headers } }); + } + return NextResponse.rewrite(nextUrl, { request: { headers } }); + } + const fernToken = request.cookies.get(COOKIE_FERN_TOKEN); const authConfig = await getAuthEdgeConfig(xFernHost); let fernUser: FernUser | undefined; @@ -159,7 +174,7 @@ export const config = { * - _next/image (image optimization files) * - favicon.ico (favicon file) */ - "/((?!api/fern-docs|_next/static|_next/image|_next/data/:buildId/404.json|_next/data/:buildId/500.json|_vercel|favicon.ico).*)", + "/((?!api/fern-docs|_next/static|_next/image|_vercel|favicon.ico).*)", ], }; diff --git a/packages/ui/docs-bundle/src/pages/404.tsx b/packages/ui/docs-bundle/src/pages/404.tsx index 12138f9cf1..0f2390ffdc 100644 --- a/packages/ui/docs-bundle/src/pages/404.tsx +++ b/packages/ui/docs-bundle/src/pages/404.tsx @@ -1,10 +1,15 @@ import Error from "next/error"; -import { ReactElement } from "react"; +import { ReactElement, useEffect } from "react"; +import { capturePosthogEvent } from "../../../app/src/analytics/posthog"; /** * This is required for Next.js to generate `_next/static/chunks/pages/404.js` * Which helps prevent a client-side error to be thrown when navigating to a non-existent page */ export default function Page(): ReactElement { + useEffect(() => { + capturePosthogEvent("not_found"); + }); + return ; } diff --git a/packages/ui/docs-bundle/src/server/extractNextDataPathname.ts b/packages/ui/docs-bundle/src/server/extractNextDataPathname.ts index 0af5938d90..80cfdb91f3 100644 --- a/packages/ui/docs-bundle/src/server/extractNextDataPathname.ts +++ b/packages/ui/docs-bundle/src/server/extractNextDataPathname.ts @@ -7,6 +7,12 @@ * In both cases, we want to extract `/learn/home` */ export function extractNextDataPathname(pathname: string): string { + if (pathname.includes("/404.json")) { + return "/404"; + } else if (pathname.includes("/_error.json")) { + return "/_error"; + } + return ( removeIndex( pathname.match(/\/_next\/data\/.*\/_next\/data\/[^/]*(\/.*)\.json.json/)?.[1] ?? From 5b170cc1fe613af81ca51a8df29827d9b0aa4a17 Mon Sep 17 00:00:00 2001 From: Andrew Jiang Date: Sat, 12 Oct 2024 13:42:37 -0400 Subject: [PATCH 2/2] update imports --- packages/ui/app/src/analytics/posthog.ts | 3 +++ packages/ui/app/src/index.ts | 1 + packages/ui/docs-bundle/src/pages/404.tsx | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/ui/app/src/analytics/posthog.ts b/packages/ui/app/src/analytics/posthog.ts index b665469ff2..0ec95e5f0f 100644 --- a/packages/ui/app/src/analytics/posthog.ts +++ b/packages/ui/app/src/analytics/posthog.ts @@ -54,6 +54,9 @@ function ifCustomer(posthog: PostHog, run: (hog: PostHogWithCustomer) => void): export async function initializePosthog(api_host: string, customerConfig?: DocsV1Read.PostHogConfig): Promise { const apiKey = process.env.NEXT_PUBLIC_POSTHOG_API_KEY?.trim() ?? ""; + /** + * TODO: refactor this to use the posthog react provider + */ const posthog = (await import("posthog-js")).default; if (posthog.__loaded) { diff --git a/packages/ui/app/src/index.ts b/packages/ui/app/src/index.ts index 36cb881fcb..15ee6d21af 100644 --- a/packages/ui/app/src/index.ts +++ b/packages/ui/app/src/index.ts @@ -1,3 +1,4 @@ +export { capturePosthogEvent } from "./analytics/posthog"; export { type CustomerAnalytics } from "./analytics/types"; export type { DocsProps } from "./atoms"; export * from "./docs/DocsPage"; diff --git a/packages/ui/docs-bundle/src/pages/404.tsx b/packages/ui/docs-bundle/src/pages/404.tsx index 0f2390ffdc..a05aaa7068 100644 --- a/packages/ui/docs-bundle/src/pages/404.tsx +++ b/packages/ui/docs-bundle/src/pages/404.tsx @@ -1,6 +1,6 @@ +import { capturePosthogEvent } from "@fern-ui/ui"; import Error from "next/error"; import { ReactElement, useEffect } from "react"; -import { capturePosthogEvent } from "../../../app/src/analytics/posthog"; /** * This is required for Next.js to generate `_next/static/chunks/pages/404.js`