From 8a358d7f9b3037eda3402d022670887bf579336c Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Mon, 19 May 2025 23:46:37 +0900 Subject: [PATCH 1/2] Revert "remove unused Next.js redirects, use `_redirects` file instead." This reverts commit ba12573e18c6b02c4dcae15699bcad0a3b09953d. --- next.config.mjs | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/next.config.mjs b/next.config.mjs index 7aba6c534..0c83aa16e 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -84,6 +84,70 @@ const config = { config.plugins.push(new ProvidePlugin({ React: "react" })); return config; }, + async redirects() { + return [ + { + source: "/community", + destination: "/community/overview", + permanent: true, + }, + { + source: "/bucklescript-rebranding", + destination: "/blog/bucklescript-is-rebranding", + permanent: true, + }, + { + source: "/docs/manual/latest/migrate-from-bucklescript-reason", + destination: "/docs/manual/v10.0.0/migrate-from-bucklescript-reason", + permanent: true, + }, + { + source: "/docs/manual/latest/unboxed", + destination: "/docs/manual/v10.0.0/unboxed", + permanent: true, + }, + { + source: "/docs/gentype/latest/introduction", + destination: "/docs/manual/latest/typescript-integration", + permanent: true, + }, + { + source: "/docs/gentype/latest/getting-started", + destination: "/docs/manual/latest/typescript-integration", + permanent: true, + }, + { + source: "/docs/gentype/latest/usage", + destination: "/docs/manual/latest/typescript-integration", + permanent: true, + }, + { + source: "/docs/gentype/latest/supported-types", + destination: "/docs/manual/latest/typescript-integration", + permanent: true, + }, + { + source: "/docs/manual/latest/:slug*", + destination: `/docs/manual/${process.env.VERSION_LATEST}/:slug*`, + permanent: false, + }, + { + source: "/docs/manual/next/:slug*", + destination: `/docs/manual/${process.env.VERSION_NEXT}/:slug*`, + permanent: false, + }, + { + source: "/llms/manual/latest/:file*", + destination: `/llms/manual/${process.env.VERSION_LATEST}/:file*`, + permanent: false, + }, + { + source: "/llms/manual/next/:file*", + destination: `/llms/manual/${process.env.VERSION_NEXT}/:file*`, + permanent: false, + }, + ]; + }, }; export default { From 2f524898bc2363559322ad84bb9f94d5a6a8a94f Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Tue, 20 May 2025 00:13:22 +0900 Subject: [PATCH 2/2] Sync Next.js redirects to Cloudflare --- next.config.mjs | 38 +++++++++++++++++++++++++++++++++----- public/_redirects | 18 +++++++----------- scripts/sync-redirects.mjs | 25 +++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 scripts/sync-redirects.mjs diff --git a/next.config.mjs b/next.config.mjs index 0c83aa16e..960623f38 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,5 +1,8 @@ -// @ts-check -import fs from "fs"; +// @ ts-check + +import * as assert from "node:assert/strict"; +import * as path from "node:path"; +import * as fs from "node:fs/promises"; import webpack from "webpack"; import rehypeSlug from "rehype-slug"; import remarkGfm from "remark-gfm"; @@ -8,14 +11,15 @@ import remarkFrontmatter from "remark-frontmatter"; import remarkMdxFrontmatter from "remark-mdx-frontmatter"; import { createLoader } from "simple-functional-loader"; -const bsconfig = JSON.parse(fs.readFileSync("./rescript.json").toString()); +const bsconfig = JSON.parse((await fs.readFile("./rescript.json", "utf8")).toString()); const { ProvidePlugin } = webpack; const transpileModules = ["rescript"].concat(bsconfig["bs-dependencies"]); +/** @type {import("next").NextConfig} */ const config = { - output: "export", + output: process.env.NODE_ENV === "production" ? "export" : undefined, pageExtensions: ["jsx", "js", "bs.js", "mdx", "mjs"], env: { ENV: process.env.NODE_ENV, @@ -85,7 +89,7 @@ const config = { return config; }, async redirects() { - return [ + const redirects = [ { source: "/community", destination: "/community/overview", @@ -126,6 +130,8 @@ const config = { destination: "/docs/manual/latest/typescript-integration", permanent: true, }, + ]; + const splatRedirects = [ { source: "/docs/manual/latest/:slug*", destination: `/docs/manual/${process.env.VERSION_LATEST}/:slug*`, @@ -147,6 +153,28 @@ const config = { permanent: false, }, ]; + + const redirectsFile = path.join(import.meta.dirname, "public/_redirects"); + await fs.writeFile( + redirectsFile, + redirects + .map(({ source, destination, permanent }) => { + return `${source} ${destination} ${permanent ? 308 : 307}`; + }) + .join("\n") + + "\n" + + splatRedirects + .map(({ source, destination, permanent }) => { + const splatPattern = /:(\w+)\*$/; + assert.match(source, splatPattern); + assert.match(destination, splatPattern); + return `${source.replace(splatPattern, "*")} ${destination.replace(splatPattern, ":splat")} ${permanent ? 308 : 307}`; + }) + .join("\n"), + "utf8", + ); + + return [...redirects, ...splatRedirects]; }, }; diff --git a/public/_redirects b/public/_redirects index 0eaa09717..abaab5625 100644 --- a/public/_redirects +++ b/public/_redirects @@ -1,16 +1,12 @@ /community /community/overview 308 - /bucklescript-rebranding /blog/bucklescript-is-rebranding 308 - /docs/manual/latest/migrate-from-bucklescript-reason /docs/manual/v10.0.0/migrate-from-bucklescript-reason 308 -/docs/manual/latest/unboxed /docs/manual/v10.0.0/unboxed 308 -/docs/gentype/latest/introduction /docs/manual/latest/typescript-integration 308 -/docs/gentype/latest/getting-started /docs/manual/latest/typescript-integration 308 -/docs/gentype/latest/usage /docs/manual/latest/typescript-integration 308 -/docs/gentype/latest/supported-types /docs/manual/latest/typescript-integration 308 - +/docs/manual/latest/unboxed /docs/manual/v10.0.0/unboxed 308 +/docs/gentype/latest/introduction /docs/manual/latest/typescript-integration 308 +/docs/gentype/latest/getting-started /docs/manual/latest/typescript-integration 308 +/docs/gentype/latest/usage /docs/manual/latest/typescript-integration 308 +/docs/gentype/latest/supported-types /docs/manual/latest/typescript-integration 308 /docs/manual/latest/* /docs/manual/v11.0.0/:splat 307 +/docs/manual/next/* /docs/manual/v12.0.0/:splat 307 /llms/manual/latest/* /llms/manual/v11.0.0/:splat 307 - -/docs/manual/next/* /docs/manual/v12.0.0/:splat 307 -/llms/manual/next/* /llms/manual/v12.0.0/:splat 307 +/llms/manual/next/* /llms/manual/v12.0.0/:splat 307 \ No newline at end of file diff --git a/scripts/sync-redirects.mjs b/scripts/sync-redirects.mjs new file mode 100644 index 000000000..566d842bc --- /dev/null +++ b/scripts/sync-redirects.mjs @@ -0,0 +1,25 @@ +import * as path from "node:path"; +import * as fs from "node:fs"; + +import nextConfig from "../next.config.mjs"; + +const redirectsConfig = await nextConfig.redirects(); + +/** + * @param {{ + * source: string, + * destination: string, + * permanent: boolean, + * }} config + * @return {string} + */ +function lineFormat({ + source, + destination, + permanent, +}) { + return `${source} ${destination} ${permanent ? 308 : 307}`; +} + +const redirects = redirectsConfig.map(lineFormat).join("\n"); +const redirectsFile = path.join(import.meta.dirname, "../public/_redirects");