From 285f6cd16dc5c5adab73e4051daddee935e7a696 Mon Sep 17 00:00:00 2001 From: okxint Date: Tue, 13 Oct 2026 10:41:56 +0530 Subject: [PATCH] fix(svelte-form): use stable module-level counter for default formId When formId is not provided, FormApi falls back to uuid(), generating a different ID on the server and client, causing SSR hydration mismatches when form.formId is bound to a DOM attribute in SvelteKit. Add a module-level counter (nextFormId) that increments in component-tree order, matching both SSR and hydration passes deterministically. Mirrors the same pattern used by angular-form (APP_ID + counter, PR #2415). Explicit opts.formId is always respected unchanged. Fixes #2388 --- packages/svelte-form/src/createForm.svelte.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/svelte-form/src/createForm.svelte.ts b/packages/svelte-form/src/createForm.svelte.ts index 1b40ce748f..0a5302d224 100644 --- a/packages/svelte-form/src/createForm.svelte.ts +++ b/packages/svelte-form/src/createForm.svelte.ts @@ -1,6 +1,12 @@ import { FormApi } from '@tanstack/form-core' import { useSelector } from '@tanstack/svelte-store' import { onMount } from 'svelte' + +let _formCounter = 0 + +function nextFormId(): string { + return `svelte-form-${++_formCounter}` +} import Field from './Field.svelte' import FormGroup from './FormGroup.svelte' import Subscribe from './Subscribe.svelte' @@ -310,7 +316,7 @@ export function createForm< TFormOnDynamicAsync, TFormOnServer, TSubmitMeta - >(options) + >({ ...options, formId: options?.formId ?? nextFormId() } as typeof options) const extendedApi: typeof api & SvelteFormApi< TParentData,