github vaadin/flow 25.3.0-alpha1
Vaadin Flow 25.3.0-alpha1

pre-release4 hours ago

Changes since 25.2.0-beta1

All changes

Breaking changes

  • NativeLabel.setFor() lazily resolves and auto-generates IDs
    Commit · Pull request · Issue

    setFor(Component) now resolves the component's ID lazily at sync time instead of requiring it immediately, and auto-generates one if the component still has no ID. Developers no longer need to manually assign IDs to components used with setFor().

New features

  • Support not having a project-specific index.html
    Commit · Pull request

    The Vaadin-generated index.html is again placed in frontend/generated/ instead of frontend/. A user-provided frontend/index.html still overrides the default, so having an index.html in the project is optional again, as in Vaadin 14.

  • Add HasAriaRole interface
    Commit · Pull request

    Adds a shared HasAriaRole mixin interface so components like Card, Badge, Dialog, and Popover can share a single contract instead of duplicating logic. It sits next to HasAriaLabel in com.vaadin.flow.component and follows the same pattern: attribute-based storage, null clears the attribute, and the getter returns an Optional.

  • Allow setting frontend build toggles via system properties
    Commit · Pull request

    Several build-frontend toggles could previously only be set through a POM <configuration> block. A property attribute is added to generateBundle, runNpmInstall, generateEmbeddableWebComponents, optimizeBundle, and eagerServerLoad so they can be overridden at runtime, e.g. -Dvaadin.generateBundle=false.

  • Warn when an add-on uses the legacy META-INF/resources/frontend layout
    Commit · Pull request

    TaskCopyFrontendFiles still scans the deprecated META-INF/resources/frontend/ for backwards compatibility, but now emits a once-per-jar/dir warning recommending the split layout: bundle sources for @JsModule/@CssImport under META-INF/frontend/, and runtime resources for @StyleSheet/@JavaScript under META-INF/resources/.

  • Support custom timeout for DevTools license download
    Commit · Pull request · Issue

    The DevTools license-checker waited a fixed 60 seconds for the asynchronous license download, which is too short for first-time users who must still register a Vaadin account. Callers of downloadLicense can now pass an optional timeout; when omitted, the previous default is kept.

  • Add RouterState.isNavigationPending()
    Commit · Pull request · Issue

    Adds RouterState.isNavigationPending() so user code can detect the pre-navigation state without an NPE.

  • Fail loudly when a trigger is created without an action
    Commit · Pull request

    A Trigger that is never armed with an action does nothing on the client, which is almost always a forgotten terminal binding call (e.g. Clipboard.onClick(button) with no following writeText(...)). This is now detected in the Trigger base class via beforeClientResponse, throwing an IllegalStateException if no action was committed. Trigger.triggersWhenAttached(target, supplier) is added so a binding that legitimately defers wiring until a target attaches is not mistaken for a forgotten one.

  • Expose page title resolution as public API
    Commit · Pull request

    Adds Router.resolvePageTitle for resolving the page title of a navigation target without instantiating it, applying the same dynamic / default / static PageTitle chain used during navigation. RouteUtil.resolvePageTitle is deprecated and now delegates to Router.

  • Allow custom actions and triggers to consume trigger inputs
    Commit · Pull request

    Action.Input#toJs is widened to public so an Action implemented outside the internal trigger package can render an Input received as a parameter. HandlerInput and its constructor are also made public so custom trigger families can reuse the canonical implementation instead of declaring anonymous subclasses.

  • Add Screen Orientation API support to Page
    Commit · Pull request

    Exposes the browser Screen Orientation API through Page methods, providing a read-only signal for tracking orientation changes and methods to lock/unlock screen orientation for tablet and mobile apps.

  • Add Web Share API support
    Commit · Pull request

    Adds a WebShare facade for the browser's Web Share API: WebShare.onClick(button).share(ShareContent.create().title(...).text(...).url(...)) opens the native share sheet on click, optionally reporting the outcome through onShared/onError callbacks. ShareContent slots accept either string literals or HasValue components, and WebShare.supportSignal() exposes feature detection as a read-only signal.

  • Set X-Frame-Options header by default
    Commit · Pull request · Issue

    The X-Frame-Options response header is now sent with a default value of SAMEORIGIN so browsers opt in to clickjacking protection out of the box. It is configurable through the new frameOptions init parameter (DeploymentConfiguration#getFrameOptions); an empty value disables the header for apps meant to be embedded in a frame.

  • Validate URL schemes in Anchor, IFrame and Page#open
    Commit · Pull request

    Re-introduces URL-scheme validation for link and navigation sinks using application-wide configuration plus a per-instance opt-out. Safe schemes are read from the new com.vaadin.safeUrlSchemes (InitParameters.URL_SAFE_SCHEMES) property, defaulting to http, https, mailto, tel, and ftp, so script-capable schemes such as javascript and data are rejected. Setting the property to * marks every scheme safe. For trusted, hard-coded URLs, each sink offers an unsafe variant: Anchor#setUnsafeHref, IFrame#setUnsafeSrc, and Page#openUnsafe.

  • Add UI.triggerAfter for deferred server-side callbacks
    Commit · Pull request

    Adds UI.triggerAfter(Duration, SerializableRunnable), which runs a task on the server once the given delay has elapsed. The delay is measured by the browser via a one-shot client timer that makes a normal round trip when it elapses, so a single deferred event can be handled without enabling push. The returned Registration cancels the client timer when removed.

  • Add Clipboard.onFilePaste for server-side file paste handling
    Commit · Pull request

    Pastes that carry files (screenshots, files copied from a file manager) flow through the supplied UploadHandler — one POST per file, matching vaadin-upload's wire format. PasteFileHandler offers inMemory(consumer), which delivers each file as a PasteFile, and session(...), which builds an onStart / onFile / onComplete listener that knows when a whole paste has finished. onFilePaste is independent of onPaste; both fire on the same gesture when registered.

  • Add route hierarchy with dynamic titles
    Commit · Pull request

    Introduces an instance-free mechanism for resolving page titles and logical route hierarchies without instantiating navigation target components. New annotations, interfaces, and APIs let routes declare a PageTitleGenerator and a static or resolver-based logical parent, enabling dynamic titles and hierarchical navigation aids such as breadcrumbs and menus.

  • Add Safelist overloads to Html component
    Commit · Pull request · Issue

    Adds Safelist overloads to the Html component, giving control over which HTML elements and attributes are permitted in the parsed content.

  • Add Clipboard.onPaste for server-side paste handling
    Commit · Pull request

    Adds Clipboard.onPaste(Component, listener) (and a PasteOptions overload) that forwards the browser's native paste event to a server-side listener as a PasteEvent carrying text/plain, text/html, the source component, and the closest Flow-tracked target element. Pass any component to scope the listener to it and its descendants, or the UI for UI-wide scope. By default, pastes targeting input/textarea/contenteditable elements are filtered out client-side; PasteOptions.includingInputFields() disables that filter.

  • Public read API on ClipboardBinding
    Commit · Pull request

    Clipboard.onClick(button).read(onPayload, onError) — and the readText / readHtml convenience variants — make the clipboard read side reachable from the same binding entry point as the write side. ClipboardPayload moves to the public clipboard package so it can appear in these method signatures.

  • OpenInNewTabAction for the action trigger framework
    Commit · Pull request

    Adds OpenInNewTabAction to the internal trigger system for opening URLs in a new tab or window in response to user actions. Dangerous javascript: URLs are blocked both server- and client-side, and popup features are configurable.

  • DownloadAction for the action trigger framework
    Commit · Pull request

    Adds a server-side DownloadAction for triggering browser downloads from static URLs, server-generated streams, or client-resolved values, with optional filename suggestions. The client-side helper synthesizes and clicks an anchor element and is exposed under window.Vaadin.Flow.download.start.

  • Add image/png to the Clipboard write API
    Commit · Pull request

    Lets an app copy an image to the system clipboard as image/png when a trigger fires, alongside the existing text/plain and text/html slots. Two image sources are supported: an <img>-rooted component already on the page, or a DownloadHandler that serves bytes from the server. Image-only and multi-format writes (text + HTML + image in one ClipboardItem) are both supported via the new ClipboardBinding.writeImage(...) methods and ClipboardContent.image(...).

  • RPC invocation listener support
    Commit · Pull request

    Enables listening to RPC invocations.

  • Add session lock request, acquire, release events
    Commit · Pull request

    Enables listening to session lock request, acquire, and release events.

  • Screen Wake Lock API on Page
    Commit · Pull request

    Adds a per-UI WakeLock facade reached through Page#getWakeLock(), exposing request(), release(), and an active-state Signal<Boolean>. The client transparently re-acquires the lock on visibilitychange, so a single request() covers the lifetime of a view; failures (insecure context, unsupported browser, denied) leave the active signal false.

  • SizeTrigger — a trigger that fires on element resize
    Commit · Pull request

    Adds a SizeTrigger that wires the browser's ResizeObserver into the trigger framework, exposing width(), height(), and size() inputs. Combined with SetSignalAction, this provides a purely server-side equivalent of an element size signal.

  • Add Fullscreen API wrapping the browser Fullscreen API
    Commit · Pull request

    Adds Component.requestFullscreen() (using a wrapper approach that handles Vaadin theming and overlay components correctly), along with Page.requestFullscreen(), Page.exitFullscreen(), and Page.fullscreenSignal() for reactive observation of the fullscreen state.

  • Add virtual-aware component tree traversal helpers
    Commit · Pull request

    Adds ComponentUtil.getAllChildren and ComponentUtil.streamDescendants. Unlike Component.getChildren, these include components attached as virtual children (slotted helpers, overlays attached to the UI, the client-side routing wrapper), so tools needing a complete component tree no longer have to reach into internal APIs.

  • SignalInput — read a server-side Signal at trigger fire time
    Commit · Pull request

    Adds SignalInput<T>(Component owner, Signal<T> signal) so actions can use a server-side signal as their value source at trigger fire time without first projecting it onto a DOM property.

  • CallbackAction + SetSignalAction — trigger actions for server-side callbacks
    Commit · Pull request

    CallbackAction<T> forwards a value from a trigger's handler scope back to the server, decodes it as T, and hands it to a SerializableConsumer<T> on the UI thread, bridging any client-side trigger into arbitrary server-side state. SetSignalAction is a thin named subclass for the common signal::set case.

Fixes

  • Keep component fullscreen working when the target is the view root
    Commit · Pull request

    requestComponentFullscreen threw "Cannot read properties of undefined" when the fullscreened component was the wrapper's direct child (the route view root), because the inserted placeholder comment became the wrapper's first node. The view root is now captured via firstElementChild before mutating the DOM, and hiding is skipped when the fullscreened component is itself the view root.

  • Move internal frontend sources out of deprecated location
    Commit · Pull request · Issue

    flow-react and flow-dnd shipped their @JsModule bundle sources (ReactRouterOutletElement.tsx and dndConnector.js) under the deprecated META-INF/resources/frontend/ location, triggering a per-jar deprecation warning. They are moved to META-INF/frontend/, with FrontendDependencies falling back to the legacy location for older add-on jars.

  • Do not keep vaadin.overrides
    Commit · Pull request · Issue

    When setting overrides, Vaadin versions are removed and re-added from the platform, $VALUE entries with no dependency or devDependency are cleared, and dependencies/devDependencies are added as $ overrides. User overrides should live in dependencies/devDependencies.

  • Allow UI polling while a modal component is open
    Commit · Pull request · Issue

    Poll listeners registered through PollNotifier.addPollListener are now registered with allowInert, so they keep firing even when a modal component makes the UI inert. UI polling is a global, UI-level feature and should not be blocked by a modality curtain; previously, opening a modal dialog dropped poll events for as long as the modal stayed open.

  • Ignore empty entries when parsing postinstall package lists
    Commit · Pull request · Issue

    Splitting an empty configuration value on "," yields a single empty string rather than an empty array, which caused TaskRunNpmInstall to attempt a postinstall for a package with an empty name. The additional and exclude postinstall package properties are now parsed through a shared helper that trims entries and drops blank ones, so an unset property yields an empty list.

  • Keep project version data in telemetry after a clear
    Commit · Pull request

    The dev-mode usage statistics file is shared by all dev servers on a machine; after a successful upload, StatisticsSender cleared the whole projects array, wiping the data of other still-running dev servers. Project identity data (flowVersion, vaadinVersion, hillaVersion, sourceId) is now re-asserted whenever a running session writes project data and the entry is missing it, so reports always include complete version information.

  • Write frontend build files into build dir when it is outside project dir
    Commit · Pull request · Issue

    When the build dir is relocated outside the project dir, vaadinPrepareFrontend wrote vaadin-dev-server-settings.json and the dev-bundle output under the source tree. buildFolder() is now always relative to projectDir.

  • Cancel pending validation effect listener on binding removal
    Commit · Pull request · Issue

    Binding a not-yet-attached field schedules the internal validation signal effect via a component attach listener. That listener registration was not tracked, so unbind() could not cancel it, leaving a stale listener that fired on a later attach and threw an NPE ("This binding is already unbound"). The attach listener registration is now stored and removed in unbind().

  • Support the configuration cache when packaging the production jar
    Commit · Pull request · Issue

    The production-mode token-restore action was added as a Jar.doFirst {} whose lambda captured the whole Project, which can't be serialized for the configuration cache. It now captures the vaadinBuildFrontendToken service provider instead.

  • Preserve dev-server generated frontend files during prepare-frontend
    Commit · Pull request

    A standalone prepare-frontend run cleaned the frontend generated folder by deleting any file it did not itself produce, removing files generated only by a full generation run (index.tsx, vaadin-react.tsx, layouts.json, flow/ReactAdapter.tsx, vite-devmode.ts) out from under a running app. A generation run now records the files it produces in a manifest; the prepare-frontend cleanup reads that manifest and preserves these files instead of deleting them.

  • Improve shared signal transaction error message
    Commit · Pull request

    Clarifies the error shown when updating multiple shared signals in a transaction, explaining the restriction with cluster context.

  • Fire cancelable event on license download instead of forcing reload
    Commit · Pull request · Issue

    DevTools reloaded the page when a license was downloaded, which prevented consumers (such as Copilot) from resuming an ongoing operation. A cancelable vaadin-license-download-completed event is now dispatched on the document; if no listener calls preventDefault(), the previous reload behavior is kept as the default.

  • Send browser details as plain query parameters during v-r=init
    Commit · Pull request · Issue

    The initial v-r=init bootstrap request appended browser details as a single JSON-encoded v-browserDetails query parameter, whose percent-encoded escapes (%7B, %22, %3A, ...) some firewalls/WAFs flag and block, failing the app on the first page load. Browser details are now appended as individual, unwrapped v-* query parameters (e.g. &v-sw=1641&v-tzid=Europe%2FBerlin), which contain no JSON braces or quotes.

  • Write generated frontend files atomically
    Commit · Pull request

    Generated frontend files were written via Files.writeString, which truncates and rewrites in place, so a file watcher such as Vite's could read an empty or partial file and crash the dev server. FileIOUtils.writeIfChanged now writes to a temp file in the same directory and moves it over the target atomically (falling back to a regular replace where atomic moves are unsupported).

  • Read Vaadin version from vaadin-core-internal pom.properties
    Commit · Pull request

    Platform.getVaadinVersion() now reads from vaadin-core-internal/pom.properties instead of the hardcoded vaadin-core/pom.properties path. vaadin-core always depends on vaadin-core-internal, so the version is always available on the classpath.

  • Unpack prod bundle on Windows mapped network drives
    Commit · Pull request · Issue

    The Zip Slip guard in CompressUtil.newFile canonicalized the target dir and the not-yet-created entry separately; on mapped/subst drives getCanonicalPath() returns inconsistent forms, so legitimate entries were rejected. The destination is now canonicalized once and entries are resolved lexically, checking containment with Path.startsWith.

  • Declare signal class tokens as Class<@NonNull T>
    Commit · Pull request

    NullAway 0.13.2+ rejects passing String.class to a signal constructor taking Class<T> for a @Nullable element type, since Class<T> is invariant. The type-token parameter and backing field are now declared as Class<@NonNull T>, letting callers pass a plain class literal for a nullable element type with no cast.

  • Omit feature flag updater script when no flags are enabled
    Commit · Pull request · Issue

    The feature-flag bootstrap script was always written into index.html, even when no flags were enabled, shipping a redundant registration in every default production app. It is now omitted when no feature flags are enabled.

  • Avoid stale and duplicate observers on concurrent Effect revalidation
    Commit · Pull request

    Effect.revalidate() registers signal-tree observers without holding the Effect monitor (to avoid the ABBA deadlock fixed in #24362), so overlapping revalidation/invalidation/activation attempts could each add a generation of observers, leaving duplicate or stale listeners. A generation counter bumped under the Effect monitor now lets each attempt install its observers only if it is still the latest; stale attempts remove the observers they created.

  • Revert "fix: Add Url validation in Anchor and Page#open (#24371)"
    Commit · Pull request

    Reverts commit a35f9be. The validation is re-introduced in a thread-safe form by #24539.

  • Add Url validation in Anchor and Page#open
    Commit · Pull request

    Adds URL validation in Anchor and Page#open. Superseded — reverted in #24502 and re-introduced via #24539.

  • iOS home screen app height
    Commit · Pull request · Issue

    The bootstrap page now ensures the app covers the entire viewport height on iOS when opened as a standalone / home-screen app.

  • Avoid false infinite loop detection when a cached signal self-updates
    Commit · Pull request · Issue

    When an effect reads a cached signal that detects its value is stale, the cached signal recomputes and submits an update, which was incorrectly flagged as an infinite loop even though it is lazy evaluation during a read, not a write loop. A thread-local flag now marks the read-triggered update context so infinite-loop detection is skipped for it.

Don't miss a new flow release

NewReleases is sending notifications on new releases.