diff --git a/messages/en.json b/messages/en.json
index 07aa121..a3dd25f 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -1501,6 +1501,7 @@
"appearance": "Appearance",
"whatsapp": "WhatsApp",
"templates": "Templates",
+ "quick-replies": "Quick replies",
"fields": "Fields & tags",
"deals": "Deals & currency",
"members": "Team members",
diff --git a/src/app/(dashboard)/automations/new/page.tsx b/src/app/(dashboard)/automations/new/page.tsx
index d707984..55d5c90 100644
--- a/src/app/(dashboard)/automations/new/page.tsx
+++ b/src/app/(dashboard)/automations/new/page.tsx
@@ -1,6 +1,6 @@
"use client"
-import { useMemo } from "react"
+import { Suspense, useMemo } from "react"
import { useSearchParams } from "next/navigation"
import {
@@ -11,7 +11,18 @@ import {
import { AUTOMATION_TEMPLATES, type TemplateSlug } from "@/lib/automations/templates"
import type { AutomationStepType, AutomationTriggerType } from "@/types"
+// `useSearchParams` requires a Suspense boundary or the production build
+// bails to CSR and errors out. Thin wrapper supplies it; the inner
+// component reads the `?template=` query string.
export default function NewAutomationPage() {
+ return (
+
+
+
+ )
+}
+
+function NewAutomationPageInner() {
const params = useSearchParams()
const template = params.get("template") as TemplateSlug | null
diff --git a/src/app/(dashboard)/inbox/page.tsx b/src/app/(dashboard)/inbox/page.tsx
index b32e74b..f73a7e2 100644
--- a/src/app/(dashboard)/inbox/page.tsx
+++ b/src/app/(dashboard)/inbox/page.tsx
@@ -1,6 +1,6 @@
"use client";
-import { useState, useCallback, useEffect, useRef } from "react";
+import { Suspense, useState, useCallback, useEffect, useRef } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useTranslations } from "next-intl";
import { createClient } from "@/lib/supabase/client";
@@ -21,7 +21,18 @@ import { cn } from "@/lib/utils";
// across reloads and sessions (device-scoped, like the theme prefs).
const CONTACT_PANEL_STORAGE_KEY = "wacrm:inbox:contact-panel-open";
+// `useSearchParams` (the `?c=` deep link below) requires a Suspense
+// boundary or the production build bails to CSR and errors out. Thin
+// wrapper supplies it; the inner component holds all the inbox state.
export default function InboxPage() {
+ return (
+
+
+
+ );
+}
+
+function InboxPageInner() {
const t = useTranslations("Inbox.page");
const router = useRouter();
const searchParams = useSearchParams();
diff --git a/src/app/(dashboard)/settings/page.tsx b/src/app/(dashboard)/settings/page.tsx
index 97d192b..a423383 100644
--- a/src/app/(dashboard)/settings/page.tsx
+++ b/src/app/(dashboard)/settings/page.tsx
@@ -1,6 +1,6 @@
'use client';
-import { useMemo, type ReactNode } from 'react';
+import { Suspense, useMemo, type ReactNode } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useTranslations } from 'next-intl';
@@ -23,7 +23,23 @@ import {
type SettingsSection,
} from '@/components/settings/settings-sections';
+// `useSearchParams` opts this page out of static prerendering unless it
+// sits under a Suspense boundary. Without one, the production build hits
+// the "missing Suspense with CSR bailout" error and the whole page bails
+// to client-side rendering — shipping a settings screen whose rail never
+// wires up its click handlers. You land on the section the URL carried
+// (the account-menu Settings link points at `?tab=whatsapp`) and can't
+// navigate away. Mirror the login/signup split: a thin wrapper supplies
+// the boundary; the inner component reads the query string.
export default function SettingsPage() {
+ return (
+
+
+
+ );
+}
+
+function SettingsPageInner() {
const router = useRouter();
const searchParams = useSearchParams();
const { defaultCurrency } = useAuth();