From f23e1813dd52451efb2d9575f8d9e823579d32e7 Mon Sep 17 00:00:00 2001 From: Mike Hartington Date: Thu, 2 Apr 2026 10:08:25 -0400 Subject: [PATCH] feat(site): next-config --- apps/site/next.config.mjs | 585 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 585 insertions(+) diff --git a/apps/site/next.config.mjs b/apps/site/next.config.mjs index 326f4938ad..aea18a0417 100644 --- a/apps/site/next.config.mjs +++ b/apps/site/next.config.mjs @@ -2,6 +2,39 @@ import { createMDX } from "fumadocs-mdx/next"; const withMDX = createMDX(); +const DOCS_ORIGIN = process.env.NEXT_DOCS_ORIGIN || "https://docs.prisma.io"; +const DOCS_ORIGIN_HOST = (() => { + try { + return new URL(DOCS_ORIGIN).hostname; + } catch { + return "docs.prisma.io"; + } +})(); + +const BLOG_ORIGIN = process.env.NEXT_BLOG_ORIGIN || "https://blog.prisma.io"; +const BLOG_ORIGIN_HOST = (() => { + try { + return new URL(BLOG_ORIGIN).hostname; + } catch { + return "blog.prisma.io"; + } +})(); + +if ( + process.env.NODE_ENV === "production" && + (!process.env.NEXT_DOCS_ORIGIN || !process.env.NEXT_BLOG_ORIGIN) +) { + throw new Error( + [ + !process.env.NEXT_DOCS_ORIGIN && "DOCS_ORIGIN is required in production", + !process.env.NEXT_BLOG_ORIGIN && "BLOG_ORIGIN is required in production", + ] + .filter(Boolean) + .join("; ") + ); +} + + const ContentSecurityPolicy = ` default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' @@ -233,6 +266,558 @@ const config = { ], }, transpilePackages: ["@prisma/eclipse"], + async redirects() { + return [ + { + source: "/:path*", + has: [ + { + type: "host", + value: "prisma.studio", + }, + ], + destination: "https://www.prisma.io/studio", + permanent: true, + }, + { + source: "/:path*", + has: [ + { + type: "host", + value: "prismagraphql.com", + }, + ], + destination: "https://www.prisma.io/:path*", + permanent: true, + }, + { + source: "/:path*", + has: [ + { + type: "host", + value: "prisma.sh", + }, + ], + destination: "https://www.prisma.io/:path*", + permanent: true, + }, + { + source: "/:path*", + has: [ + { + type: "host", + value: "jobs.prisma.io", + }, + ], + destination: "https://www.prisma.io/careers", + permanent: true, + }, + { + source: "/:path*", + has: [ + { + type: "host", + value: "careers.prisma.io", + }, + ], + destination: "https://www.prisma.io/careers", + permanent: true, + }, + { + source: "/:path*", + has: [ + { + type: "host", + value: "dataguide.prisma.io", + }, + ], + destination: "https://www.prisma.io/dataguide", + permanent: true, + }, + { + source: "/:path*", + has: [ + { + type: "host", + value: "slack.prisma.io", + }, + ], + destination: "https://pris.ly/discord", + permanent: true, + }, + { + permanent: true, + source: "/blog/introducing-graphql-playground-f1e0a018f05d", + destination: "/blog/prisma-and-graphql-mfl5y2r7t49c", + }, + { + permanent: true, + source: "/blog/introduction-to-databases-jmt9jwidtc2a", + destination: "https://www.prisma.io/dataguide/intro/what-are-databases", + }, + { + permanent: true, + source: "/blog/comparison-of-database-models-1iz9u29nwn37", + destination: + "https://www.prisma.io/dataguide/intro/comparing-database-types", + }, + { + permanent: true, + source: "/blog/comparing-sql-query-builders-and-orms-dkuixe3aa5a2", + destination: + "https://www.prisma.io/dataguide/types/relational/comparing-sql-query-builders-and-orms", + }, + { + permanent: true, + source: "/tutorials/postgres-why-choose-postgres-db08", + destination: + "https://www.prisma.io/dataguide/postgresql/benefits-of-postgresql", + }, + { + permanent: true, + source: "/blog/ways-to-host-postgresql-w0xrhqqgp4zp", + destination: + "https://www.prisma.io/dataguide/postgresql/5-ways-to-host-postgresql", + }, + { + permanent: true, + source: "/tutorials/postgres-connecting-to-databases-db05", + destination: + "https://www.prisma.io/dataguide/postgresql/connecting-to-postgresql-databases", + }, + { + permanent: true, + source: "/tutorials/postgres-configuring-user-authentication-db06", + destination: + "https://www.prisma.io/dataguide/postgresql/configuring-user-authentication", + }, + { + permanent: true, + source: "/tutorials/postgres-create-databases-and-tables-db01", + destination: + "https://www.prisma.io/dataguide/postgresql/create-and-delete-databases-and-tables", + }, + { + permanent: true, + source: "/tutorials/postgres-introduction-to-data-types-db02", + destination: + "https://www.prisma.io/dataguide/postgresql/introduction-to-data-types", + }, + { + permanent: true, + source: + "/tutorials/postgres-introduction-to-column-and-table-constraints-db03", + destination: + "https://www.prisma.io/dataguide/postgresql/column-and-table-constraints", + }, + { + permanent: true, + source: "/blog/modern-backend-1-tsjs1ps7kip1", + destination: + "/blog/backend-prisma-typescript-orm-with-postgresql-data-modeling-tsjs1ps7kip1", + }, + { + permanent: true, + source: "/blog/modern-backend-2-dcba1ps7kip3", + destination: + "/blog/backend-prisma-typescript-orm-with-postgresql-rest-api-validation-dcba1ps7kip3", + }, + { + permanent: false, + source: "/blog/prisma-the-complete-orm-inw24qjeawmb", + destination: + "https://www.prisma.io/docs/orm/overview/introduction/why-prisma", + }, + { + permanent: true, + source: "/forum/:any*", + destination: "https://v1.prisma.io/forum/:any*", + }, + { + permanent: true, + source: "/tutorials/:any*", + destination: "https://v1.prisma.io/tutorials/:any*", + }, + { + permanent: true, + source: "/docs/1.:any*/:any2*", + destination: "https://v1.prisma.io/docs/1.:any*/:any2*", + }, + { + permanent: true, + source: "/admin", + destination: "https://github.com/prisma/studio", + }, + { + permanent: true, + source: "/with-db-microservices", + destination: "https://www.prisma.io", + }, + { + permanent: true, + source: "/with-graphql", + destination: "/docs/understand-prisma/prisma-in-your-stack/graphql", + }, + { + permanent: true, + source: "/with-rest", + destination: "/docs/understand-prisma/prisma-in-your-stack/rest", + }, + { + permanent: true, + source: "/client/client-javascript", + destination: "/docs/reference/tools-and-interfaces/prisma-client/api", + }, + { + permanent: true, + source: "/client/client-typescript", + destination: "/docs/reference/tools-and-interfaces/prisma-client/api", + }, + { + permanent: true, + source: "/client/client-go", + destination: "https://github.com/prisma/prisma-client-go", + }, + { + permanent: true, + source: "/features/bindings", + destination: "/docs/understand-prisma/prisma-in-your-stack/graphql", + }, + { + permanent: true, + source: "/features/data-modeling", + destination: "/docs/understand-prisma/data-modeling", + }, + { + permanent: true, + source: "/features/databases", + destination: "/docs/more/supported-databases", + }, + { + permanent: true, + source: "/features/graphql-api", + destination: "/docs/understand-prisma/prisma-in-your-stack/graphql", + }, + { + permanent: true, + source: "/features/query-engine", + destination: "/docs/understand-prisma/prisma-in-your-stack/graphql", + }, + { + permanent: true, + source: "/blog/prisma-admin-beta-pai5lah43soe", + destination: "https://github.com/prisma/studio", + }, + { + permanent: true, + source: "/blog/mongodb-preview-ow4wahkekaep", + destination: "https://github.com/prisma/prisma/issues/1277", + }, + { + permanent: true, + source: "/blog/heroku-integration-homihof6eifi", + destination: + "https://www.prisma.io/docs/orm/prisma-client/deployment/traditional/deploy-to-heroku", + }, + { + permanent: true, + source: "/blog/prisma-now-supports-postgres-aad74ba479cb", + destination: + "https://www.prisma.io/docs/orm/overview/databases/postgresql", + }, + { + permanent: true, + source: + "/blog/introducing-prisma-cloud-a-graphql-database-platform-ed591baa8737", + destination: "https://www.prisma.io/cloud", + }, + { + permanent: true, + source: "/blog/introducing-prisma-1ff423fd629e", + destination: + "https://www.prisma.io/blog/announcing-prisma-2-n0v98rzc8br1", + }, + { + permanent: true, + source: "/dataguide/postgresql/configuring-user-authentication", + destination: + "/dataguide/postgresql/authentication-and-authorization/configuring-user-authentication", + }, + { + permanent: true, + source: + "/dataguide/database-tools/top-nodejs-orms-query-builders-and-database-libraries-in-2020", + destination: + "/dataguide/database-tools/top-nodejs-orms-query-builders-and-database-libraries", + }, + { + source: "/dataplatform/:any*", + destination: "/data-platform/:any*", + permanent: true, + }, + { + source: "/data-platform/accelerate", + destination: "/accelerate", + permanent: true, + }, + { + source: "/data-platform/pulse", + destination: "/pulse", + permanent: true, + }, + { + source: "/data-platform/optimize", + destination: "/optimize", + permanent: true, + }, + { + source: "/data-platform", + destination: "https://console.prisma.io", + permanent: true, + }, + { + source: "/optimise", + destination: "/optimize", + permanent: true, + }, + { + source: "/prisma-enterprise", + destination: "/enterprise", + permanent: true, + }, + { + source: "/prisma-in-your-ecosystem", + destination: "/stack", + permanent: true, + }, + { + source: "/prisma-in-your-stack", + destination: "/stack", + permanent: true, + }, + { + source: "/jobs", + destination: "/careers", + permanent: true, + }, + { + source: "/cloud", + destination: "https://app.prisma.io", + permanent: true, + }, + { + source: "/mongodblaunch", + destination: "/mongodb", + permanent: true, + }, + { + source: "/mongodb-launch", + destination: "/mongodb", + permanent: true, + }, + { + source: "/turso", + destination: "https://pris.ly/turso", + permanent: false, + }, + { + source: "/ambassador", + destination: "/partners", + permanent: true, + }, + { + source: "/changelogs", + destination: "/changelog", + permanent: true, + }, + { + source: "/login", + destination: "https://console.prisma.io/login", + permanent: true, + }, + { + source: "/sign-up", + destination: "https://console.prisma.io/sign-up", + permanent: true, + }, + { + source: "/pulse", + destination: "/postgres", + permanent: true, + }, + { + source: "/blog/prisma-studio-3rtf78dg99fe", + destination: "/docs/orm/tools/prisma-studio", + permanent: true, + }, + { + source: "/blog/fullstack-remix-prisma-mongodb-1-7D0BfTXBmB6r", + destination: "/docs/guides/react-router-7", + permanent: true, + }, + { + source: "/blog/series/fullstack-nextjs-and-graphql-md1tczpfz1", + destination: "/docs/guides/nextjs", + permanent: true, + }, + { + source: "/blog/performance-engineering-aeduv0rei0jk", + destination: "/blog/optimize-now-generally-available", + permanent: true, + }, + { + source: "/learn", + destination: "/docs/guides", + permanent: false, + }, + { + source: "/:path*", // Match all routes under playground.prisma.io + has: [ + { + type: "host", + value: "playground.prisma.io", + }, + ], + destination: "https://prisma.io/playground", // Redirect everything to this URL + permanent: false, // Use true for a 301 permanent redirect + }, + { + permanent: true, + source: "/blog/build-a-video-processing-pipeline", + destination: "https://www.prisma.io/docs/postgres", + }, + { + permanent: true, + source: + "/blog/build-real-time-durable-workflows-with-pulse-and-inngest", + destination: "https://www.prisma.io/docs/postgres", + }, + { + permanent: true, + source: "/blog/increased-security-static-ip-support-prisma-pulse", + destination: "https://www.prisma.io/docs/postgres", + }, + { + permanent: true, + source: "/blog/increased-security-static-ip-support-prisma-pulse", + destination: "https://www.prisma.io/docs/postgres", + }, + { + permanent: true, + source: + "/blog/prisma-pulse-introducing-delivery-guarantees-for-database-change-events", + destination: "https://www.prisma.io/docs/postgres", + }, + { + permanent: true, + source: "/blog/introducing-pulse-jtu4UPC8ujy4", + destination: "https://www.prisma.io/docs/postgres", + }, + { + permanent: true, + source: + "/blog/build-a-real-time-app-with-nextjs-socketio-and-prisma-postgres", + destination: "https://www.prisma.io/docs/postgres", + }, + { + permanent: true, + source: "/blog/prisma-pulse-in-general-availability", + destination: "https://www.prisma.io/docs/postgres", + }, + { + permanent: false, + source: "/affiliates", + destination: "/", + }, + { + permanent: true, + source: "/react-server-components", + destination: "/react", + }, + { + permanent: false, + source: "/partners/affiliates", + destination: "/", + }, + ]; + }, + + async rewrites() { + return { + beforeFiles: [ + // subdomains + { + source: "/:path*", + has: [ + { + type: "host", + value: "accelerate-speed-test.prisma.io", + }, + ], + destination: "https://accelerate-speed-test.vercel.app/:path*", + }, + + + // Proxy canonical docs path to docs infrastructure + { + source: "/docs", + destination: `${DOCS_ORIGIN}/docs`, + missing: [{ type: "host", value: DOCS_ORIGIN_HOST }], + }, + { + source: "/docs/:any*", + destination: `${DOCS_ORIGIN}/docs/:any*`, + missing: [{ type: "host", value: DOCS_ORIGIN_HOST }], + }, + { + source: "/docs-static/:path*", + destination: `${DOCS_ORIGIN}/docs-static/:path*`, + missing: [{ type: "host", value: DOCS_ORIGIN_HOST }], + }, + + // Proxy canonical blog path to blog infrastructure + { + source: "/blog", + destination: `${BLOG_ORIGIN}/blog`, + missing: [{ type: "host", value: BLOG_ORIGIN_HOST }], + }, + { + source: "/blog/:any*", + destination: `${BLOG_ORIGIN}/blog/:any*`, + missing: [{ type: "host", value: BLOG_ORIGIN_HOST }], + }, + { + source: "/blog-static/:path*", + destination: `${BLOG_ORIGIN}/blog-static/:path*`, + missing: [{ type: "host", value: BLOG_ORIGIN_HOST }], + }, + ], + fallback: [ + // Files + { + source: "/ga.js", + destination: "https://www.google-analytics.com/analytics.js", + }, + { + source: "/gastats.js", + destination: "https://www.google-analytics.com/analytics.js", + }, + + // Pages + // TODO We have a redirect for this above to /careers, so should probably be removed here? + + + { + source: "/dataguide/:any*", + destination: "https://dataguide.vercel.app/dataguide/:any*", + }, + // { + // source: "/rss.xml", + // destination: "https://prismablog.vercel.app/blog/rss.xml", + // } + ], + }; + }, async headers() { return [ {