Releases: vaadin/flow
Vaadin Flow 25.1.9
Changes since 25.1.7
New features
- Add npm.excludePostinstallPackages option (#24421) (CP: 25.1)
Commit · Pull request
Adds a configuration option to exclude packages from running postinstall scripts. Mirrors the existing npm.postinstallPackages add-list and applies to both the built-in default entries (e.g. esbuild, @vaadin/vaadin-usage-statistics) and any packages added via postinstallPackages. Wired through Options, the Maven and Gradle plugins, and DevModeInitializer. Refs #24333.
Fixes
- Ios home screen app height (#24435) (CP: 25.1)
Commit · Pull request
The bootstrap page update makes sure the app covers the entire viewport height on iOS when opened as a standalone/home screen app. Fixes #5576.
Vaadin Flow 25.2.0-beta1
Overview
Vaadin Flow 25.2 adds Java API for two browser features — Geolocation and Clipboard. The reactive signal API gains pageVisibilitySignal() and routerStateSignal(), and the release ships major dependency upgrades (Vite 8, Spring Boot 4.1.0, JUnit Jupiter 6.1).
Breaking Changes
-
Stop auto-running
vaadinPrepareFrontendin development mode (Gradle)
Commit · Pull request · IssueIDE-triggered Gradle builds no longer interfere with the running Vite dev server. The previous behavior can be restored with
alwaysExecutePrepareFrontend = true. -
Auto-apply
context://for@StyleSheetvalues
Commit · Pull requestBare relative
@StyleSheethrefs now resolve relative to the context root instead of<base>, fixing 404s whenvaadin.urlMappingis set to a non-root path.http(s)://,//,context://,base://, and/-prefixed values pass through unchanged.
New Features
Geolocation API
-
Add Geolocation API
Commit · Pull requestA new
Geolocationutility wraps the browser Geolocation API. One-shot reads viagetPosition(...), continuous tracking viawatchPosition(...), all asynchronous and delivered on the UI thread. Results use sealed types (GeolocationPosition|GeolocationError, plusGeolocationPendingfor the watcher signal) for exhaustive pattern matching. Watches auto-stop on detach;stop()andresume()are explicit.// One-shot read Button locate = new Button("Use my location"); locate.addClickListener(e -> Geolocation.getPosition( pos -> showNearest(pos.coords().latitude(), pos.coords().longitude()), err -> showManualEntry())); // Continuous tracking via reactive signal GeolocationWatcher watcher = Geolocation.watchPosition(this); Signal.effect(() -> { if (watcher.positionSignal().get() instanceof GeolocationPosition pos) { map.setCenter(pos.coords().longitude(), pos.coords().latitude()); } });
-
Split
get()intoonSuccess/onErrorcallbacks
Commit · Pull request -
Add
addPositionListenertoGeolocationWatcher
Commit · Pull request -
Add
GeolocationClientport for external test drivers
Commit · Pull request
Clipboard API
-
Add Clipboard text/html write API
Commit · Pull requestA new
Clipboardentry point binds clipboard writes to a user gesture — the browser requires a fresh gesture for each write. Fluent chaining viaClipboard.onClick(component)produces aClipboardBindingwith fire-and-forget and observed (onCopied/onError) variants for plain text, HTML, field values, and multi-formatClipboardContent.Button copy = new Button("Copy"); // Copy a literal value Clipboard.onClick(copy).writeText("Hello, world"); // Copy the current value of a field, with success/error callbacks Clipboard.onClick(copy).writeText(textField, copied -> Notification.show("Copied " + copied), err -> Notification.show("Failed: " + err.message())); // Multi-format: text + HTML Clipboard.onClick(copy).write(ClipboardContent.create() .text("Hello") .html("<b>Hello</b>"));
Signals
-
Add
pageVisibilitySignal()to Page for tracking browser tab visibility
Commit · Pull requestRead-only signal tracking whether the browser tab is visible+focused, visible+not-focused, or hidden.
-
Add UI router state signal
Commit · Pull requestUI.routerStateSignal()is a read-onlySignal<RouterState>updated atomically alongsideAfterNavigationEventdispatch, so reactive consumers can observe the active route without registering anAfterNavigationListener.
Components and Events
-
Add
getUI()toComponentEvent
Commit · Pull requestNo more
event.getSource().getUI().ifPresent(...)boilerplate. -
Support explicit UI in
ComponentEventconstructor
Commit · Pull request -
Add relevant API to allow drag and drop to a certain location
Commit · Pull request · IssueExposes
clientX/clientYfor all D&D events plus offsets of the target and start element to enable repositioning absolutely-positioned components on drop. -
Introduce
HasComponentsOfTypefor typed child containers
Commit · Pull request
executeJs and Client-Side JS
-
Add
JsFunctionvalue type for composableexecuteJs
Commit · Pull request -
Add
Element.addJsInitializerfor scoped client-side JS lifecycle
Commit · Pull request
Data and Binding
-
Extract interface
HierarchicalTreeDatafromTreeData
Commit · Pull request -
Add overloaded
fromInputStreammethod withfileNameOverride
Commit · Pull request
Build, Frontend, and Tooling
-
Upgrade Vite 7 to Vite 8
Commit · Pull request -
Only install npm packages that have been available more than a day
Commit · Pull requestDefault
--min-release-ageguards against supply-chain attacks via fresh releases. -
BuildFrontend incremental build
Commit · Pull request · Issue -
Add help goal for the Maven plugin
Commit · Pull request
Dependency Updates
- Spring Boot updated to 4.1.0-RC1 (from 4.0.4)
- Vite updated to 8.0.14 (from 7)
- Node.js updated to 24.16.0 (from 24.14.1)
- pnpm updated to 11.1.3 (from 11.0.4)
- TypeScript updated to 6.0.3
- TestBench updated to 10.2.0-beta1 (from 10.1)
- JUnit Jupiter updated to 6.1.0 (from 6.0.3)
- Jackson BOM updated to 3.1.3 (from 3.1.0)
- Jetty updated to 12.1.9 (from 12.1.7)
- Tailwind CSS updated to 4.2.2
- Maven updated to 3.9.16 (from 3.9.14)
- ASM updated to 9.10.1 (from 9.9.1)
- Workbox bumped to current
- Guava updated to 33.6.0-jre (from 33.5.0-jre)
Vaadin Flow 25.1.7
Changes since 25.1.6
Fixes
-
Clear repeatable read transaction before running access tasks (#24400) (CP: 25.1)
Commit · Pull requestWhen a shared signal is updated concurrently with an ongoing UIDL request, effects associated with that UI would run with the repeatable read transaction used for the request. If the transaction cached the old value, effects would miss the update.
The fix moves sessionScopedTransaction = null to execute before runPendingAccessTasks() instead of after, ensuring access tasks read fresh values.
Fixes #24399
-
Encode location query parameter in init request to preserve + (#24089) (CP: 25.1)
Commit · Pull requestRe-add encodeURIComponent() around the location parameter in the init request query string. Without encoding, a literal + in the URL path (e.g. /+/dashboard) is interpreted as a space by the servlet container's query parameter decoding, resulting in InvalidLocationException: Relative path cannot start with /
The encodeURIComponent was removed in #22791 to preserve %2F in wildcard parameters, but this is not needed: double-encoding (%2F becomes %252F) is correctly undone by the servlet's single query parameter decode.
Vaadin Flow 25.1.6
Changes since 25.1.5
New features
-
Support delaying installation of recently published npm packages (#24334) (CP: 25.1)
Commit · Pull requestAdds a minimum package age check (default disabled) so that npm, pnpm and bun are instructed not to install package versions newer than the configured threshold. This mitigates supply-chain attacks where a compromised version is briefly published to the registry. The threshold is exposed via Options#withMinimumPackageAgeDays(int); setting it to 0 disables the check.
-
Expose application properties via
OptionsforTypeScriptBootstrapModifierconsumers (#24073) (CP: 25.1)
Commit · Pull requestTypeScriptBootstrapModifierimplementations (e.g., Copilot) need access > to application properties to conditionally modify bootstrap TypeScript. Currently, the Copilot script is injected in dev mode regardless of > whether Copilot is enabled in the project configuration.
AddwithApplicationConfigurationtoOptionsand property accessor > methods (getApplicationStringProperty,getApplicationBooleanProperty) that returnOptional.empty()when configuration is unavailable (build > time). WireApplicationConfigurationfromDevModeInitializer.
Fixes #24055
Fixes
-
Load Image/IFrame sources when disabled (#24346) (CP: 25.1)
Commit · Pull request · IssueWhen an Image or IFrame backed by a DownloadHandler lives inside a disabled component, the browser receives a 403 and the resource never loads. Image.setSrc(DownloadHandler) and IFrame.setSrc(DownloadHandler) now allow the resource to be served regardless of the owner's enabled state, since these sources are fetched passively as part of rendering rather than as a user action.
-
Loading state muting based on trigger events (#24230) (CP: 25.1)
Commit · Pull requestThis change reverts the eager removal of loading state introduced by #23229, as it causes the indication to disappear during ongoing loading. As a replacement, it re-introduces debouncing tracking of active requests, and adds event-based silencing of the loading indication to avoid flashing the indicator for high-frequency UI interactions.
In addition, instead of setting loading state usingConnectionState.setState()directly, the proper connection state methods (loadingStarted(),loadingFinished()) are used to avoid interference with loading state for requests from other sources outside Flow client. -
Package json hash difference between linux and windows (#24321) (CP: 25.1)
Commit · Pull requestWindows and Linux generated a different hash for the package json content as jackson default indenter used system line separator.
Fixes #24305 -
NPE when web push subscription is expired (#24310) (CP: 25.1)
Commit · Pull requestWhen the push service reports a subscription as expired,
WebPush.sendNotificationthrewNullPointerExceptioninstead of the intendedWebPushException.
Remove a leftover reference to an unassignedHttpResponselocal variable that was no longer populated after the migration tocom.interaso.webpush.
Fixes #24306 > -
Install pnpm deps in hoisted mode + declare @babel/types (#24288) (CP: 25.1)
CommitAdjusted for 25.1's dep-graph: @babel/types is pinned to 7.28.5 to match @babel/preset-react's version on this branch (main pins to 7.29.0 to match @babel/core which is not declared on 25.1). @babel/core and @babel/plugin-transform-react-jsx-development from the main commit are not added — they are not declared as direct deps on 25.1 and the React function location plugin only imports @babel/types. The .npmrc and FrontendTools changes that switch pnpm to hoisted mode apply unchanged.
-
Wrong existence check in getStaticResource (#24283) (CP: 25.1)
Commit · Pull requestOn Jetty 12.1.9, requests for static resources packaged inside a JAR (e.g.
vaadinPush.jsfromflow-push) fail withFileSystemNotFoundException.VaadinServletService.getStaticResourceverifies the URL returned byServletContext.getResourceviaPath.of(url.toURI()), which for ajar:file:...!/entryURI requires the JAR's NIOFileSystemto already be mounted in the JVM-wide cache. Jetty 12.1.8 incidentally kept those filesystems mounted during resource resolution; 12.1.9 no longer does, sogetFileSystemthrows and the existingcatch (URISyntaxException)lets the unchecked exception escape, producing HTTP 500.
Probe the URL withURL.openStream()instead.JarURLConnectionandFileURLConnectionusejava.util.jar.JarFile/java.io.Filedirectly and are independent of the NIOFileSystemscache, so the check works uniformly forfile:andjar:file:URLs and on every Jetty 12 build. The catch is broadened toIOException, covering both missing files (the original Jetty 12 workaround) and missing JAR entries.
Vaadin Flow 25.2.0-alpha13
Changes since 25.2.0-alpha12
New features
-
Add JsFunction value type for composable executeJs
Commit · Pull request · IssueLets server code build a JS function value with captured parameters and pass it as an executeJs parameter, removing the need to string-concatenate framework boilerplate around user-supplied JS. Captures may themselves be Elements or other JsFunctions; the codec encodes them recursively as @v-fn, and the client reifies the value as a callable function with the captures pre-bound.
-
Only install npm packages that have been available more than a day
Commit · Pull requestBumps the default from 0 to 1 to enable the supply-chain delay by default while keeping the window short enough that the same-day Vaadin upgrade pain is at least bounded. Users can still opt out by setting the option to 0.
-
Support delaying installation of recently published npm packages
Commit · Pull requestAdds a minimum package age check (default disabled) so that npm, pnpm and bun are instructed not to install package versions newer than the configured threshold. This mitigates supply-chain attacks where a compromised version is briefly published to the registry. The threshold is exposed via Options#withMinimumPackageAgeDays(int); setting it to 0 disables the check.
Fixes
-
Prevent EOVERRIDE conflict when upgrading vaadin.version
Commit · Pull request · Issue -
Load Image/IFrame sources when disabled
Commit · Pull request · IssueWhen an
ImageorIFramebacked by aDownloadHandlerlives inside a disabled component, the browser receives a 403 and the resource never loads.Image.setSrc(DownloadHandler)andIFrame.setSrc(DownloadHandler)now allow the resource to be served regardless of the owner's enabled state, since these sources are fetched passively as part of rendering rather than as a user action.
Vaadin Flow 25.0.13
Changes since 25.0.12
New features
-
Expose application properties via
OptionsforTypeScriptBootstrapModifierconsumers (#24073) (CP: 25.0)
Commit · Pull request · IssueTypeScriptBootstrapModifierimplementations (e.g., Copilot) need access to application properties to conditionally modify bootstrap TypeScript. Currently, the Copilot script is injected in dev mode regardless of whether Copilot is enabled in the project configuration. AddwithApplicationConfigurationtoOptionsand property accessor methods (getApplicationStringProperty,getApplicationBooleanProperty) that returnOptional.empty()when configuration is unavailable (build time). WireApplicationConfigurationfromDevModeInitializer.
Fixes
-
Load Image/IFrame sources when disabled (CP: 25.0)
Commit · Pull request · IssueWhen an Image or IFrame backed by a DownloadHandler lives inside a disabled component, the browser receives a 403 and the resource never loads. Image.setSrc(DownloadHandler) and IFrame.setSrc(DownloadHandler) now allow the resource to be served regardless of the owner's enabled state, since these sources are fetched passively as part of rendering rather than as a user action.
-
Package json hash difference between linux and windows (#24321)
Commit · Pull request · IssueWindows and Linux generated a different hash for the package json content as jackson default indenter used system line separator.
-
NPE when web push subscription is expired (#24310) (CP: 25.0)
Commit · Pull requestWhen the push service reports a subscription as expired,
WebPush.sendNotificationthrewNullPointerExceptioninstead of the intendedWebPushException.
Remove a leftover reference to an unassignedHttpResponselocal variable that was no longer populated after the migration tocom.interaso.webpush.
Fixes #24306 -
Install pnpm deps in hoisted mode + declare @babel/types (#24288) (CP: 25.0)
Commit · Pull requestSswitches pnpm install to hoisted (flat npm-style) layout so transitive npm deps (
@babel/types,@lit/reactive-element,cookie,set-cookie-parser,@preact/signals-react/runtime) are always reachable from project root, eliminating thevite-basicsIT hang and similar symptoms. -
Wrong existence check in getStaticResource (CP: 25.0)
Commit · Pull requestThis PR cherry-picks changes from the original PR #24283 to branch 25.0
-
Handle Unicode classpath resource paths (#24220)(CP:25.0)
Commit · Pull requestCherry pick of #24220 to 25.0
Vaadin Flow 24.10.5
Changes since 24.10.4
New features
-
Expose application properties via
OptionsforTypeScriptBootstrapModifierconsumers (#24073) (CP: 24.10)
Commit · Pull request · IssueTypeScriptBootstrapModifierimplementations (e.g., Copilot) need access to application properties to conditionally modify bootstrap TypeScript. Currently, the Copilot script is injected in dev mode regardless of whether Copilot is enabled in the project configuration. AddwithApplicationConfigurationtoOptionsand property accessor methods (getApplicationStringProperty,getApplicationBooleanProperty) that returnOptional.empty()when configuration is unavailable (build time). WireApplicationConfigurationfromDevModeInitializer.
Fixes
-
Load Image/IFrame sources when disabled (CP: 24.10)
Commit · Pull request · IssueWhen an Image or IFrame backed by a DownloadHandler lives inside a disabled component, the browser receives a 403 and the resource never loads. Image.setSrc(DownloadHandler) and IFrame.setSrc(DownloadHandler) now allow the resource to be served regardless of the owner's enabled state, since these sources are fetched passively as part of rendering rather than as a user action.
-
NPE when web push subscription is expired (CP: 24.10)
Commit · Pull request · IssueWhen the push service reports a subscription as expired,
WebPush.sendNotificationthrewNullPointerExceptioninstead of the intendedWebPushException. Remove a leftover reference to an unassignedHttpResponselocal variable that was no longer populated after the migration tocom.interaso.webpush. -
Install pnpm deps in hoisted mode + declare @babel/types (#24288) (CP: 24.10)
Commit · Pull requestCherry-pick of #24288 (commit d9290f8) from main to 24.10. ## Summary Same fix as #24288: switches pnpm install to hoisted (flat npm-style) layout so transitive npm deps (
@babel/types,@lit/reactive-element,cookie,set-cookie-parser,@preact/signals-react/runtime) are always reachable from project root, eliminating thevite-basicsIT hang and similar symptoms. ## Adjustments for 24.10 24.10 is pre-flow-build-toolsrefactor (#23161), so all the Java files the original commit touches (FrontendTools.java,FrontendToolsTest.java,NodeUpdaterTest.java,TaskRunPnpmInstallTest.java) live underflow-server/here. The edits are otherwise identical. Two version adjustments to match this branch's dep graph: 1.@babel/typespinned to7.28.5(matching@babel/preset-react) instead of main's7.29.0. 24.10 does not declare@babel/core, so version coherence is anchored topreset-react. 2. Skipped@babel/coreand@babel/plugin-transform-react-jsx-developmentdeclarations from the main commit — not declared as direct deps on 24.10, and the React function location plugin only imports@babel/types. ## Supersedes #24289 This PR replaces #24289 (the narrower @babel/types-only fix). Once this lands, #24289 should be closed. ## Test plan - [ ] CI on this PR passes (specificallyit-tests (1)andit-tests (2)). - [ ]mvn -pl flow-server test -Dtest=NodeUpdaterTest,TaskRunPnpmInstallTest,FrontendToolsTestpasses. - [ ] After install in any vite-using IT module,node_modules/.pnpm/does not exist (or is empty);node_modules/@babel/types/andnode_modules/@lit/reactive-element/exist as real directories at the project root. 🤖 Generated with Claude Code -
Wrong existence check in getStaticResource (CP: 25.0) (#24285) (CP: 24.10)
Commit · Pull requestThis PR cherry-picks changes from the original PR #24285 to branch 24.10. --- #### Original PR description > This PR cherry-picks changes from the original PR #24283 to branch 25.0. > > A conflict in
flow-server/src/test/java/com/vaadin/flow/server/VaadinServletServiceTest.javawas resolved manually: the newgetStaticResource_jarUrlOnJetty12_returnsUrlInsteadOfThrowingtest was rewritten in JUnit 4 idioms (@Rule TemporaryFolder,Assert.*) since 25.0 has not adopted the JUnit 5 migration that landed onmain. > > --- > > > On Jetty 12.1.9, requests for static resources packaged inside a JAR (e.g.vaadinPush.jsfromflow-push) fail with > >FileSystemNotFoundException.VaadinServletService.getStaticResourceverifies the URL returned byServletContext.getResourceviaPath.of(url.toURI()), which for ajar:file:...!/entryURI requires the JAR's NIOFileSystemto already be mounted in the JVM-wide cache. Jetty 12.1.8 incidentally kept those filesystems mounted during resource resolution; 12.1.9 no longer does, sogetFileSystemthrows and the existingcatch (URISyntaxException)lets the unchecked exception escape, producing HTTP 500. > > > > Probe the URL withURL.openStream()instead.JarURLConnectionandFileURLConnectionusejava.util.jar.JarFile/java.io.Filedirectly and are independent of the NIOFileSystemscache, so the check works uniformly forfile:andjar:file:URLs and on every Jetty 12 build. The catch is broadened toIOException, covering both missing files (the original Jetty 12 workaround) and missing JAR entries.
Vaadin Flow 24.9.19
Changes since 24.9.18
New features
-
Expose application properties via
OptionsforTypeScriptBootstrapModifierconsumers (#24073) (CP: 24.10) (#24267) (CP: 24.9)
Commit · Pull requestTypeScriptBootstrapModifierimplementations (e.g., Copilot) need access to application properties to conditionally modify bootstrap TypeScript. Currently, the Copilot script is injected in dev mode regardless of whether Copilot is enabled in the project configuration.
AddwithApplicationConfigurationtoOptionsand property accessor methods (getApplicationStringProperty,getApplicationBooleanProperty) that returnOptional.empty()when configuration is unavailable (build time). WireApplicationConfigurationfromDevModeInitializer.
Fixes #24055
Fixes
-
Load Image/IFrame sources when disabled (CP: 24.10) (#24365) (CP: 24.9)
Commit · Pull request · IssueWhen an Image or IFrame backed by a DownloadHandler lives inside a disabled component, the browser receives a 403 and the resource never loads. Image.setSrc(DownloadHandler) and IFrame.setSrc(DownloadHandler) now allow the resource to be served regardless of the owner's enabled state, since these sources are fetched passively as part of rendering rather than as a user action.
-
NPE when web push subscription is expired (CP: 24.10) (#24311) (CP: 24.9)
Commit · Pull requestWhen the push service reports a subscription as expired,
WebPush.sendNotificationthrewNullPointerExceptioninstead of the intendedWebPushException.
Remove a leftover reference to an unassignedHttpResponselocal variable that was no longer populated after the migration tocom.interaso.webpush.
Fixes #24306 -
Install pnpm deps in hoisted mode + declare @babel/types (#24288) (CP: 24.9)
Commit · Pull requestSwitches pnpm install to hoisted (flat npm-style) layout so transitive npm deps (
@babel/types,@lit/reactive-element,cookie,set-cookie-parser,@preact/signals-react/runtime) are always reachable from project root, eliminating thevite-basicsIT hang and similar symptoms. -
Wrong existence check in getStaticResource (CP: 25.0) (#24285) (CP: 24.9)
Commit · Pull requestOn Jetty 12.1.9, requests for static resources packaged inside a JAR (e.g.
vaadinPush.jsfromflow-push) fail withFileSystemNotFoundException.VaadinServletService.getStaticResourceverifies the URL returned byServletContext.getResourceviaPath.of(url.toURI()), which for ajar:file:...!/entryURI requires the JAR's NIOFileSystemto already be mounted in the JVM-wide cache. Jetty 12.1.8 incidentally kept those filesystems mounted during resource resolution; 12.1.9 no longer does, sogetFileSystemthrows and the existingcatch (URISyntaxException)lets the unchecked exception escape, producing HTTP 500.
Probe the URL withURL.openStream()instead.JarURLConnectionandFileURLConnectionusejava.util.jar.JarFile/java.io.Filedirectly and are independent of the NIOFileSystemscache, so the check works uniformly forfile:andjar:file:URLs and on every Jetty 12 build. The catch is broadened toIOException, covering both missing files (the original Jetty 12 workaround) and missing JAR entries.
Vaadin Flow 25.2.0-alpha12
Changes since 25.2.0-alpha11
Breaking changes
-
Auto-apply context:// for @Stylesheet values
Commit · Pull request · Issue@Stylesheet currently produces broken elements when the Vaadin servlet is mapped at a non-root path (vaadin.urlMapping=/ui/* etc.): the browser resolves the bare relative href against (which points to the servlet mapping path), so a file at META-INF/resources/styles.css is fetched as /ui/styles.css and 404s. Users had to know to write @Stylesheet("context://styles.css") explicitly to step out of the servlet path. Frame the right behavior into the framework instead: - New FrontendDependencyUrlResolver.resolveToContextRoot extracts the prefix-handling rules into one place: http(s)://, //, context://, base:// pass through unchanged; "/" is treated as an absolute server path; "./" leads strip to a context-root-relative value; everything else gets a context:// prefix prepended. Path traversals are rejected. - UIInternals.addComponentDependencies normalizes @Stylesheet values through the resolver before storing them on the dependency list, so component-level @Stylesheet now renders correctly under any servlet mapping. The same normalization keys ActiveStyleSheetTracker so spelling variants of the same file (foo.css, ./foo.css, context://foo.css) deduplicate to a single . - AppShellRegistry.resolveStyleSheetHref delegates to the same resolver, replacing the inline rule set. The trailing BootstrapUriResolver call continues to expand context:// using the servlet-relative path produced by getContextRootRelativePath, so AppShell-level resolution stays consistent with the UIDL path. Test fixtures updated for the canonical context://-prefixed URLs in the dependency list. UidlWriterTest also registers inline test resources at the leading-slash path (/inline.css) to match the servlet container lookup that resolveResource produces for a context:// value.
-
Redesign Geolocation as static utility with watcher handle
Commit · Pull requestRedesigns the Geolocation API as a static utility class with a watcher handle, replacing the previous per-UI facade. API surface Geolocation.getPosition() and Geolocation.watchPosition() are static. UI is implicit (UI.getCurrent()), with explicit-UI overloads for background threads. watchPosition() returns a GeolocationWatcher handle that exposes both a callback API (addPositionListener) and a reactive Signal. The owner component drives the watcher's lifecycle: watchPosition() accepts an unattached owner and starts the underlying browser watch on first attach (so it's safe from a view constructor); the watch auto-stops on detach; stop() and resume() work explicitly. Per-UI state (the GeolocationClient and the availability signal) lives in UIInternals; static methods resolve the client there or install a default one through the GeolocationClientFactory Lookup SPI. options is now a non-null parameter — callers who want browser defaults use the no-options overloads, or pass an empty GeolocationOptions explicitly. The fields inside GeolocationOptions remain independently optional. Error model Callback exceptions thrown from onSuccess/onError in getPosition and from watcher position listeners are routed to VaadinSession.getErrorHandler() instead of being silently swallowed by CompletableFuture.whenComplete or aborting the listener loop. GeolocationError.message() is renamed to debugInfo() to make it clear the value is a free-form, non-localised string suitable for logs and bug reports — not for UI display. Test seam GeolocationClient and WatchHandle become public so external test drivers and native bridges can replace the production client through Lookup. GeolocationOutcome becomes package-private since the public API no longer exposes it. The watcher's bridge-failure error path is unchanged.
New features
-
Support explicit UI in
ComponentEventconstructor
Commit · Pull requestAllows the UI to be provided at construction time so that
getUI()can return it even when the source component is not yet attached. Related to #18818 -
Split get() into onSuccess/onError callbacks
Commit · Pull requestGeolocation.get() now takes a (onSuccess, onError) pair, mirroring GeolocationTracker.addPositionListener and the W3C getCurrentPosition(success, error) signature. The optional GeolocationOptions argument moves to the trailing position so that additional parameters can be added at the end without rearranging the common case. GeolocationOutcome is retained as the SPI sum-type returned by GeolocationClient#get; only the public facade changes shape.
Fixes
-
Loading state muting based on trigger events
Commit · Pull request · IssueThis change reverts the eager removal of loading state introduced by #23229, as it causes the indication to disappear during ongoing loading. As a replacement, it re-introduces debouncing tracking of active requests, and adds event-based silencing of the loading indication to avoid flashing the indicator for high-frequency UI interactions. In addition, instead of setting loading state using
ConnectionState.setState()directly, the proper connection state methods (loadingStarted(),loadingFinished()) are used to avoid interference with loading state for requests from other sources outside Flow client. -
Package json hash difference between linux and windows
Commit · Pull request · IssueWindows and Linux generated a different hash for the package json content as jackson default indenter used system line separator.
-
NPE when web push subscription is expired
Commit · Pull request · IssueWhen the push service reports a subscription as expired,
WebPush.sendNotificationthrewNullPointerExceptioninstead of the intendedWebPushException. Remove a leftover reference to an unassignedHttpResponselocal variable that was no longer populated after the migration tocom.interaso.webpush. -
Pin pnpm version when invoking via npx
Commit · Pull requestgetSuitablePnpm() invoked
npx --yes --quiet pnpm, letting npx resolve whatever it considered latest (or whatever was cached) rather than the DEFAULT_PNPM_VERSION constant. Passpnpm@<DEFAULT_PNPM_VERSION>so the installed version matches the constant. -
Install pnpm deps in hoisted mode + declare @babel/types
Commit · Pull request
Vaadin Flow 23.6.12
Changes since 23.6.11
Fixes
-
Install pnpm deps in hoisted mode + declare @babel/types (#24288) (CP:23.7) (#24322) (CP: 23.6)
Commit · Pull requestThe Vite dev server intermittently fails (or hangs) on vite-basics and other Vite-using IT modules because transitive npm dependencies are not consistently reachable from the project's root node_modules.
Selenium tests then wait for pages that never render, and the matrix shard times out at the 30-minute job cap.