Changes since 25.1.0-alpha6
Breaking changes
-
Merge signals module into flow-server
Commit · Pull requestMove all signals source code directly into flow-server and rename the package from com.vaadin.signals to com.vaadin.flow.signals to match the flow-server package convention. Remove the standalone signals module and its references from all POM files.
New features
-
Add localeSignal() to UI and VaadinSession
CommitAdd a signal that reflects the current locale and updates automatically when setLocale() is called. This allows components to reactively respond to locale changes using the signals API.
-
Make signals Serializable
Commit · Pull requestMakes serializable local signals: ValueSignal and ListSignal. Serializable ComponentEffect and ComputedSignal. Adds unit test for basic case: serialize and deserialize session with one UI instance and ensure that ComponentEffect in a Component is still executed when ValueSignal's value is changed. Same unit tests for Element bindText, bindProperty, bindAttribute, bindEnabled, bindVisible, Signal.computed(), Signal.map. Part of #22843
-
Delegate no-routes handling to Copilot
Commit · Pull requestCall copilot's noRoutesInProject() on page load if available, letting Copilot handle the view creation flow. Fall back to a simple info page suggesting Copilot or manual view creation via the tutorial.
-
Enhance Binder with cross-field validation
Commit · Pull request · Issues 23364, 23300Adds Binder.Binding.value() to be used in field binding validators to read value of another field. The Binder automatically runs validators inside a ComponentEffect#effect context, making validators and converters reactive to signal changes. Part of #23298
Fixes
-
Pass javaResourceFolder to Options in DevModeInitializer
Commit · Pull request · IssueDevModeInitializer was creating an Options object without setting javaResourceFolder, causing TaskUpdateSettingsFile to overwrite it with an empty string. This broke legacy theme component styles in Gradle dev mode because the Vite theme plugin couldn't find vaadin-featureflags.properties in the correct location.
-
Properly check ancestors for alias child
Commit · Pull requestThe signal tree logic has a check to verify that a node isn't moved in a way that creates a cyclic graph, i.e. to prevent the node from becoming its own ancestor. Before this fix, the logic was checking based on the provided node id without resolving aliases whereas the actual move was applied with resolved aliases. This made it possible to accidentally move a node in a way that created a cycle by moving an alias of the node rather than the original node. The fix is to resolve any alias before checking for cycles.
-
Remove Content-Type header from heartbeat requests and responses
Commit · Pull request · IssueHeartbeat requests and responses both have empty bodies, so the with Web Application Firewalls (WAFs). WAFs struggle to validate text/plain requests with no body content, triggering false positive security alerts in SOC monitoring systems. Changes: - Server: Remove Content-Type header from successful heartbeat responses in HeartbeatHandler (empty body = no content type needed) - Client: Remove Content-Type from heartbeat POST requests in Heartbeat.java (request body is null) - Tests: Add verification that Content-Type is not set while Cache-Control remains in place The original Content-Type header was added in 2013 to fix Firefox issue vaadin/framework#4167, where Firefox tried to parse the empty response as HTML and threw errors. This is no longer relevant because: 1. Vaadin's client code never reads the response body, avoiding any parsing that would trigger browser errors 2. Modern browsers handle empty responses without Content-Type 3. HTTP best practices recommend no Content-Type for empty bodies The Cache-Control: no-cache header is retained as it's still required for iOS 6 Safari compatibility (vaadin/framework#3226).
-
Extract browser details earlier
Commit · Pull request · IssueExtract the browserDetails earlier so that they are available when UiInitListeners are fired.