Form Page Guard (TanStack Router)
TanStack Router adapter for Form Page unsaved-changes — drop FormPageUnsavedGuard inside FormPage to block in-app navigation.
Plus Registry
Form Page Guard (TanStack Router) ships on the authenticated @f-ui-plus registry. Configure FUI_PLUS_REGISTRY_TOKEN as described in Installation — Plus Registry.
Form Page Guard (TanStack Router) blocks in-app navigation while a Form Page is dirty. Form Page is router-agnostic: it owns the native tab-close prompt. This item is the TanStack useBlocker adapter. Drop <FormPageUnsavedGuard /> inside FormPage — no app-root provider.
A live blocker is not mounted in these docs (it would trap the whole docs tree). Copy the Usage snippet into a TanStack route that owns the form.
When To Use
- The host is TanStack Router and Form Page should confirm before in-app navigation.
- Pair with Form Page. Use Form Page Guard (Next.js App Router) on Next hosts.
- No layout provider. One child inside Form Page is enough — TanStack
Link/navigatealready go through history.block. - Do not set TanStack
enableBeforeUnloadon this adapter. Form Page already owns the tab-close prompt. - Keep a stable
shouldBlockFn— the adapter does this so auto-save togglingwhendoes not tear down the blocker mid-dialog.
Features
| Area | Behavior |
|---|---|
| Guard | FormPageUnsavedGuard reads Form Page context and renders the confirm dialog |
| Blocker | useBlocker({ shouldBlockFn, withResolver: true, enableBeforeUnload: false }) |
| Dialog | Stay / Leave, plus optional Save draft & leave from Form Page confirm copy |
| Hook | useTanStackFormNavigationGuard({ when, confirm? }) if you are not using Form Page |
Installing
pnpm dlx shadcn@latest add https://ui.isaacfei.com/api/plus/r/form-page-guard-tanstack.jsonnpx shadcn@latest add https://ui.isaacfei.com/api/plus/r/form-page-guard-tanstack.jsonyarn dlx shadcn@latest add https://ui.isaacfei.com/api/plus/r/form-page-guard-tanstack.jsonbunx shadcn@latest add https://ui.isaacfei.com/api/plus/r/form-page-guard-tanstack.jsonWith the @f-ui-plus namespace configured in components.json, shadcn add @f-ui-plus/form-page-guard-tanstack also works.
Runtime npm dep: @tanstack/react-router. registryDependencies: @f-ui-plus/form-page.
Usage
import { FormPageUnsavedGuard } from "@/components/f-ui/form-page/navigation-guard/tanstack-router";
<FormPage form={form} onFinish={handleSubmit} warnOnUnsavedChanges>
<FormPageUnsavedGuard />
{/* fields */}
</FormPage>Examples
One Child
Unlike the Next adapter, there is no app-root provider and no special Link. The guard is a Form Page child; TanStack history blocking does the rest.
One child
- Keep
warnOnUnsavedChangesonFormPage(default on). - Render
FormPageUnsavedGuardas a child ofFormPage. - In-app
useBlockeris this adapter. The native tab-close prompt stays on Form Page — do not enable TanStackenableBeforeUnload.
"use client";
import { SectionCard } from "@/components/f-ui/section-card/section-card";
/** TanStack Router wiring — drop the guard inside FormPage; FormPage owns the tab-close prompt. */
export function FormPageGuardTanstackDemo() {
return (
<SectionCard title="One child">
<ol className="text-sm text-muted-foreground list-decimal space-y-2 pl-5">
<li>
Keep <code>warnOnUnsavedChanges</code> on <code>FormPage</code> (default on).
</li>
<li>
Render <code>FormPageUnsavedGuard</code> as a child of <code>FormPage</code>.
</li>
<li>
In-app <code>useBlocker</code> is this adapter. The native tab-close prompt stays on
Form Page — do not enable TanStack <code>enableBeforeUnload</code>.
</li>
</ol>
</SectionCard>
);
}API Reference
FormPageUnsavedGuard
No props. Must be a child of FormPage. Renders UnsavedChangesDialog when the TanStack blocker status is "blocked".
useTanStackFormNavigationGuard
| Option | Type | Description |
|---|---|---|
when | boolean | Block while true. |
confirm | UnsavedChangesConfirm | Dialog copy / optional save-and-leave. |
Returns the shared guard core (dialogOpen, proceed, reset, confirm). Prefer FormPageUnsavedGuard inside Form Page so when / confirm stay on the form context.