diff --git a/articles/upgrading/V23-V24-steps.adoc b/articles/upgrading/V23-V24-steps.adoc index 3834b006dc..0a055b9615 100644 --- a/articles/upgrading/V23-V24-steps.adoc +++ b/articles/upgrading/V23-V24-steps.adoc @@ -1,6 +1,6 @@ --- -title: Upgrading from Vaadin 23 (removed) +title: Upgrading from Vaadin 24 (removed) section-nav: hidden --- -This page has moved: <> +This page has moved: <> diff --git a/articles/upgrading/index.adoc b/articles/upgrading/index.adoc index 85b4e38bc9..a90ccb0aa5 100644 --- a/articles/upgrading/index.adoc +++ b/articles/upgrading/index.adoc @@ -1,59 +1,69 @@ --- title: Upgrading Guide page-title: How to upgrade Vaadin applications -description: Changes needed to upgrade an application from Vaadin 23 to the latest version. +description: Changes needed to upgrade an application from Vaadin 24 to the latest version. meta-description: Follow this comprehensive guide to upgrade your Vaadin applications to the latest version. order: 900 --- -= Upgrading from Vaadin 23 += Upgrading from Vaadin 24 -This guide goes through the changes you'll need to make in your applications when upgrading from Vaadin 23 to the latest version. After making them, your application should compile, run, behave, and look the way it did before you upgraded. +This guide goes through the changes you'll need to make in your applications when upgrading from Vaadin 24 to the latest version. After making them, your application should compile, run, behave, and look the way it did before you upgraded. .Upgrading from Earlier Version [TIP] -See link:/docs/v23/upgrading/essential-steps[Vaadin 14 to 23 Upgrade Instructions] if you're upgrading from a version earlier than Vaadin 23. +See link:/docs/v24/upgrading[Vaadin 23 to 24 Upgrade Instructions] if you're upgrading from a version earlier than Vaadin 24. Many of the breaking changes are needed because of fundamental changes in the Java platform and the major dependencies on which Vaadin relies. This includes the following: -Servlet 6:: -Vaadin 24 is based on Servlet 6 specifications. It's compatible with Jakarta EE 10. Vaadin encapsulates the usage of the classes from `javax` and `jakarta` packages. Therefore, application code doesn't need to use servlets, directly. Nevertheless, this is still needed in various cases -- like accessing cookies, setting servlet parameters, etc. +// Allow LTS +pass:[] -Spring Boot 3:: -Vaadin 24 uses the latest Spring Boot 3 and Spring Framework 6 versions. This leads to making breaking changes in Spring-based features, compared to earlier Spring Boot 2 and Spring Framework 5 versions. +Java 21:: +Vaadin 25 requires Java 21 or later. Java 21 is the Long Term Support (LTS) version of Java. Upgrading to Java 21 might require you to upgrade other dependencies in your application. -Java 17:: -Vaadin 24 requires Java 17 or later. This is dictated by Spring Framework and newer versions of application servers. +pass:[] + +Spring Boot 4:: +Vaadin 25 uses the latest Spring Boot 4 and Spring Framework 7 versions. This leads to making breaking changes in Spring-based features, compared to earlier Spring Boot 3.5 and Spring Framework 6 versions. Details can be found in link:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Migration-Guide[Spring Boot 4 Migration Guide]. + +Servlet 6.1:: +Vaadin 25 is based on link:https://jakarta.ee/specifications/servlet/6.1/[Servlet 6.1] specification, which is compatible with link:https://jakarta.ee/specifications/platform/11/[Jakarta EE 11]. When upgrading from Vaadin 24 (Servlet 6 and Jakarta EE10), changes are typically not needed. + +Gradle 8/9:: +Gradle 8 (8.14 and later) and Gradle 9 releases are supported. + +Jackson 3:: +Elemental has been replaced with Jackson while Jackson version has been updated to 3. This only affects you if your application uses some of the affected low-level APIs. Details can be found in link:https://github.com/vaadin/flow/issues/21060[Finalize Jackson conversion] and its sub-issues. + +Node.js 24:: +Vaadin 25 requires Node.js 24 or later for building the frontend part of the application. Node.js 24 becomes the active Long Term Support (LTS) before Vaadin 25.0.0 - guaranteeing the longest possible support. + +React 19:: +Vaadin 25 uses React 19 for the React-based components and views. Details about the changes in React 19 can be found in link:https://react.dev/blog/2024/04/25/react-19-upgrade-guide[React 19 Upgrade Guide]. == Overview -Vaadin 24 doesn't change fundamentally how applications are developed and behave. Nevertheless, the upgrade process requires the following essential tasks and tests: +Vaadin 25 doesn't change fundamentally how applications are developed and behave. Nevertheless, the upgrade process requires the following essential tasks and tests: Preparation:: -Upgrade the Vaadin version in the project's [filename]`pom.xml` file, checking for the latest Vaadin 24 release link:https://github.com/vaadin/platform/releases[in GitHub]. +Upgrade the Vaadin version in the project's [filename]`pom.xml` file, checking for the latest Vaadin 25 release link:https://github.com/vaadin/platform/releases[in GitHub]. -Jakarta EE 10:: -Convert package names to Jakarta EE 10 namespace. +Upgrade Java:: +Upgrade your application to use Java 21 or later. Upgrade Spring:: -For Spring-based applications, upgrade to Spring Boot 3 or Spring Framework 6, depending on which is used in your project. For non-Spring applications, upgrade the application server version to one that's compatible with Jakarta EE 10. +For Spring-based applications, upgrade to Spring Boot 4 or Spring Framework 7, depending on which is used in your project. For non-Spring applications, upgrade the application server version to one that's compatible with Jakarta EE 11. Other Dependencies:: -Upgrade third-party dependencies used in your project (e.g., Maven/Gradle plugins, libraries, frameworks) to the Jakarta and Spring-compatible versions. +Upgrade third-party dependencies used in your project (e.g., Maven/Gradle plugins, libraries, frameworks) to compatible versions. Verify & Test:: Ensure your application is not using deprecated code fragments. + -Make sure your application runs well on Java 17 runtime. -+ -Verify that the frontend build works as it should with Vite since webpack is no longer supported. - - -== Limitations - -Portlet and OSGi integrations are not included for two reasons: First, the latest Portlet 3 specification corresponds to Servlet 3, and it doesn't work with Servlet 6. Second, a Jakarta EE 10 compatible version of OSGi core runtime https://felix.apache.org/documentation/index.html[Apache Felix 8] is under development. The https://karaf.apache.org/[Apache Karaf] container is based on Apache Felix and doesn't have a Jakarta-compatible version. +Make sure your application runs well on Java 21 runtime. == Preparation @@ -78,54 +88,56 @@ vaadinVersion={vaadin-version} See the link:https://github.com/vaadin/platform/releases[list of releases on GitHub] for the latest one. +== Java Version -== Jakarta EE 10 Namespaces - -You can use the free tools, https://github.com/eclipse/transformer[Eclipse Transformer] and https://github.com/apache/tomcat-jakartaee-migration[Apache migration tool] for the package name conversion. - -When applied to a project, they'll convert Java class imports, manifests, property files, and other resources to use `jakarta.*` namespace when needed. Conversion instructions are in each tool's [filename]`README` file. - -The last versions of IntelliJ IDEA offer https://www.jetbrains.com/help/idea/2022.2/migrate.html[migration refactoring] tools, including a Java EE to Jakarta EE package converter. Make sure that the Jakarta specifications in your project have the correct versions. Refer to the full list of https://jakarta.ee/release/10/[Jakarta EE 10 specifications] for more information. - -Below are a few examples: +Java 21 or later is required. Below is an example of how to use this version: -.pom.xml +[.example] +-- [source,xml] ---- - - jakarta.servlet - jakarta.servlet-api - 6.0.0 - - - jakarta.annotation - jakarta.annotation-api - 2.1.0 - - - jakarta.enterprise - jakarta.enterprise.cdi-api - 4.0.0 - - - jakarta.enterprise.concurrent - jakarta.enterprise.concurrent-api - 3.0.0 - + + + 21 + + 21/maven.compiler.source> + 21 + ---- +[source,kotlin] +---- + +plugins { + java +} +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} +---- +[source,groovy] +---- + +plugins { + id 'java' +} -== Spring Upgrade Instructions - -Spring Boot 3 and Spring Framework 6 don't fundamentally change how applications are developed. The main changes are regarding Jakarta EE 10 namespaces and supported products, the Java version, and the dependency upgrades and deprecations. +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} +---- +-- -Spring Boot 3 and Framework 6 use new versions of third-party dependencies: Hibernate 6, Hibernate Validator 8, servlet containers (e.g., Jetty 11, Tomcat 10.1), and many others. Spring has available the https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide[Dedicated Migration Guide for Spring-boot 3.0] and the https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x[Upgrading to Spring Framework 6.x Guide]. You may want to consult them. +== Spring Upgrade Instructions -To browse a full list of changes, see the https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes[Spring-boot 3.0 Release Notes] and the https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-6.x[What's New in Spring Framework 6.x] page. +To browse a full list of changes, see the link:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0.0-M3-Release-Notes[Spring Boot 4.0 Release Notes] and the https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-7.0-Release-Notes[What's New in Spring Framework 7.x] page. The following sections provide a general overview of the changes needed for Spring-based Vaadin applications. - === Upgrade Spring to Latest You'll need to upgrade Spring to the latest versions, including the starter parent dependency: @@ -136,21 +148,80 @@ You'll need to upgrade Spring to the latest versions, including the starter pare org.springframework.boot spring-boot-starter-parent - 3.0.0 + 4.0.0 ---- +== Application Servers -=== Deprecation +Before migrating, find the corresponding version of the Jakarta EE 11-compatible application server used in your project. See link:https://jakarta.ee/compatibility/[Jakarta Compatible Products] for more information. -The deprecated `VaadinWebSecurityConfigurerAdapter` class was removed since Spring no longer includes the `WebSecurityConfigurerAdapter` class. Use instead the `VaadinSecurityConfigurer` class or [deprecated:com.vaadin:vaadin@V24.9]#`VaadinWebSecurity` base class# for your security configuration. Below is an example of this: +== Maven & Gradle Plugins -[.example] --- +Ensure that the Maven plugins which are explicitly defined in your project, are compatible with Java 21. +A safe choice: Maven 3.9.11 (or the latest in the 3.9 line) or Maven 4.0.x (once stable) if you are comfortable with that. + +To run Gradle on top of Java 21 and latest Spring Boot 4 versions, you'll need to use version 8.14 or later. See the link:https://docs.gradle.org/8.14/release-notes.html[Gradle release notes] for further details. If your project uses Spring Boot, upgrade the plugin `org.springframework.boot` to version 4.0.0. + +If you're using a Gradle wrapper, update it to version 8.14 by executing the following from the command line: + +[source,terminal] +---- +./gradlew wrapper --gradle-version 8.14 +---- + +For Java 21 compatibility, you may need to update the `sourceCompatibility` setting in your project's build file to version 21. Check your project's build file and make any necessary changes. + +== Quarkus + +Vaadin Quarkus extension is changed to build production package by default. No need for production profile with exclusions for development tools in Maven configurations because Vaadin Quarkus extension has build-in Vaadin plugin handling production packaging. + +To allow project to keep build configuration unchanged, Vaadin Quarkus extension has `vaadin.build.enabled` property to change the default behavior. Disable Vaadin plugin by adding `vaadin.build.enabled=false` in `application.properties` file to keep using profile based configuration. + +== Changes in Theming System + +Vaadin 25 simplifies the theme/styling system to bring it closer to normal/native web development, and minimizes Vaadin-specific peculiarities, while keeping migration from earlier versions as painless as possible. + +Below are the main highlights of the changes and more detailed instructions are described in link:https://github.com/vaadin/platform/issues/7453[Theming System Renewal]. + + +The special `frontend/themes` folder, and the `components` sub-folder for CSS shadow-DOM injection, is deprecated (but still supported). + +The [classname]`@Theme` annotation is deprecated. Instead, [classname]`StyleSheet` annotation to be used for loading one or more stylesheets from public static resources locations (e.g. `META-INF/resources/`), whereas [classname]`CssImport` loads one or more stylesheets from the `src/main/frontend/` folder and use mechanisms native to HTML, CSS, and React (e.g. `@import url("morestyles.css")` in CSS). + +`StyleSheet` annotation is now a recommended way to load Vaadin theme for the application — to be placed on the application class implementing [classname]`AppShellConfigurator`. Below are some examples of how to use it: [source,java] ---- - +// theme selection +@StyleSheet(Aura.STYLESHEET) // or Lumo.STYLESHEET +public class Application implements AppShellConfigurator {} + +// or loading custom styles and theme: + +@StyleSheet("styles.css") +public class Application implements AppShellConfigurator {} + +// then using @import in the src/main/resources/META-INF/resources/styles.css: + +@import 'aura/aura.css'; /* or 'lumo/lumo.css' */ +// your custom styles go here ... + +---- + +The [filename]`theme.json` configuration file is deprecated (but still supported). + +The `themeFor` parameter of the [classname]`@CssImport` annotation (for shadow-DOM injection) is deprecated (but still supported). + +The special [filename]`document.css` file (for loading styles into the document root in embedded components) is removed as no longer necessary. + +== Security Configuration Changes + +The deprecated [classname]`VaadinWebSecurity` class has been removed from Vaadin 25. Use instead the [classname]`VaadinSecurityConfigurer` base class for your security configuration. Below is an example of this: + +[source,java] +---- + @EnableWebSecurity @Configuration @Import(VaadinAwareSecurityContextHolderStrategyConfiguration.class) @@ -215,786 +286,188 @@ public class SecurityConfig { } ---- -[source,java] ----- - -@EnableWebSecurity -@Configuration -public class SecurityConfig extends VaadinWebSecurity { +==== Upgrade To VaadinSecurityConfigurer From VaadinWebSecurity - @Override - public void configure(HttpSecurity http) throws Exception { - /** - * Delegating the responsibility of general configuration - * of HTTP security to the superclass. - * - * It's configuring the following: - * - Vaadin's CSRF protection by ignoring internal framework requests, - * - default request cache, - * - ignoring public views annotated with @AnonymousAllowed, - * - restricting access to other views/endpoints, and - * - enabling ViewAccessChecker authorization. - */ +. Add a new method to the security configuration class to provide the security filter chain bean - // You can add any possible extra configurations of your own - // here - the following is just an example: - http.rememberMe().alwaysRemember(false); - - // Configure your static resources with public access before calling - // super.configure(HttpSecurity) as it adds final anyRequest matcher - http.authorizeHttpRequests(auth -> { - auth.requestMatchers(new AntPathRequestMatcher("/admin-only/**")) - .hasAnyRole("admin") - .requestMatchers(new AntPathRequestMatcher("/public/**")) - .permitAll(); - }); - super.configure(http); - - // This is important to register your login view to the - // view access checker mechanism: - setLoginView(http, LoginView.class); - } - - @Override - public void configure(WebSecurity web) throws Exception { - // Customize your WebSecurity configuration. - super.configure(web); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - - /** - * Demo UserDetailsManager which only provides two hardcoded - * in-memory users and their roles. - * This shouldn't be used in real-world applications. - */ - @Bean - public UserDetailsService userDetailsService( - PasswordEncoder passwordEncoder) { - InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser(User.withUsername("user") - .password(passwordEncoder.encode("userPass")) - .roles("USER").build()); - manager.createUser(User.withUsername("admin") - .password(passwordEncoder.encode("adminPass")) - .roles("USER", "ADMIN").build()); - return manager; - } -} ----- - --- -In the example here, `AuthenticationManagerBuilder` -- used in Spring Boot 2 -- is replaced by `UserDetailsService`. Also, `http.authorizeRequests().antMatchers()` is replaced with `http.authorizeHttpRequests(auth -> auth.requestMatchers())`. - - -=== Spring Security - -If the application is using Spring Security 5, the default behavior is for the `SecurityContext` to be saved automatically to the `SecurityContextRepository` using the `SecurityContextPersistenceFilter`. - -In Spring Security 6, users now must explicitly save the `SecurityContext` to the `SecurityContextRepository`. - -You can return the old behavior by adding to [methodname]`SecurityFilterChain securityFilterChain(HttpSecurity http)` (or [methodname]`configure(HttpSecurity http)` with `VaadinWebSecurity`) the line `http.securityContext ( (securityContext) -> securityContext.requireExplicitSave( false ) );`. - -For more information see https://docs.spring.io/spring-security/reference/5.8/migration/servlet/session-management.html#_require_explicit_saving_of_securitycontextrepository[Servlet Migrations - Session Management]. - - -== Java Version - -Java 17 or later is required. Below is an example of how to use this version: - -[.example] --- -[source,xml] ----- - - - 17 - - 17 - 17 - ----- -[source,kotlin] ++ +[source,java] ---- - -plugins { - java -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(17) - } +@Bean +public SecurityFilterChain vaadinSecurityFilterChain(HttpSecurity http) throws Exception { + return http.with(VaadinSecurityConfigurer.vaadin(), vaadin -> { + ... + }).build(); } ---- -[source,groovy] ----- - -plugins { - id 'java' -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(17) - } -} ----- --- - - -== Application Servers - -Before migrating, find the corresponding version of the Jakarta EE 10-compatible application server used in your project. See https://jakarta.ee/compatibility/[Jakarta Compatible Products] for more information. - -CDI 4.0 specification -- which is part of Jakarta EE 10 -- changes the default value of the `bean-discovery-mode` attribute to `annotated` and uses `annotated` as the default when an empty [filename]`beans.xml` file is found in a deployment. See https://jakarta.ee/specifications/cdi/4.0/[Jakarta CDI page] for more information. - -To let the container scan and manage Vaadin components and views when the `bean-discovery-mode` attribute is not defined and the default is used, you should annotate Vaadin components and views with the `com.vaadin.cdi.annotation.CdiComponent` to allow them to be detected correctly as CDI beans. - -As an alternative, you can set `bean-discovery-mode=all` in the [filename]`beans.xml` file if it's applicable to your project. However, this isn't recommended. - - -[role="since:com.vaadin:vaadin@V24.4"] -== Frontend Sources Directory -Vaadin uses the [filename]`{project directory}/src/main/frontend/` directory as the default location for frontend sources. The legacy location [filename]`{project directory}/frontend/` is still supported and used if the [filename]`{project directory}/src/main/frontend/` directory doesn't exist. - -Although it's currently optional, if you're using the legacy location, you should move your files to a new location, as support for this may be removed in the future releases. - - -[role="since:com.vaadin:vaadin@V24.4"] -== Unification with Hilla & Integration with React - -Vaadin 24.4 and later versions unify the server and client development approaches known as Vaadin Flow and Hilla, respectively. This makes it easier to create hybrid applications, including: - -- unify dependencies for the Vaadin, making the project configuration simpler; -- develop https://reactjs.org/[React]-based routes and components in Vaadin Flow applications; -- export Flow components or entire views into frontend views implemented with React; and -- use unified routing based on https://reactrouter.com/en/main[React Router]. - - -=== Hilla & React Dependencies - -Vaadin 24 includes React dependencies, such as https://www.npmjs.com/package/react[React], https://www.npmjs.com/package/react-router[React Router], and https://github.com/vaadin/react-components[Vaadin React-based components] provided by Vaadin. These dependencies allow you to start developing immediately with React. - -Vaadin React includes free, core components and commercial (i.e., professional) components. These components are shipped in the separate npm packages: `@vaadin/react-components`, which is only free; and `@vaadin/react-components-pro`, which is only commercial. Vaadin adds both of these packages to [filename]`package.json` if the `com.vaadin:vaadin` artifact is in the project's configuration: - -[source,xml] -.pom.xml ----- - - com.vaadin - vaadin - ----- - -It adds only `@vaadin/react-components` if `com.vaadin:vaadin-core` is used: - -[source,xml] -.pom.xml ----- - - com.vaadin - vaadin-core - ----- - -Vaadin Flow applications don't need any changes regarding React or Hilla dependencies management. However, the opt-out options are available for the following cases: - -- Lit is used for frontend development instead of React; -- having Hilla or React dependencies is undesirable; and -- you need the legacy `vaadin-router` (e.g. if your project uses an add-on that needs it). - - -==== Opting-Out of React - -To opt-out, change both `reactEnable` plugin configuration parameter and `vaadin.react.enable` configuration property to `false`. - -Maven plugin configuration parameter in the `vaadin-maven-plugin`: - -[source,xml] -.pom.xml ----- - - com.vaadin - vaadin-maven-plugin - - false - - ----- - -Below is the configuration property with Spring Boot application properties: - -[source,terminal] -.application.properties ----- -vaadin.react.enable=false ----- - -Disabling it excludes React completely from your project and fallbacks to `vaadin-router` and Lit. - - -===== Two Places for Same Property - -Two properties exists mainly to support the development and production modes. `reactEnable` is effective for both; `vaadin.react.enable`, though, is effective only for development. - -Production package and bundle is built by running the Vaadin Maven and Gradle plugin with `build-frontend` goal. The `reactEnable` plugin configuration parameter value is contained in the build information file inside the package, which is used as a default value in runtime. - -Configuration property `vaadin.react.enable` overrides the default value in the production package at runtime. However, it doesn't change the production bundle content. - -Running an application with the `vaadin.react.enable` in production mode means possibly using a different value than what was used when the production package was built. Both properties should have the same value to avoid confusion as to which is effective. - - -===== Opting-Out of React with Spring - -System property has priority over application property. When running a Spring application with Maven, you may need to wrap system property in `-Dspring-boot.run.jvmArguments=vaadin.react.enable=false"`. - - -====== Simplified Maintenance - -To make it easier to keep both properties the same, Spring supports https://docs.spring.io/spring-boot/how-to/properties-and-configuration.html#howto.properties-and-configuration.expand-properties.maven[Automatic Property Expansion with Maven] and https://docs.spring.io/spring-boot/how-to/properties-and-configuration.html#howto.properties-and-configuration.expand-properties.gradle[with Gradle]. Please follow the instructions in the Spring documentation to enable this feature. - -When running with Maven and using `spring-boot-starter-parent`, property value can have `@reactEnable@`, which is replaced with the value of the `reactEnable` Maven project property. Otherwise, please follow the https://docs.spring.io/spring-boot/how-to/properties-and-configuration.html#howto.properties-and-configuration.expand-properties.maven[Spring documentation] to see how to enable `resources` filtering and set `maven-resources-plugin` configurations. - -[source,terminal] -.application.properties ----- -vaadin.react.enable=@reactEnable@ ----- - -[source,xml] -.pom.xml -- project properties ----- - - false - ----- -[source,xml] -.pom.xml -- build configuration ----- - - com.vaadin - vaadin-maven-plugin - - ${reactEnable} - - ----- - - -===== Opting-Out of React without Spring - -When Spring is not used, set `vaadin.react.enable` <<../flow/configuration/properties#system-properties, system property>> or `react.enable` <<../flow/configuration/properties#servlet-initialization-parameters, initialization parameter>>. - ++ -==== Opting-Out of React Components +**Hint**: you can use a static import for `VaadinSecurityConfigurer.vaadin()`. -If you don't need Vaadin's https://github.com/vaadin/react-components[React components], you can opt-out by excluding the `flow-react` package in your dependencies. This replaces the `@vaadin/react-components` and `@vaadin/react-components-pro` packages in your [filename]`package.json` with `@vaadin/*` web components: +. Move and adapt the code of the `configure(HttpSecurity)` method into `vaadinSecurityFilterChain()`. +.. customizations of [classname]`HttpSecurity` placed before `super.configure()` can be moved before the `with(vaadin(), vaadin -> {})` instruction. +.. calls to [classname]`VaadinWebSecurity` methods have related methods in the [classname]`VaadinSecurityConfigurer`. -[.example] ++ -- -[source,xml] ----- - - - com.vaadin - vaadin - - - com.vaadin - flow-react - - - ----- -[source,groovy] +.Before +[source,java] ---- - -dependencies { - implementation ("com.vaadin:vaadin") { - exclude group: 'com.vaadin', module: 'flow-react' - } +@Override +protected void configure(HttpSecurity http) throws Exception { + http.authorizeHttpRequests(registry -> { + registry.requestMatchers("/assets/**").permitAll(); + }); + super.configure(http); + setLoginView(http, "/login", "/"); } ---- --- -This example exclude Hilla from a project when using Maven: -.pom.xml -[source,xml] ----- - - com.vaadin - vaadin - - - com.vaadin - hilla - - - com.vaadin - hilla-dev - - - ----- - -This example is for when you're using Gradle: - -.build.gradle -[source,groovy] +.After +[source,java] ---- -buildscript { - configurations.classpath { - exclude group: 'com.vaadin', module: 'hilla-engine-core' - } +@Bean +public SecurityFilterChain vaadinSecurityFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests(registry -> { + registry.requestMatchers("/assets/**").permitAll(); + }); + http.with(vaadin(), vaadin -> vaadin.loginView("/login", "/")); + return http.build(); } - -dependencies { - implementation ("com.vaadin:vaadin") { - exclude group: 'com.vaadin', module: 'hilla-dev' - } -} ----- - -.gradle.properties -[source,properties] ---- - -hilla.active=false ----- - -The following Hilla dependencies are included in Vaadin. You don't need to include these explicitly: - -- `dev.hilla:hilla-bom` -- `dev.hilla:hilla-react` -- `dev.hilla:hilla` - - -=== Frontend Bundles & Hot Deploy Modes - -Vaadin chooses using a pre-compiled frontend bundle, or re-building a new bundle, or starting a frontend development server. If it detects Hilla views in a project, it uses development server -- unless you set the configuration parameter, `vaadin.frontend.hotdeploy=false`. Conversely, for Flow applications it uses frontend bundle -- unless you set the configuration parameter, `vaadin.frontend.hotdeploy=true`. - - -=== Default Location for Client-Side Views - -Place your React client-side views in the [filename]`src/main/frontend/views/` directory. Vaadin searches for any [filename]`.tsx` or [filename]`.jsx` React views. It registers them as React routes if they're present in this directory or subdirectories. See <<{articles}/hilla/guides/routing#,Routing >> for more details about File-Based Routing. - - -== Polymer Templates - -Polymer support has been deprecated since Vaadin 18 was released in November 2020, in favor of faster and simpler <<{articles}/flow/create-ui/templates#,Lit templates>>. The built-in support for Polymer templates has been removed and is only available for Prime and Ultimate customers via an addon. However, a free conversion tool is also available to assist you in converting your Polymer templates to Lit. - - -=== Commercial Polymer Template Addon - -If you have a Prime or Ultimate subscription, you can continue to use Polymer templates by adding the following dependency to your [filename]`pom.xml` file: - -.pom.xml -[source,xml] ----- - - com.vaadin - flow-polymer-template - ----- - -Then you'll need to update all imports of the `PolymerTemplate` classes to the new coordinates: `com.vaadin.flow.component.polymertemplate.PolymerTemplate`. - -==== Limitations - -Even with the PolymerTemplate Addon, you cannot use the Polymer-based TemplateRenderer; instead <<{articles}/components/grid/renderers#using-lit-renderers#,LitRenderer>> is required. Additionally, if the Polymer template relies on Vaadin component imports and APIs, these may need to be updated. - -=== Polymer to Lit Conversion Tool - -You can use the free conversion tool to facilitate the migration from Polymer to Lit by converting automatically basic Polymer constructions into their Lit equivalents in Java and JavaScript source files. - - -==== Limitations - -The converter covers only basic cases. More advanced cases, such as TypeScript source files or usage of internal Polymer API, should still be converted manually. - -See the https://github.com/vaadin/flow/tree/master/flow-polymer2lit[Polymer-to-Lit converter documentation] for more information about limitations and supported transformations. - +-- -==== Usage +. If `configure(WebSecurity web)` is overridden you might: -Regarding usage, run the converter in your project's root folder as follows: +.. Move the rules in the security filter chain bean definition using `HttpSecurity.authorizeRequests()` and remove the original method (recommended by Spring, to prevent skipping all other filters in the chain): -[.example] ++ -- -[source,terminal] ----- - -mvn vaadin:convert-polymer ----- -[source,groovy] +.Before +[source,java] ---- - -./gradlew vaadinConvertPolymer +@Override +protected void configure(WebSecurity web) throws Exception { + web.ignoring().requestMatchers("/images/**"); +} ---- --- - -To convert a project that is based on versions before Vaadin 24, use the following: -[.example] --- -[source,terminal,subs="+attributes"] ----- - -mvn com.vaadin:vaadin-maven-plugin:{vaadin-version}:convert-polymer ----- -.`build.gradle` -[source,groovy,subs="+attributes"] +.After +[source,java] ---- - -buildscript { - repositories { - classpath 'com.vaadin:flow-gradle-plugin:{vaadin-version}' - } +@Bean +public SecurityFilterChain vaadinSecurityFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests(registry -> { + registry.requestMatchers("/assets/**", "/images/**").permitAll(); + }); + http.with(vaadin(), vaadin -> vaadin.loginView("/login", "/")); + return http.build(); } ---- -- +.. OR, expose a [classname]`WebSecurityCustomizer` bean by your own and remove the original method -==== Configuring - -The converter needs to be configured. It accepts the following properties: - -`-Dvaadin.path=path/to/your/file`:: -By default, the converter scans all files that match `/.js` and `/.java` and then tries to convert them to Lit. -+ -To limit conversion to a specific file or directory, you can use the `vaadin.path` property like so: + -[.example] -- -[source,terminal] ----- - -mvn vaadin:convert-polymer -Dvaadin.path=path/to/your/file ----- -[source,terminal] +.Before +[source,java] ---- - -./gradlew vaadinConvertPolymer -Dvaadin.path=path/to/your/file +@Override +protected void configure(WebSecurity web) throws Exception { +web.ignoring().requestMatchers("/images/**"); +} ---- --- -+ -The path is always relative to your project's root folder. -`-Dvaadin.useLit1`:: -By default, the converter transforms Polymer imports into their Lit 2 equivalents. -+ -If your project is using Lit 1 (i.e., before Vaadin 21), you can use the vaadin.useLit1 flag to enforce Lit 1 compatible imports: -+ -[.example] --- -[source,terminal] ----- - -mvn vaadin:convert-polymer -Dvaadin.useLit1 ----- -[source,terminal] +.After +[source,java] ---- - -./gradlew vaadinConvertPolymer -Dvaadin.useLit1 +@Bean +public WebSecurityCustomizer webSecurityCustomizer() { +return (web) -> web.ignoring().requestMatchers("/images/**"); +} ---- -- -`-Dvaadin.disableOptionalChaining`:: -By default, the converter transforms `\[[prop.sub.something]]` expressions into `${this.prop?.sub?.something}`. -+ -If your project is using the Vaadin webpack configuration, which doesn't support the JavaScript optional chaining operator `(?.)`, you can use the `vaadin.disableOptionalChaining` flag like so: +. If stateless authentication is configured (`setStatelessAuthentication(...)`), replace the call using `VaadinStatelessSecurityConfigurer` + + -[.example] -- -[source,terminal] ----- - -mvn vaadin:convert-polymer -Dvaadin.disableOptionalChaining ----- -[source,terminal] ----- - -./gradlew vaadinConvertPolymer -Dvaadin.disableOptionalChaining ----- --- - - -== Multiplatform Runtime - -Multiplatform Runtime allows the use of legacy Vaadin 7 or 8 framework components in Vaadin Flow applications. The Multiplatform Runtime artifacts remain the same: `mpr-v8` and `mpr-v7`. However, the framework server dependencies now contain an `mpr-jakarta` postfix: - -.pom.xml -[source,xml] +.Before +[source,java] ---- - - - com.vaadin - vaadin-server-mpr-jakarta - 8.19.0 - - - - com.vaadin - vaadin-compatibility-server-mpr-jakarta - 8.19.0 - - - - - com.vaadin - vaadin-server-mpr-jakarta - 7.7.37 - +@Override +protected void configure(HttpSecurity web) throws Exception { + //... + setStatelessAuthentication(http, new SecretKeySpec(Base64.getDecoder().decode(authSecret), JwsAlgorithms.HS256), "com.example.application"); + //... +} ---- -Other legacy framework dependencies have the same names, but transitive dependencies to `vaadin-server` artifacts must be detected and excluded. Consult <<{articles}/tools/mpr/introduction/1-maven-v8#exclude-incompatible-framework-8-dependency, Exclude Incompatible Framework 8 Dependency>> for further details. - - -== Maven & Gradle Plugins - -Ensure that the Maven plugins which are explicitly defined in your project, are compatible with Java 17. For example, the `nexus-staging-maven-plugin` requires a minimum version of 1.6.13. Maven version 3.5 and later support Java 17, but avoid using 3.8.2 or 3.8.3. They break any redeploy in Jetty. - -To run Gradle on top of Java 17 and latest Spring Boot 3 versions, you'll need to use version 8.4 or later. See the https://docs.gradle.org/8.6/release-notes.html[Gradle release notes] for further details. If your project uses Spring Boot, upgrade the plugin `org.springframework.boot` to version 3.2.x. - -If you're using a Gradle wrapper, update it to version 8.6 by executing the following from the command line: - -[source,terminal] +.After +[source,java] ---- -./gradlew wrapper --gradle-version 8.6 +@Bean +public SecurityFilterChain vaadinSecurityFilterChain(HttpSecurity http) throws Exception { + //... + http.with(new VaadinStatelessSecurityConfigurer<>(), stateless -> stateless.issuer("com.example.application") + .withSecretKey() + .secretKey(new SecretKeySpec(Base64.getDecoder().decode(authSecret), JwsAlgorithms.HS256)) + ); + //... +} ---- +-- -For Java 17 compatibility, you may need to update the `sourceCompatibility` setting in your project's build file to version 17. Check your project's build file and make any necessary changes. - - -== SLF4J 2.0 - -Vaadin 24 and Spring-boot 3 use SLF4J library version 2.0, which has breaking changes compared to earlier versions. See the https://www.slf4j.org/news.html[SLF4J release notes] for more information. - - -== Line-Awesome Icons Set Library - -Vaadin 23 starter projects used the https://icons8.com/line-awesome[Line Awesome] icon set. If you need those icons, you should use the https://vaadin.com/directory/component/line-awesome-icons-for-vaadin[Line Awesome add-on] with Vaadin 24. This add-on doesn't require building a new bundle, which means your application will benefit from the pre-compiled frontend bundle feature. - - -== New Types Definition - -Vaadin might ask you to add new types definitions to the [filename]`types.d.ts` file, if it detects customized content in it. If so, the first build after the upgrade will fail, and show instructions on how to correct it in the server logs. - - -== Breaking Changes in Vaadin Components - -Vaadin components have several breaking changes related to upgrading to the latest version. These are covered in the sections that follow. - - -=== Shrinking Badges - -Badges no longer shrink by default. This can be overridden globally with CSS `[theme~="badge"] { flex-shrink:1; }`, or for specific instances with `badge.getStyle().set("flex-shrink", "1")`, or with `layout.setFlexShrink(badge, 1)`. - -=== Shrinking Buttons - -Buttons also no longer shrink by default. This also can be overridden globally, but with CSS `vaadin-button { flex-shrink:1; }`, or for specific instances with `btn.getStyle().set("flex-shrink", "1")` or with `layout.setFlexShrink(btn, 1)`. - - -=== CheckboxGroup -The `CheckboxGroup::setItemLabelGenerator` no longer clears the current selection. The `CheckboxGroup.clear()` can be used to clear values, separately. - - -=== BlurNotifier - -The `BlurNotifier` type signature was corrected to `BlurNotifier>`. - - -=== Date Picker - -Date Picker now uses the ISO 8601 date format (i.e., `yyyy-mm-dd`) as fallback for unsupported locales -- instead of `mm-dd-yyyy`. Time Picker no longer adjusts automatically values to fit minimum and maximum constraints. - - -=== Number Field - -Number Field's default width now matches that of other text input components. The old default can be brought back with CSS `vaadin-number-field { width:8em; }`. - - -=== RichTextEditor - -`RichTextEditor::setValue` and `getValue` now use HTML format by default, instead of Delta. Applications using the Delta format must be refactored to use the `RichTextEditor.asDelta()` API (e.g., `rte.asDelta().getValue()` and `binder.forField(rte.asDelta())`). - -To help avoid using the wrong setter, `RichTextEditor.setValue(String)` now throws an exception if the value looks like it's in Delta format (i.e., it starts with a `[` or `{` bracket). To set an HTML value starting with the above characters, either wrap the value in an HTML tag, or use the `RichTextEditor.asHtml()` API, which doesn't check for them. - - -=== Margins for Headings - -The default top and bottom margins of the `H1`...`H6` HTML elements have been removed. This change can be reverted by applying the following CSS: +. Remove `extends VaadinWebSecurity` and import the Vaadin security context holder strategy -.styles.css -[source,css] +[source,java] ---- -h1,h2,h3,h4,h5,h6 { margin-top: 1.25em; } -h1 { margin-bottom: 0.75em; } -h2, h3, h4 { margin-bottom: 0.5em; } -h5 { margin-bottom: 0.25em; } +@EnableWebSecurity // should be already present +@Configuration // should be already present +@Import(VaadinAwareSecurityContextHolderStrategyConfiguration.class) +public class SecurityConfiguration { +} ---- -=== Removed Flow Component APIs - -.View Removed or Renamed Flow APIs -[%collapsible] -==== -The following Vaadin component APIs have been removed or renamed in Flow: - -- The `Generated[ComponentName]` classes have been removed. Extend the normal component classes instead when extending components. -+ -The following event classes were introduced in V23.3 as replacements for the ones in the generated classes: `DatePicker.OpenedChangeEvent`; `DatePicker.InvalidChangeEvent`; `Dialog.OpenedChangeEvent`; `Notification.OpenedChangeEvent`; and `SplitLayout.SplitterDragendEvent`. -+ -The generic type parameters in these events -- introduced in V23.3 for backward compatibility -- was removed in V24. -- `Button.setDisabled()` was removed in favor of `setEnabled(false)`. -- Charts `HTMLLabels` and `HTMLLabelItem` APIs were removed -- they were broken -- in favor of `Configuration.addLabel` or `Configuration.setLabels` with `AnnotationItemLabel` objects instead of `HTMLLabel`. Coordinate information for the label can be provided using `AnnotationItemLabel.setPoint`. -- `Checkbox::setLabelAsHtml` was removed in favor of renderers (i.e., `setRenderer`). -- `CheckboxGroup` and `RadioButtonGroup` no longer implement the `HasComponents` and `HasItemComponents` interfaces and the following related methods have been removed: - -- `add(Component...)`, `add(Collection)`, and `add(String)`; - -- `remove(Component...)`, `remove(Collection)`, and `removeAll()`; - -- `addComponentAtIndex(int, Component)`; - -- `addComponentAsFirst(Component)`; - -- `addComponents(T, Component...)`; - -- `prependComponents(T, Component...)`; and - -- `getItemPosition(T)`. -- `ContextMenu` `clickListener` API was removed -- it wasn't working. Apply instead click listeners to the menu's target component if needed. -- `CustomFieldI81n::parseValue` and `CustomFieldI18n::formatValue` were moved to `CustomField::parseValue` and `CustomField::formatValue`. -- `DatePickerI18n` setters and getters for `clear`, `.calendar`, and `.week` were removed since it was unused. -- `FlexLayout.getFlexDirection(HasElement elementContainer)` overload was removed -- it was pointless -- in favor of `getFlexDirection()`. -- `Grid::setHeightByRows` was removed in favor of `Grid::setAllRowsVisible`. -- `Grid.addColumn(renderer, sortingProperties)` was removed in favor of `addColumn(renderer).setSortProperty(sortingProperties)`. -- `Grid.ItemClickEvent` and `ItemDoubleClickEvent` without `columnId` were removed. -- `Grid::findInShadowRoot` was removed. -- `Grid::setVerticalScrollingEnabled` was removed: it wasn't working. -- `Map.Coordinate::fromLonLat` was removed as unnecessary since the default coordinate system is now EPSG:4326, and `new Coordinate(x,y)` is sufficient. -- `Map` APIs that used `float` values now use `double`. -- `NumberField::setMaxLength`, `setPattern`, and `setPreventInvalidInput` were removed because they didn't work. -- `NumberField::setHasControls` was renamed `setStepButtonsVisible`. -- `RichTextEditor(String value)` constructor was removed in favor of `RichTextEditor()`, followed by `setValue(String value)`. -- `Select(T... items)` constructor was removed in favor of `Select(String label, T... items)`. -- `SplitLayout.IronResizeEvent` was removed as part of a migration away from Polymer. -- `Tabs` no longer implements the `HasComponents` interface, with the following APIs removed or deprecated: - -- `add(Collection)` was removed in favor of `add(Tab...)`; - -- `remove(Collection)` was removed in favor of `remove(Tab...)`; - -- `add(String)` was removed; - -- `indexOf(Component)` was deprecated in favor of `indexOf(Tab)`; - -- `add(Component)` was deprecated in favor of `add(Tab)`; - -- `remove(Component)` was deprecated in favor of `remove(Tab)`; - -- `replace(Component, Component)` was deprecated in favor of `replace(Tab, Tab)`; - -- `getComponentAt(int)` was deprecated in favor of `getTabAt(int)`; - -- `addComponentAtIndex(int, Component)` was deprecated in favor of `addTabAtIndex(int, Tab)`; and - -- `addComponentAsFirst(Component)` was deprecated in favor of `addTabAsFirst(Tab)`. -- `TemplateRenderer` public API was removed in favor of `LitRenderer`. -- `TextField::setPreventInvalidInput` was removed in favor of `setAllowedCharPattern`. -- `TimePicker.setMin(String)` and `setMax(String)` were removed in favor of `setMin(LocalTime)` and `setMax(LocalTime)`. -- Upload `SelectedChangeEvent(Tabs source, boolean fromClient)` overload was removed in favor of `SelectedChangeEvent(Tabs source, Tab previousTab, boolean fromClient)`. -- `UploadI18n::setCancel` and `UploadI18n::getCancel` were removed since they were unused. - -==== - - -=== Web Component APIs - -.Click and read if using Vaadin Components without Flow. -[%collapsible] -==== -The following changes only affect the client-side APIs of Vaadin components: +==== Restrict Access By Default For Url-Based Security +URLs not explicitly specified in security configuration changed from being allowed for authenticated users to restricted by default. This requires extra security rules (path matchers) for URLs that were allowed only for authentication users. -- The label on `vaadin-checkbox` and `vaadin-radio-button` must be set using the `label` property, as the default slot has been removed. -- `vaadin-confirm-dialog.cancel` and `.reject` properties were renamed `.cancelButtonVisible` and `.rejectButtonVisible`. -- `vaadin-number-field` property `has-controls` was renamed `step-buttons-visible`. -- Deprecated `@vaadin/vaadin-xxx` (e.g., `@vaadin/vaadin-grid`) npm packages have been removed. Use instead the new `@vaadin/xxx` (e.g., `@vaadin/grid`). -- Deprecated `xxxElement` legacy class aliases (e.g., `GridElement`) have been removed. Use the plain component classes instead (e.g., `Grid`). -- Deprecated misspelled `vaadin-icons` were removed: `buss`, `funcion`, `megafone`, `palete`, and `trendind-down`. -- `notifyResize` and `updateStyles` methods were removed from various components as obsolete. -- `preventInvalidInput` in text input fields was removed in favor of `setAllowedCharPattern`. -- The read-only `theme` _property_ was removed. Use instead the `theme` _attribute_. +==== Deny Access If Flow Layout Has No Security Annotation +Vaadin Flow layouts now require access annotation (e.g. [classname]`RolesAllowed`) on layout classes. This was added to align with auto-layout default security rules. -==== +== TestBench +[classname]`ComponentTester` in UI Unit test has been updated to prove a common [methodname]`void click()` method. However, the new method clashes with a similar existing method in [classname]`AnchorTester` and [classname]`RouterLinkTester` that returns an [classname]`HasElement` instance as a result of the navigation. Existing tests that rely on the return type have to migrate to the new [methodname]`navigate()` method; if the return value is not used, there is no need for changes. -=== Update Your Component Styling +Because of the change, the [classname]`com.vaadin.flow.component.html.testbench.ClickHandler` class has been removed. The interface, meant to be used with [classname]`ComponentTester` subclasses, should not be needed anymore. In this case, [classname]`com.vaadin.testbench.unit.Clickable` is a valid substitute. -.Click and read if styled Vaadin Components. -[%collapsible] -==== -include::_styling.adoc[] -==== +== Binder +[methodname]`Binder.validate()` implementation has been changed to behave as its Javadoc states. In other words, [methodname]`Binder.validate()` no longer fails when bean level validators have been configured but no bean is currently set (i.e. [classname]`Binder` is used in buffered mode). +== Server-Side Modality +[classname]`Dialog` has become less strict and allows background requests to server. Vaadin Flow allows to change this behavior if needed through [methodname]`Dialog.setModality(ModalityMode)` method. -== Field Validation Changes +== Tree Grid And Hierarchical Data Providers +Vaadin Flow added support for flat hierarchy in [classname]`TreeGrid` and hierarchical data providers. +This required some API removal in Vaadin Flow. -Vaadin 24 introduced several major changes in field component validation, addressing various issues and UX inconsistencies that have been reported in previous versions. These are listed and described in the sections that follow. +[classname]`HierarchyMapper` and [classname]`HierarchicalCommunicationController` have been replaced with the new concept - `Cache`. This new class provides a system for storing data in a hierarchical structure while enabling access in a flattened format for client-side consumption. [methodname]`setRequestedRange` and [methodname]`setParentRequestedRange` have been replaced with a single [methodname]`setViewportRange` which spans all hierarchy levels. +See link:https://github.com/vaadin/platform/issues/7843[Tree Grid Flat Hierarchy Support] and link:https://github.com/vaadin/flow-components/issues/7269[Improving user and developer experience in Tree Grid] for more details. -=== Binder Considers Component Constraints +== Form Filler Add-On +The link:https://github.com/vaadin/form-filler-addon[Form Filler add-on] has been removed from the Vaadin 25 platform. If your project uses it, you can add it as a separate dependency or get the same functionality with much less code using Spring AI to have the LLM directly populate a Java object that you can then use with e.g. [methodname]`binder.readBean()`. -Every field component provides its own set of constraints, such as `required`, `minlength`, `pattern`, etc. +== Polymer Support -*Before:* When using Binder, component constraints were ignored in earlier versions. They could still affect the client-side invalid state without reflecting this to the server. - -*After:* In the new version, component constraints are integrated into Binder validation. Binder checks the value against constraints before custom validators. The only exception is the required constraint. It doesn't participate in Binder validation since Binder provides its own `asRequired` validator. - -*Known Issues:* It's currently not possible to configure custom error messages for constraints (https://github.com/vaadin/flow-components/issues/4618[flow-components#4618]). - -Also, it's currently not possible to revert Binder's behavior to ignore constraints as before, except by removing the constraints from the component, entirely (https://github.com/vaadin/flow/issues/17178[flow#17178]). - - -=== Blur Triggers Server-Side Validation - -*Before:* Both constraint and Binder validation were previously only triggered on `ValueChangeEvent`, while client-side validation was completely disregarded. - -*After:* The server-side validation timing is now aligned with client-side validation, meaning that whenever the web component validation occurs, it triggers the corresponding validation in the Flow component. In practice, this means that the server-side validation also is performed on blur (i.e., when the component loses focus). - -*Known Issues:* The component validates on blur even when the user leaves it without typing anything. This behavior results from the web component, which validates on blur to detect possible bad input (https://github.com/vaadin/web-components/issues/6146[web-components#6146]). - -The server-side validation can be triggered more frequently than necessary. For example, if you edit a Text Field and then blur, both value-changed and blur events can fire at the same time, resulting in double validation in a single round-trip (https://github.com/vaadin/flow-components/issues/4390[flow-components#4390]). - - -=== Bad Input Invalidates Component - -Date Picker, Integer Field, and some other similar components only accept user input that can be parsed as a `LocalDate`, `Integer`, etc. Otherwise, the value on the server falls back to `null`. - -*Before:* Previously, entering bad input didn't invalidate the component because the server treated this case as an empty value. - -*After:* The server is now aware if the user has entered any input. When the input cannot be parsed, it's considered bad input, causing constraint validation to fail once the user presses Enter or removes focus from the component. - - -[role="since:com.vaadin:vaadin@V24.2"] -=== Manual Validation Mode - -There are applications that require a fully customized validation logic that is beyond the capabilities of validation tools provided by Vaadin. For such applications, Vaadin 24.2 introduces a manual validation mode. This mode disables the component's built-in validation, allowing developers to have manual control over the component's invalid state and error messages. - -Below is an example of a custom implementation of the required validation performed on `ValueChangeEvent`: - -[source,java] ----- -TextField textField = new TextField(); -textField.setManualValidation(true); -textField.addValueChangeListener(event -> { - if (Objects.equals(event.getValue(), "")) { - textField.setInvalid(true); - textField.setErrorMessage("The field is required."); - } else { - textField.setInvalid(false); - } -}); ----- +In Vaadin 25, the `@polymer/polymer` dependency in default `package.json` is removed by default, if polymer-template module is not found from the project. If the application uses Polymer in add-ons may require to add `@NpmPackage(value = "@polymer/polymer", version = "3.5.2")` or add an import to `package.json` explicitly. Details can be found in link:https://github.com/vaadin/flow/issues/21421[Ensure Flow works without Polymer in v25]. +== Frontend Sources Directory +Vaadin uses the [filename]`{project directory}/src/main/frontend/` directory as the default location for frontend sources. Legacy location [filename]`{project directory}/frontend/` is deprecated and a warning is shown if it's used. If you're using the legacy location, please move your files to the new location, or add the `frontendDirectory` parameter and point it to the legacy location. Legacy location support will be removed in a future release. == Removed Deprecations -APIs that were deprecated earlier have now been removed. The following linked GitHub issue lists these removals: - -- https://github.com/vaadin/flow/issues/15665[Remove deprecated API and tools in Flow 24.0] - -== Side Navigation Replaces AppNav and AppNavItem - -Some starter projects previously used the `AppNav` and `AppNavItem` components, which relied on the Vaadin Component Factory components, vcf-nav and vcf-nav-item. These Component Factory components are no longer supported and you should replace `AppNav` and `AppNavItem` with their successor, <>. - +APIs deprecated earlier have now been removed. The following linked GitHub issue lists these removals — link:https://github.com/vaadin/flow/issues/21396[Remove deprecated API in Flow 25.0].