Docs

Documentation versions (currently viewingVaadin 25)
Documentation translations (currently viewingEnglish)

Upgrading from Vaadin 25.2 to 25.3

Changes needed to upgrade an application from Vaadin 25.2 to Vaadin 25.3.

Vaadin 25.3 is a minor release, and for most applications the upgrade is a version bump. The system requirements are the same as for Vaadin 25.2: Java 21 or later, Spring Boot 4.1 or later, and Node.js 24 or later. This page lists the changes that can still need attention, followed by the deprecations to act on before Vaadin 26.

For what’s new in Vaadin 25.3, see the release notes. If you’re upgrading from Vaadin 24, follow Upgrading from Vaadin 24 instead — it includes the Vaadin 25.3 changes.

Update the Version

Set the Vaadin version in the pom.xml or gradle.properties file:

Source code
XML
<vaadin.version>25.3.0</vaadin.version>
XML
properties
properties

Use the latest 25.3 maintenance release, if one is available. See the list of releases on GitHub.

Build and Frontend

Default index.html

The build now generates the default index.html into frontend/generated/, and only when the project has no frontend/index.html of its own. An index.html that an older build generated into frontend — and that was committed to source control — takes precedence and hides later improvements to the default. If you haven’t customized it, delete it. See Default Template & Entry Point.

TypeScript 7 and React Router 8

The frontend toolchain moves from TypeScript 6 to 7 and from React Router 7 to 8. The tsconfig.json that Vaadin generates is unchanged. If you have customized it, remove any compiler options that TypeScript 6 deprecated, as TypeScript 7 no longer accepts them. If your React views use React Router APIs directly, see the React Router upgrade guide.

Client-side engine

The engine that runs in the browser is now written in TypeScript and bundled by Vite. It replaces the engine that Google Web Toolkit (GWT) compiled from Java. Applications need no changes. Only an add-on that compiled against com.vaadin.client.*, or a build step that referenced VAADIN/static/client/, is affected. See Client-Side Engine Ported to TypeScript.

Java API Changes

Image

Image extends HtmlComponent instead of HtmlContainer, so it no longer has the add(), remove(), removeAll(), setText(), and getText() methods. An img element never rendered children or text. Remove those calls, and use setAlt() for the alternative text.

Navigating to a location with a query string

UI.navigate(String) parses a query string and fragment in the location, as in ui.navigate("user/123?tab=orders"). Passing a QueryParameters object together with such a location throws an IllegalArgumentException, since it would discard the parameters in the string. See Navigating Between Routes.

Custom servlets

VaadinServlet no longer calls serveStaticOrWebJarRequest(), so overriding it has no effect. To customize how static resources are served, override createStaticFileHandler() instead.

Spring configuration classes

The vaadin-spring configuration classes are now Spring Boot auto-configurations, with proxyBeanMethods=false. This only affects code that extends or imports these classes, and relies on a call from one bean method to another returning the shared bean instance.

Security

When a log-in view is configured with VaadinSecurityConfigurer.loginView(), an unauthorized request for a sub-resource — a stylesheet, script, image, font, or web app manifest — is answered with 401 Unauthorized instead of a redirect to the log-in view. A test or client that expects the redirect has to expect 401. See Security Changes in Vaadin 25.3.

Components

Grid: hidden columns

Value providers, tooltip generators, and part name generators no longer run for hidden columns, and Grid sends no data to the browser for them. Showing a column generates its data again. Don’t rely on side effects of these callbacks, or on client-side access to the data of hidden columns.

Grid: selection and item details

Selection and item details react only to the user’s clicks. Selecting an item on the server no longer opens its details, and the selected row is no longer mirrored to the activeItem property of the web component. Update any client-side code that reads or sets activeItem to select a row or open its details.

Dialog focus

Non-modal dialogs still receive focus when opened, but no longer trap it: Tab moves on to the rest of the page. setFocusTrap() is deprecated — use setAutofocus() instead. See Dialog.

Multi-Select Combo Box

The value is synchronized to the server on the web component’s change event. Client-side code that sets the selectedItems property directly has to dispatch a change event for the server to receive the new value. Server-side setValue() and user interaction aren’t affected.

AI Integration (Preview)

The AI integration is still a preview feature, behind the com.vaadin.experimental.aiComponents feature flag, and Vaadin 25.3 changes its API:

  • The vaadin-ai-components-flow artifact is replaced by two modules. The free vaadin-ai-core-flow module contains the orchestrator, the LLM providers, the component interfaces, and the AIController interface. The commercial vaadin-ai-extensions-flow module contains the built-in Grid, Chart, and Form controllers, which now require a commercial Vaadin subscription. The vaadin-core dependency includes only the free module, while vaadin includes both. Replace any explicit vaadin-ai-components-flow dependency. The Java package names are unchanged.

  • AIController.onRequest() now takes a RequestListener.RequestEvent, and onResponse(Throwable) is now onResponse(ResponseListener.ResponseEvent), where the error is available from getError(). Update custom controllers to the new signatures.

  • FormAIController fires addFieldValueChangeListener() listeners once per changed field, replacing addFieldValueChangedListener(), which fired once per turn. showFieldHighlight() and hideFieldHighlight() are removed: fields that the AI changes are marked automatically with a marker that lets the user revert the change. Turn this off with setFieldMarkerEnabled(false). Fields are also no longer set to read-only on the server while a turn runs.

See AI Support for details.

Observability Kit

Vaadin 25.3 comes with Observability Kit 5, a rewrite built on Micrometer. It isn’t a drop-in replacement for version 4: there’s no Java agent any more, and meter names, configuration, tracing data, and the custom instrumentation API have changed. If your application uses Observability Kit, follow Migrating to Version 5.

Browserless Testing and TestBench

Some component testers now behave more like a browser, which can make existing tests fail:

  • NumberFieldTester, DatePickerTester, TimePickerTester, and DateTimePickerTester accept a value that violates min, max, step, or a required constraint, and mark the field invalid, instead of throwing an IllegalArgumentException. Assert the validity instead of the exception.

  • A read-only value component isn’t usable, so setting its value through a tester throws.

  • Queries find the components set as a Grid column header, footer, or editor.

  • GridTester.getCellComponent() returns the component that the grid rendered, and throws for a cell that the grid doesn’t render. Use renderCellComponent() for the old behavior.

  • test(treeGrid) returns a TreeGridTester, and test(gridContextMenu) returns a GridContextMenuTester.

  • A context menu has to be opened with open() before its items can be clicked or inspected.

  • CheckboxGroupTester.updateSelection() is no longer public.

  • Override frameworkLookupServices() instead of lookupServices() to replace a service that the Spring or Quarkus integration registers. lookupServices() is deprecated in favor of the test configuration.

  • In TestBench, SelectElement.getSelectedText() returns an empty string when no item is selected.

See TestBench and Browserless Testing for examples and details.

Deprecations to Address Before Vaadin 26

Deprecated APIs still work in Vaadin 25.3, but most of them are removed in Vaadin 26. Replacing them now makes the next upgrade easier.

Deprecated Replacement

NativeTable and the related NativeTable* components and TestBench elements

The Table component family. See Migrating from Native Table.

SessionLockListener, RpcInvocationListener, and the VaadinService methods that add them

Events of the service event bus. See Deprecated Listener Interfaces.

setItems(rootItems, childItemProvider) and setTreeData() of Tree Grid, and the TreeDataProvider(TreeData) constructor

A TreeDataProvider with an explicit hierarchy format, as the default changes from NESTED to FLATTENED in Vaadin 26. See the example below.

ValueChangeMode.ON_BLUR

ValueChangeMode.ON_CHANGE, which fires on focus loss only when the value has changed.

Dialog.setFocusTrap()

Dialog.setAutofocus()

setRole() of Dialog, Popover, and Badge

setAriaRole()

Tabs.indexOf()

Tabs.getIndexOf()

SplitLayout.setPrimaryStyle() and setSecondaryStyle()

Styling getPrimaryComponent() and getSecondaryComponent() directly.

LoginI18n.createDefault() and CrudI18n.createDefault()

A new instance with only the customized texts set. Unset texts fall back to the component defaults.

ExtendedClientDetails.getCurrentDate()

ExtendedClientDetails.getBrowserTime()

WebBrowser.isIPhone(), ExtendedClientDetails.isIPad(), and ExtendedClientDetails.isIOS()

Feature detection, or ExtendedClientDetails.getNavigatorPlatform().

VaadinServlet.serveStaticOrWebJarRequest()

Overriding createStaticFileHandler().

About 150 VaadinIcon constants, such as the _O outline variants and brand icons

The replacement named in the Javadoc of each constant. For brand icons, use an icon set such as Simple Icons.

To keep the current Tree Grid behavior, build the TreeDataProvider yourself instead of calling setItems():

Source code
Java
// Before
treeGrid.setItems(rootFolders, Folder::children);

// After
TreeData<Folder> treeData = new TreeData<>();
treeData.addItems(rootFolders, Folder::children);
treeGrid.setDataProvider(new TreeDataProvider<>(treeData,
        HierarchicalDataProvider.HierarchyFormat.NESTED));

Use HierarchyFormat.FLATTENED instead to adopt the Vaadin 26 default now. It keeps the scroll position more reliably when the hierarchy changes, but it changes how some methods, such as scrollToIndex(), interpret their arguments. See Hierarchy Formats.

These products and features are deprecated as well, and aren’t available in Vaadin 26: