diff --git a/apps/web/src/global-error.tsx b/apps/web/src/global-error.tsx
new file mode 100644
index 000000000..cadf38e40
--- /dev/null
+++ b/apps/web/src/global-error.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+import * as Sentry from "@sentry/nextjs";
+import NextError from "next/error";
+import React from "react";
+
+export default function GlobalError({
+ error,
+}: {
+ error: Error & { digest?: string };
+}) {
+ React.useEffect(() => {
+ Sentry.captureException(error);
+ }, [error]);
+
+ return (
+
+
+ {/* `NextError` is the default Next.js error page component. Its type
+ definition requires a `statusCode` prop. However, since the App Router
+ does not expose status codes for errors, we simply pass 0 to render a
+ generic error message. */}
+
+
+
+ );
+}
diff --git a/apps/web/src/instrumentation.ts b/apps/web/src/instrumentation.ts
new file mode 100644
index 000000000..10aaacea3
--- /dev/null
+++ b/apps/web/src/instrumentation.ts
@@ -0,0 +1,9 @@
+export async function register() {
+ if (process.env.NEXT_RUNTIME === "nodejs") {
+ await import("../sentry.server.config");
+ }
+
+ if (process.env.NEXT_RUNTIME === "edge") {
+ await import("../sentry.edge.config");
+ }
+}
diff --git a/turbo.json b/turbo.json
index ce7e28d13..8ab7435dd 100644
--- a/turbo.json
+++ b/turbo.json
@@ -69,20 +69,22 @@
"DATABASE_URL",
"DISABLE_LANDING_PAGE",
"EMAIL_PROVIDER",
+ "GOOGLE_CLIENT_ID",
+ "GOOGLE_CLIENT_SECRET",
+ "KV_REST_API_URL",
"MAINTENANCE_MODE",
"MICROSOFT_CLIENT_ID",
"MICROSOFT_CLIENT_SECRET",
"MICROSOFT_TENANT_ID",
"NEXT_PUBLIC_*",
+ "NEXT_RUNTIME",
"NODE_ENV",
- "NOREPLY_EMAIL",
"NOREPLY_EMAIL_NAME",
- "OIDC_NAME",
- "OIDC_DISCOVERY_URL",
+ "NOREPLY_EMAIL",
"OIDC_CLIENT_ID",
"OIDC_CLIENT_SECRET",
- "GOOGLE_CLIENT_ID",
- "GOOGLE_CLIENT_SECRET",
+ "OIDC_DISCOVERY_URL",
+ "OIDC_NAME",
"PADDLE_PUBLIC_KEY",
"PORT",
"SECRET_PASSWORD",
@@ -99,7 +101,6 @@
"STRIPE_SECRET_KEY",
"STRIPE_SIGNING_SECRET",
"STRIPE_YEARLY_PRICE",
- "SUPPORT_EMAIL",
- "KV_REST_API_URL"
+ "SUPPORT_EMAIL"
]
}