diff --git a/apps/docs/package.json b/apps/docs/package.json
index 8c314fb40bf..b96c20d0535 100644
--- a/apps/docs/package.json
+++ b/apps/docs/package.json
@@ -26,7 +26,7 @@
"fumadocs-openapi": "10.3.13",
"fumadocs-ui": "16.6.7",
"lucide-react": "^0.511.0",
- "next": "16.1.6",
+ "next": "16.2.4",
"next-themes": "^0.4.6",
"postgres": "^3.4.5",
"react": "19.2.4",
diff --git a/apps/sim/app/(auth)/oauth/consent/page.tsx b/apps/sim/app/(auth)/oauth/consent/page.tsx
index 8addf4e82b4..ea624d9b87f 100644
--- a/apps/sim/app/(auth)/oauth/consent/page.tsx
+++ b/apps/sim/app/(auth)/oauth/consent/page.tsx
@@ -1,6 +1,6 @@
'use client'
-import { useCallback, useEffect, useState } from 'react'
+import { Suspense, useCallback, useEffect, useState } from 'react'
import { ArrowLeftRight } from 'lucide-react'
import Image from 'next/image'
import { useRouter, useSearchParams } from 'next/navigation'
@@ -25,6 +25,14 @@ interface ClientInfo {
}
export default function OAuthConsentPage() {
+ return (
+
+
+
+ )
+}
+
+function OAuthConsentInner() {
const router = useRouter()
const searchParams = useSearchParams()
const { data: session } = useSession()
diff --git a/apps/sim/app/(auth)/reset-password/page.tsx b/apps/sim/app/(auth)/reset-password/page.tsx
index cb6470bba0e..8d9ee5dfd42 100644
--- a/apps/sim/app/(auth)/reset-password/page.tsx
+++ b/apps/sim/app/(auth)/reset-password/page.tsx
@@ -5,4 +5,6 @@ export const metadata: Metadata = {
title: 'Reset Password',
}
+export const dynamic = 'force-dynamic'
+
export default ResetPasswordPage
diff --git a/apps/sim/app/(landing)/components/navbar/navbar.tsx b/apps/sim/app/(landing)/components/navbar/navbar.tsx
index 4ee2fdb2aca..e5503dcb27e 100644
--- a/apps/sim/app/(landing)/components/navbar/navbar.tsx
+++ b/apps/sim/app/(landing)/components/navbar/navbar.tsx
@@ -4,7 +4,6 @@ import { useCallback, useContext, useEffect, useRef, useState, useSyncExternalSt
import dynamic from 'next/dynamic'
import Image from 'next/image'
import Link from 'next/link'
-import { useSearchParams } from 'next/navigation'
import { GithubOutlineIcon } from '@/components/icons'
import { cn } from '@/lib/core/utils/cn'
import { SessionContext } from '@/app/_shell/providers/session-provider'
@@ -52,12 +51,14 @@ interface NavbarProps {
export default function Navbar({ logoOnly = false, blogPosts = [] }: NavbarProps) {
const brand = getBrandConfig()
- const searchParams = useSearchParams()
const sessionCtx = useContext(SessionContext)
const session = sessionCtx?.data ?? null
const isSessionPending = sessionCtx?.isPending ?? true
const isAuthenticated = Boolean(session?.user?.id)
- const isBrowsingHome = searchParams.has('home')
+ const [isBrowsingHome, setIsBrowsingHome] = useState(false)
+ useEffect(() => {
+ setIsBrowsingHome(new URLSearchParams(window.location.search).has('home'))
+ }, [])
const useHomeLinks = isAuthenticated || isBrowsingHome
const logoHref = useHomeLinks ? '/?home' : '/'
const mounted = useSyncExternalStore(
diff --git a/apps/sim/app/(landing)/privacy/page.tsx b/apps/sim/app/(landing)/privacy/page.tsx
index 44140c62bb6..1081c090b82 100644
--- a/apps/sim/app/(landing)/privacy/page.tsx
+++ b/apps/sim/app/(landing)/privacy/page.tsx
@@ -3,6 +3,8 @@ import Link from 'next/link'
import { getEnv } from '@/lib/core/config/env'
import { ExternalRedirect, LegalLayout } from '@/app/(landing)/components'
+export const dynamic = 'force-dynamic'
+
export const metadata: Metadata = {
title: 'Privacy Policy',
description:
diff --git a/apps/sim/app/(landing)/terms/page.tsx b/apps/sim/app/(landing)/terms/page.tsx
index 08c16aeaa14..5d49f2bc52a 100644
--- a/apps/sim/app/(landing)/terms/page.tsx
+++ b/apps/sim/app/(landing)/terms/page.tsx
@@ -3,6 +3,8 @@ import Link from 'next/link'
import { getEnv } from '@/lib/core/config/env'
import { ExternalRedirect, LegalLayout } from '@/app/(landing)/components'
+export const dynamic = 'force-dynamic'
+
export const metadata: Metadata = {
title: 'Terms of Service',
description:
diff --git a/apps/sim/app/invite/[id]/page.tsx b/apps/sim/app/invite/[id]/page.tsx
index e04a2ca7743..ac302790523 100644
--- a/apps/sim/app/invite/[id]/page.tsx
+++ b/apps/sim/app/invite/[id]/page.tsx
@@ -6,4 +6,6 @@ export const metadata: Metadata = {
robots: { index: false },
}
+export const dynamic = 'force-dynamic'
+
export default Invite
diff --git a/apps/sim/app/manifest.ts b/apps/sim/app/manifest.ts
index d66d2db1a17..cb91437f3c1 100644
--- a/apps/sim/app/manifest.ts
+++ b/apps/sim/app/manifest.ts
@@ -1,6 +1,8 @@
import type { MetadataRoute } from 'next'
import { getBrandConfig } from '@/ee/whitelabeling'
+export const dynamic = 'force-dynamic'
+
export default function manifest(): MetadataRoute.Manifest {
const brand = getBrandConfig()
diff --git a/apps/sim/app/unsubscribe/page.tsx b/apps/sim/app/unsubscribe/page.tsx
index d1b3ec2de10..2258e81c93e 100644
--- a/apps/sim/app/unsubscribe/page.tsx
+++ b/apps/sim/app/unsubscribe/page.tsx
@@ -6,4 +6,6 @@ export const metadata: Metadata = {
robots: { index: false },
}
+export const dynamic = 'force-dynamic'
+
export default Unsubscribe
diff --git a/apps/sim/lib/core/config/env.ts b/apps/sim/lib/core/config/env.ts
index 14bf33ce5d4..36f21446765 100644
--- a/apps/sim/lib/core/config/env.ts
+++ b/apps/sim/lib/core/config/env.ts
@@ -1,14 +1,16 @@
import { createEnv } from '@t3-oss/env-nextjs'
-import { env as runtimeEnv } from 'next-runtime-env'
import { z } from 'zod'
/**
- * Universal environment variable getter that works in both client and server contexts.
- * - Client-side: Uses next-runtime-env for runtime injection (supports Docker runtime vars)
- * - Server-side: Falls back to process.env when runtimeEnv returns undefined
- * - Provides seamless Docker runtime variable support for NEXT_PUBLIC_ vars
+ * Reads NEXT_PUBLIC_* env vars in both client and server contexts.
+ * Client reads `window.__ENV` (populated by ``); server reads `process.env`.
+ * We do not use next-runtime-env's `env()` helper because it calls `unstable_noStore()`,
+ * which Next 16.2+ rejects outside a request scope.
*/
-const getEnv = (variable: string) => runtimeEnv(variable) ?? process.env[variable]
+const getEnv = (variable: string): string | undefined => {
+ if (typeof window === 'undefined') return process.env[variable]
+ return window.__ENV?.[variable] ?? process.env[variable]
+}
// biome-ignore format: keep alignment for readability
export const env = createEnv({
diff --git a/apps/sim/next.config.ts b/apps/sim/next.config.ts
index e349e2c865b..7a96c063cfe 100644
--- a/apps/sim/next.config.ts
+++ b/apps/sim/next.config.ts
@@ -1,5 +1,5 @@
import type { NextConfig } from 'next'
-import { env, getEnv, isTruthy } from './lib/core/config/env'
+import { env, isTruthy } from './lib/core/config/env'
import { isDev } from './lib/core/config/feature-flags'
import {
getChatEmbedCSPPolicy,
@@ -40,13 +40,13 @@ const nextConfig: NextConfig = {
hostname: 'lh3.googleusercontent.com',
},
// Brand logo domain if configured
- ...(getEnv('NEXT_PUBLIC_BRAND_LOGO_URL')
+ ...(process.env.NEXT_PUBLIC_BRAND_LOGO_URL
? (() => {
try {
return [
{
protocol: 'https' as const,
- hostname: new URL(getEnv('NEXT_PUBLIC_BRAND_LOGO_URL')!).hostname,
+ hostname: new URL(process.env.NEXT_PUBLIC_BRAND_LOGO_URL!).hostname,
},
]
} catch {
@@ -55,13 +55,13 @@ const nextConfig: NextConfig = {
})()
: []),
// Brand favicon domain if configured
- ...(getEnv('NEXT_PUBLIC_BRAND_FAVICON_URL')
+ ...(process.env.NEXT_PUBLIC_BRAND_FAVICON_URL
? (() => {
try {
return [
{
protocol: 'https' as const,
- hostname: new URL(getEnv('NEXT_PUBLIC_BRAND_FAVICON_URL')!).hostname,
+ hostname: new URL(process.env.NEXT_PUBLIC_BRAND_FAVICON_URL!).hostname,
},
]
} catch {
diff --git a/apps/sim/package.json b/apps/sim/package.json
index 9d0c3e8a932..9eadf53bcd4 100644
--- a/apps/sim/package.json
+++ b/apps/sim/package.json
@@ -160,7 +160,7 @@
"mongodb": "6.19.0",
"mysql2": "3.14.3",
"neo4j-driver": "6.0.1",
- "next": "16.1.6",
+ "next": "16.2.4",
"next-mdx-remote": "^5.0.0",
"next-runtime-env": "3.3.0",
"next-themes": "^0.4.6",
@@ -250,8 +250,8 @@
"sharp"
],
"overrides": {
- "next": "16.1.6",
- "@next/env": "16.1.6",
+ "next": "16.2.4",
+ "@next/env": "16.2.4",
"drizzle-orm": "^0.45.2",
"postgres": "^3.4.5",
"react-floater": {
diff --git a/bun.lock b/bun.lock
index f8b62029912..813bb69bdb8 100644
--- a/bun.lock
+++ b/bun.lock
@@ -29,7 +29,7 @@
"fumadocs-openapi": "10.3.13",
"fumadocs-ui": "16.6.7",
"lucide-react": "^0.511.0",
- "next": "16.1.6",
+ "next": "16.2.4",
"next-themes": "^0.4.6",
"postgres": "^3.4.5",
"react": "19.2.4",
@@ -214,7 +214,7 @@
"mongodb": "6.19.0",
"mysql2": "3.14.3",
"neo4j-driver": "6.0.1",
- "next": "16.1.6",
+ "next": "16.2.4",
"next-mdx-remote": "^5.0.0",
"next-runtime-env": "3.3.0",
"next-themes": "^0.4.6",
@@ -483,9 +483,9 @@
"sharp",
],
"overrides": {
- "@next/env": "16.1.6",
+ "@next/env": "16.2.4",
"drizzle-orm": "^0.45.2",
- "next": "16.1.6",
+ "next": "16.2.4",
"postgres": "^3.4.5",
"react": "19.2.4",
"react-dom": "19.2.4",
@@ -1055,23 +1055,23 @@
"@napi-rs/canvas-win32-x64-msvc": ["@napi-rs/canvas-win32-x64-msvc@0.1.100", "", { "os": "win32", "cpu": "x64" }, "sha512-MyT1j3mHC2+Lu4pBi9mKyMJhtP6U7k7EldY7sj/uS5gJA65gTXt8MefJQXLJo5d/vZbuWmfxzkEUNc/urV3pHA=="],
- "@next/env": ["@next/env@16.1.6", "", {}, "sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ=="],
+ "@next/env": ["@next/env@16.2.4", "", {}, "sha512-dKkkOzOSwFYe5RX6y26fZgkSpVAlIOJKQHIiydQcrWH6y/97+RceSOAdjZ14Qa3zLduVUy0TXcn+EiM6t4rPgw=="],
- "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.1.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw=="],
+ "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-OXTFFox5EKN1Ym08vfrz+OXxmCcEjT4SFMbNRsWZE99dMqt2Kcusl5MqPXcW232RYkMLQTy0hqgAMEsfEd/l2A=="],
- "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.1.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ=="],
+ "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-XhpVnUfmYWvD3YrXu55XdcAkQtOnvaI6wtQa8fuF5fGoKoxIUZ0kWPtcOfqJEWngFF/lOS9l3+O9CcownhiQxQ=="],
- "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw=="],
+ "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-Mx/tjlNA3G8kg14QvuGAJ4xBwPk1tUHq56JxZ8CXnZwz1Etz714soCEzGQQzVMz4bEnGPowzkV6Xrp6wAkEWOQ=="],
- "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ=="],
+ "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-iVMMp14514u7Nup2umQS03nT/bN9HurK8ufylC3FZNykrwjtx7V1A7+4kvhbDSCeonTVqV3Txnv0Lu+m2oDXNg=="],
- "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ=="],
+ "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-EZOvm1aQWgnI/N/xcWOlnS3RQBk0VtVav5Zo7n4p0A7UKyTDx047k8opDbXgBpHl4CulRqRfbw3QrX2w5UOXMQ=="],
- "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg=="],
+ "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-h9FxsngCm9cTBf71AR4fGznDEDx1hS7+kSEiIRjq5kO1oXWm07DxVGZjCvk0SGx7TSjlUqhI8oOyz7NfwAdPoA=="],
- "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.1.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw=="],
+ "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.2.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-3NdJV5OXMSOeJYijX+bjaLge3mJBlh4ybydbT4GFoB/2hAojWHtMhl3CYlYoMrjPuodp0nzFVi4Tj2+WaMg+Ow=="],
- "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.1.6", "", { "os": "win32", "cpu": "x64" }, "sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A=="],
+ "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.2.4", "", { "os": "win32", "cpu": "x64" }, "sha512-kMVGgsqhO5YTYODD9IPGGhA6iprWidQckK3LmPeW08PIFENRmgfb4MjXHO+p//d+ts2rpjvK5gXWzXSMrPl9cw=="],
"@noble/ciphers": ["@noble/ciphers@2.2.0", "", {}, "sha512-Z6pjIZ/8IJcCGzb2S/0Px5J81yij85xASuk1teLNeg75bfT07MV3a/O2Mtn1I2se43k3lkVEcFaR10N4cgQcZA=="],
@@ -3237,7 +3237,7 @@
"netmask": ["netmask@2.1.1", "", {}, "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA=="],
- "next": ["next@16.1.6", "", { "dependencies": { "@next/env": "16.1.6", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.6", "@next/swc-darwin-x64": "16.1.6", "@next/swc-linux-arm64-gnu": "16.1.6", "@next/swc-linux-arm64-musl": "16.1.6", "@next/swc-linux-x64-gnu": "16.1.6", "@next/swc-linux-x64-musl": "16.1.6", "@next/swc-win32-arm64-msvc": "16.1.6", "@next/swc-win32-x64-msvc": "16.1.6", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw=="],
+ "next": ["next@16.2.4", "", { "dependencies": { "@next/env": "16.2.4", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.2.4", "@next/swc-darwin-x64": "16.2.4", "@next/swc-linux-arm64-gnu": "16.2.4", "@next/swc-linux-arm64-musl": "16.2.4", "@next/swc-linux-x64-gnu": "16.2.4", "@next/swc-linux-x64-musl": "16.2.4", "@next/swc-win32-arm64-msvc": "16.2.4", "@next/swc-win32-x64-msvc": "16.2.4", "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-kPvz56wF5frc+FxlHI5qnklCzbq53HTwORaWBGdT0vNoKh1Aya9XC8aPauH4NJxqtzbWsS5mAbctm4cr+EkQ2Q=="],
"next-mdx-remote": ["next-mdx-remote@5.0.0", "", { "dependencies": { "@babel/code-frame": "^7.23.5", "@mdx-js/mdx": "^3.0.1", "@mdx-js/react": "^3.0.1", "unist-util-remove": "^3.1.0", "vfile": "^6.0.1", "vfile-matter": "^5.0.0" }, "peerDependencies": { "react": ">=16" } }, "sha512-RNNbqRpK9/dcIFZs/esQhuLA8jANqlH694yqoDBK8hkVdJUndzzGmnPHa2nyi90N4Z9VmzuSWNRpr5ItT3M7xQ=="],
diff --git a/package.json b/package.json
index 8e8b78e1802..eea53bc1299 100644
--- a/package.json
+++ b/package.json
@@ -48,8 +48,8 @@
"overrides": {
"react": "19.2.4",
"react-dom": "19.2.4",
- "next": "16.1.6",
- "@next/env": "16.1.6",
+ "next": "16.2.4",
+ "@next/env": "16.2.4",
"drizzle-orm": "^0.45.2",
"postgres": "^3.4.5"
},