Skip to content

Commit 175bd68

Browse files
committed
fix(onboarding): hard-navigate to /dashboard after finish
router.replace + router.refresh occasionally raced against the app layout's hasCompletedOnboarding check — the audit_log row insert hadn't been observed by the new request yet, so the layout bounced the user straight back to /onboarding with no visible feedback. Use window.location.href for a hard reload after the action resolves. Slower (~50ms) but deterministic. Also surfaces thrown errors in the toast instead of silently returning. Side-effects: - Drop unused useRouter import
1 parent fee94a6 commit 175bd68

1 file changed

Lines changed: 12 additions & 5 deletions

File tree

apps/web/src/app/onboarding/_wizard.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { Input } from "@starter-saas/ui/components/input";
1818
import { Label } from "@starter-saas/ui/components/label";
1919
import { ArrowRight, CheckCircle2 } from "lucide-react";
2020
import Link from "next/link";
21-
import { useRouter } from "next/navigation";
2221
import * as React from "react";
2322
import { toast } from "sonner";
2423
import { authClient } from "@/lib/auth-client";
@@ -82,7 +81,6 @@ function StepDots({ active }: { active: StepKey }) {
8281
}
8382

8483
export function OnboardingWizard({ user }: Props) {
85-
const router = useRouter();
8684
const [step, setStep] = React.useState<StepKey>("profile");
8785
const [name, setName] = React.useState(user.name);
8886
const [orgName, setOrgName] = React.useState("");
@@ -123,16 +121,25 @@ export function OnboardingWizard({ user }: Props) {
123121
id: toastId,
124122
description: result.error,
125123
});
124+
setFinishing(false);
126125
return;
127126
}
128127
toast.success(skipped ? "Skipped — see you later" : "You're set", {
129128
id: toastId,
130129
});
131-
router.replace("/dashboard");
132-
router.refresh();
133-
} finally {
130+
// Hard navigation — `router.replace` doesn't always pick up the new
131+
// audit-log row before the app layout re-runs `hasCompletedOnboarding`,
132+
// which bounces us back to /onboarding. A full reload sidesteps that.
133+
window.location.href = "/dashboard";
134+
} catch (err) {
135+
toast.error("Couldn't finish", {
136+
id: toastId,
137+
description: err instanceof Error ? err.message : "?",
138+
});
134139
setFinishing(false);
135140
}
141+
// Intentionally leave `finishing` true on success — the hard nav
142+
// will unmount this component momentarily.
136143
};
137144

138145
const saveProfile = async () => {

0 commit comments

Comments
 (0)