Added
- Add a surface-aware form-level browser-module contribution event and expose structured hydration reports to module hosts.
- Add Salesforce Client Credentials authentication with configurable My Domain support. (#2961)
- Add provider-neutral subscription snapshots, canonical lifecycle/timeline fields, stale-event protection and mode-bound immediate or period-end cancellation capabilities.
- Add immutable render-scoped theme frames, a generated PHP/TypeScript browser-theme state manifest, split functional/visual CSS assets and bounded theme-config validation.
- Add end-to-end portability and repeatable builder/render/bootstrap/submit/resume/revise performance fixtures.
- Add typed After Completion outcomes shared by HTML, Ajax, REST and GraphQL, with validated redirect overrides and captured query allowlists.
- Add isolated render-instance configuration and versioned durable submission settings while preserving the trusted Twig APIs.
- Add one versioned browser-module manifest with trusted executable IDs, repeated occurrence keys, exact rendering-surface lifecycle contexts, dynamic target reconciliation and required/optional failure diagnostics.
- Add durable integration and notification delivery history with complete encrypted checkpoint evidence, safe per-operation retries, explicit reconciliation and a structured Plugin Kit diagnostics modal in Craft’s queue and submission views.
- Add one typed reference runtime and Variable Picker catalogue, with immutable field declarations, native exact values, stable nested identities, explicit row scopes and context-safe diagnostics.
- Add versioned, atomic form imports with dependency plans, stable-reference matching and recoverable missing field types.
- Add portable per-site translations to stencils and copy them into form overrides when creating forms from a stencil. (#2968)
- Allow each site to override whether a shared form field is required without duplicating the form. (#2982)
Changed
- Standardize control-panel notices, replacement states and React crash fallbacks on Plugin Kit Alert, StatePanel, ErrorState and AppErrorBoundary.
- Use large shared surfaces for prominent builder states and integration connection failures, compact replacement states for notification previews, and shared Alerts for dynamic-option feedback.
- Require Verbb Base 3.0.20 or later so shared control-panel layouts use the current asset bundle namespace. (verbb-base#3)
- Use explicit integration dispatch capability and execution-local results, with common form-integration policy separated from annotated provider settings.
- Store canonical minor-unit payment amounts, account-scoped financial references and subscription terms; retain Formie 3 major-unit and plan projections at compatibility boundaries.
- Separate payment states from browser actions and expose one canonical payment decision across submission transports and frontend adapters.
- Keep curated subscription state separate from encrypted provider evidence, and distinguish billing-period end, actual next charge and synchronization time.
- Keep administrative GraphQL saves persistence-only and separate request adapters from canonical command execution, sharing atomic content/upload persistence.
- Bind queued notification and integration operations to accepted input/configuration fingerprints and report changed operations as stale before delivery or retry.
- Replace field-only condition wrappers with shared ConditionSet predicates and row-aware submission-scoped evaluation state invalidated by content edits.
- Share a permission-scoped lightweight GraphQL schema snapshot and keep unrelated form layouts out of schema generation.
- Declare sensitive integration settings explicitly for encryption and diagnostic/configuration redaction, including inherited and non-standard property names.
- Emit the integration result event once for every normalized run result, including skipped and early-rejected runs.
- Enforce reference source usages and inline/block eligibility at the consuming boundary and filter the Variable Picker from the same declarations.
- Make completed delivery evidence retention configurable, retain unresolved evidence for reconciliation, mark diagnostic limits explicitly and require personal-data acknowledgement for support downloads.
- Retain prepared email content, stored and projected submission values, and argument-free exception traces in encrypted delivery diagnostics.
- Declare field runtime types through protected
defineValueType()hooks and keep numeric reference semantics separate from their decimal-string PHP values. - Use
browserconsistently for shared Formie 4 browser assets and JavaScript translation APIs, while retaining the Formie 3FrontendAssetbundle and rendering compatibility helpers. - Remove intermediate Formie 4 beta
runtimeclass and asset-helper aliases while retaining Formie 3 compatibility boundaries. - Separate versionless Formie 3 submission snapshot adaptation from the strict UID-based Formie 4 snapshot contract instead of retaining intermediate beta formats.
- Save form field layouts atomically inside Craft’s element transaction, batch persistence and identity validation at the root boundary, and add installation-scale load, save and export profiling.
- Treat the migrated Formie 4 database schema as one required runtime contract instead of silently disabling form, submission, notification, integration, payment and spam behavior when required columns are missing.
- Keep legacy CAPTCHA data migration inside the install and upgrade lifecycle rather than reconciling it during normal requests.
- Use explicit completion behavior, redirect source, redirect target and success-message settings throughout Formie 4, while retaining Formie 3 setting, GraphQL and response aliases at compatibility boundaries.
- Treat subscription setup and mandate operations as non-monetary while recording each recurring invoice as a separate payment, and prevent payment integrations with manageable subscriptions from being deleted or disconnected.
- Make browser-module declarations immutable, project one authoritative manifest per rendering surface, reference exact occurrence keys from fields and expose stable submit hooks instead of internal pipeline stages.
- Use non-expiring, exact-value Signature image capabilities while preserving explicitly grandfathered Formie 2/3 email image URLs behind a dedicated compatibility setting.
- Isolate Formie 3 adapters behind dedicated compatibility boundaries instead of exposing them through canonical Formie 4 models and services.
- Keep required behavioural and accessibility attributes authoritative, remove beta-only theme override and
frontendThemeAPIs, retain the final trusted PHP slot event escape hatch, and bind Summary theme state to compact, expiring access tokens backed by encrypted shared storage. - Keep Formie 3 theme grammar compatibility while renaming the beta
defineFieldSlotTag()method todefineSlotTag()and removing mutable render state from shared Form elements. - Split
formie.cssinto functionalformie-base.cssand visualformie-theme.csslayers; thenonetheme now omits only visual styling. - Share versioned tri-state conditions and plain-text validation rules across PHP and browser consumers; enforce recursive hidden-value clearing and server-authoritative navigation.
- Preserve exact nested submission error paths, return typed page-transition results, and distinguish skipped side effects from invalid condition configuration.
- Preserve explicit empty values, enforce server-populated values across resume, capture query prefill once, and evaluate Hidden value sources without changing reusable field definitions.
- Standardise server-rendered and client-rendered products, separate CP edit configuration, and enforce the client-rendered contract across React, Vue and Web Components.
- Require Formie origin allowlisting and explicit cross-origin public session credentials; share staged uploads and backend submission results across rendering products.
- Use
IntegrationConfigfor globally cached non-secret builder metadata and immutableFormIntegrationbindings for each form; isolate Formie 3 metadata APIs behind compatibility adapters, create fresh runtime instances and return explicit integration and batch results. - Run synchronous integrations before the queued lane and expose three notification timings with explicit completion policies.
- Keep queue jobs immutable and small, encrypt literal integration settings and retained responses, and require validated public destinations and provider origins.
- Expose durable queue identities through
DeliveryJobInterfaceand use field-owned reference projections for inline token interpolation. - Store explicit integration mapping slot kinds, preserve Formie 3 tokens through compatibility parsing, and replace beta fluent variable APIs with namespaced source and transform definitions.
- Require safe environment names to be allowlisted for references; diagnose missing fields and extensions and reject invalid email headers.
- Replace beta rich-value projection methods with immutable domain objects and field-owned storage, browser, data and integration projections; route native integration mappings through those field-owned projections, preserve explicit empty clears, describe only the non-null runtime type because
nullis the universal absent value, and retain Formie 3 compatibility adapters. - Separate request, browser, condition and storage value paths; encrypt complete structured values and decode legacy encryption only from trusted storage.
- Return immutable Phone values that retain entered numbers and countries, and a consistent Name value in both input modes; replace beta Array/value-class APIs and browser validation names.
Fixed
- Present required form-feature failures as aligned alerts with collapsed, copyable technical details, prevent lazy control-panel chunks from re-running submission initialization, and skip browser modules where Craft owns the editing control.
- Allow report editor pages to load when configuring export filename variables.
- Avoid Verbb Base deprecation warnings by using its current control-panel asset bundle namespace. (verbb-base#3)
- Fixed moderate-severity authorization bypass vulnerabilities across control-panel and GraphQL operations.
- Fixed low-severity information disclosure vulnerabilities.
- Fixed a low-severity rate-limit bypass vulnerability.
- Allow existing forms containing Address, Repeater and other nested fields to be updated in the form builder.
- Prevent structured Phone field defaults from being displayed as JSON in the form builder preview.
- Fix text word and character limits disagreeing between browser and server validation for Unicode punctuation, emoji, and composed characters. (#2977)
- Apply event-modified Phone countries to server-rendered and client-rendered browser pickers when a field has no explicit allowed-country list.
- Allow upgrades with beta integration-policy settings to complete the reference migration before forms are loaded.
- Preserve configured rich completion and error messages across partial settings updates, and render sanitized rich completion messages in client-rendered adapters.
- Preserve uploaded files when an incomplete multi-page submission navigates back after the asset has been bound and promoted, without weakening upload ownership checks.
- Separate shared field definition identity from form-field instances, use explicit definition/instance records and settings APIs, isolate the Formie 3
syncIdalias, require registered fields to extend the base Field class and formalize parent-field traversal. - Share identity remapping across imports, duplicates and stencils; use portable definition UIDs for Synced Fields and explicit enabled/recursive traversal APIs.
- Make payment amounts exact, return typed payment decisions with immutable actions and explicit resubmit/return/poll modes, and atomically settle payment-backed submissions with recoverable provider evidence.
- Retain coherent subscription and recurring-payment history; separate cancellation, provider return, read-only status and browser-session authority, and reconcile status polling on a server-controlled cadence.
- Process payment webhooks through adapter verification and a durable asynchronous inbox with stable integration URLs, encrypted idempotent receipts, bounded retries and redacted diagnostics; reject unauthenticated provider events without discarding valid bursts.
- Store canonical journey progress in the database and use independent purpose-bound, expiring grants for Save & Continue and authorised editing across browsers.
- Require structured, purpose-bound staged-upload references across server-rendered, client-rendered, REST and GraphQL submissions; bind accepted uploads to their exact form, field, owner and browser context before dispatch, with durable promotion recovery.
- Remove beta draft-storage APIs, etags and
maxSavedDraftsPerSession; existing beta resume links must be reissued after upgrading. - Replace beta submission workflow APIs with explicit operations, authorised commands, typed outcomes and six fixed stages with operation-scoped custom tasks.
- Resolve progression and page transitions in Preflight after hidden-value clearing, while exposing only stable semantic task anchors and having validation consume the selected transition.
- Require expected submission versions and retain bounded durable retry receipts to prevent duplicate and stale writes.
- Require integrations to explicitly declare attributes that can be configured per form.
- Require
verbb/base3.0.17 or later. - Render form-authored Twig and object templates in Base's explicit sandbox while retaining Formie 4's reference-token handling.
- Respect the existing last-page and query-string options when resolving completion redirect URLs, including payment-failure fallbacks.
- Fixed authorization for connecting OAuth integrations and revalidated access when callbacks return.
- Fixed OAuth callback transaction validation.
- Keep valid Save & Continue links usable when optional page-progress state expires or is removed.
- Build the current database schema directly during fresh installs instead of replaying upgrade migrations.
- Treat notification timing as order rather than implicit integration success, while leaving unknown outcomes unresolved and preserving explicit notification conditions.
- Commit pending delivery intent with submission completion and recover interrupted dispatches without repeating payment or creating another completion run.
- Keep integration results and reference values scoped to their delivery run instead of overwriting the submission’s latest results.
- Serve staged upload previews through expiring view capabilities and require private temporary upload storage.
- Enforce aggregate staged-upload file and byte budgets across fields and cap staged expiry independently of incomplete-submission retention.
- Bound Base64 upload input and decoded sizes before allocating file contents, using Craft’s maximum upload size.
- Complete required upload promotion before marking submissions complete, and finalize accepted uploads before completion events and delivery, including payment replay.
- Retain upload cleanup records across permanent submission and form deletion and failed file deletion, preserve retryable field references, and leave shared or unowned files intact.
- Preserve accepted field values during payment replay, including condition-cleared forced values and previously evaluated Hidden sources.
- Stop manual asset resolution from rendering the full form a second time, and memoise missing browser submission progress per Form instance to prevent all-field render query amplification. (#2637)
- Enforce field ownership and allowed field types at builder and save boundaries, preserve nested references and refresh layout lookups after descendant changes.
- Stop invalid submissions before spam screening and CAPTCHA, and keep pending payment submissions incomplete until payment succeeds.
- Fixed a moderate-severity information disclosure vulnerability. (GHSA-963f-vfpf-f85p)
- Fixed a high-severity server-side request forgery vulnerability. (GHSA-82jr-3xc8-86mr)
- Fixed high-severity server-side template injection vulnerabilities in sandboxed Twig rendering. (GHSA-f55h-mf7f-7wx7)
- Keep stencil builder data isolated from unrelated Craft elements and forms with the same numeric ID. (#2968)