DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

How are you handling the data revolution? We want your take on what's real, what's hype, and what's next in the world of data engineering.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

SBOMs are essential to circumventing software supply chain attacks, and they provide visibility into various software components.

Related

  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Mastering React App Configuration With Webpack
  • Overcoming React Development Hurdles: A Guide for Developers

Trending

  • Deploy Serverless Lambdas Confidently Using Canary
  • Vibe Coding: Conversational Software Development — Part 1 Introduction
  • *You* Can Shape Trend Reports: Join DZone's Data Engineering Research
  • Scrum Smarter, Not Louder: AI Prompts Every Developer Should Steal
  1. DZone
  2. Coding
  3. JavaScript
  4. How to Create a Custom React Component in Vaadin Flow

How to Create a Custom React Component in Vaadin Flow

Learn how to integrate custom React components (Plotly charts) into Vaadin Flow apps. Java backend sends data to a React frontend. React uses hooks to communicate.

By 
Mark Andreev user avatar
Mark Andreev
·
Jun. 06, 25 · Tutorial
Likes (0)
Comment
Save
Tweet
Share
2.0K Views

Join the DZone community and get the full member experience.

Join For Free

Vaadin Flow is a Java-based, backend-driven UI framework that is best suited for admin UIs, where the number of active users is predictable and bounded. Within this controlled context, the UI state can be managed on the backend, sharing only the necessary diffs with the user for rendering.

From a developer’s perspective, all UI configuration remains in Java code. There is no need to manually create separate REST endpoints, as the UI component state is managed directly within Java.

At some point, you may want to integrate custom UI components implemented as standalone libraries, such as charts that are not available in the free (open-source) version of Vaadin Flow. In this article, I would like to share my experience of creating a bridge between Vaadin and JavaScript code that uses React.

In this blog post, I will integrate Plotly, a popular data visualization tool in the Data Science community that is licensed under MIT. Our goal is to create a custom chart and pass data from the backend to render it in the UI.

Architecture

The Vaadin Flow React adapter consists of two parts: a Java component (which extends ReactAdapterComponent) and a React component written in TypeScript. 

From the React component's perspective, we use the useState hook provided by ReactAdapter from Vaadin Flow.

From the Java perspective, we treat ReactAdapterComponent as a proxy that follows the default communication flow of the setState method. All implementation details are abstracted by the Vaadin Flow framework.

Impl

Vaadin Flow utilizes Shadow DOM to encapsulate custom React components, ensuring style isolation and preventing conflicts with the rest of the application. When a React component is integrated using @JsModule and @Tag, it is rendered inside a custom element with Shadow DOM enabled, keeping its structure and styles separate from Vaadin’s global styles. 

Data binding between Java and the React component is managed via Element.setProperty() or ReactAdapterComponent, allowing seamless state synchronization. This approach ensures encapsulated styles, prevents unintended overrides, and maintains a modular UI architecture while enabling dynamic updates between Vaadin and React.

ChartComponent class

Custom Component

Java Component

The ChartComponent class is a Vaadin Flow component that integrates Plotly.js for interactive charting in a Java-based web application. It is annotated with @NpmPackage to ensure that the required JavaScript dependencies — react-plotly.js, plotly.js, and their TypeScript definitions — are included in the project. The @JsModule annotation links the component to a corresponding React-based implementation defined in chart-component.tsx, enabling seamless frontend integration. 

Extending ReactAdapterComponent, the class provides a way to manage chart data as a JSON structure, facilitating dynamic updates and integration with Vaadin's data-binding mechanisms.

Java
 
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.dependency.NpmPackage;
import com.vaadin.flow.component.react.ReactAdapterComponent;


@NpmPackage(value = "react-plotly.js", version = "2.6.0")
@NpmPackage(value = "plotly.js", version = "3.0.1")
@NpmPackage(value = "@types/react-plotly.js", version = "2.6.3")
@JsModule("./chart-component.tsx")
@Tag("chart-component")
public class ChartComponent extends ReactAdapterComponent {
    public void nextValue(ChartComponentValue value) {
        setState("value", value);
    }
}


public record ChartComponentValue(List<Data> data, Layout layout){
    public record Data(String type, List<Integer> x, List<Integer> y){}
    public record Layout(int width, int height, String title) {}
}


We specify ChartComponentValue as a data transfer object that will be serialised by Vaadin and used by Plotly for configuration.

ChartComponentValue

React Component

Create a new file “chart-component.tsx” in “src/main/frontend/.” With custom implementation of ReactAdapterElement:

TypeScript
 
import React from 'react';
import Plot from 'react-plotly.js';
import { ReactAdapterElement, RenderHooks } from 'Frontend/generated/flow/ReactAdapter';


class ChartComponent extends ReactAdapterElement {
   constructor() {
       super();
   }


   protected override render(hooks: RenderHooks): React.ReactElement | null {
       const [data, setData] = hooks.useState<any>('value');


       return (
           data && (
               <Plot
                   data={ data.data }
                   layout={ data.layout }
                   />
               )
       );
   }
}


customElements.define('chart-component', ChartComponent);


The ChartComponent class is a React-based web component that integrates Plotly.js for interactive chart rendering within a Vaadin Flow application. It extends ReactAdapterElement, which allows seamless communication between Vaadin's Java backend and React frontend. The component utilizes the render method, where it initializes a state variable data using hooks.useState, with an initial placeholder value 'value'. 

When valid data is available, it renders a Plot component from the react-plotly.js library, passing the data and layout properties dynamically. Finally, the component is registered as a custom element with the tag name 'chart-component', making it usable within the Vaadin application as a web component.

chart-component

Vaadin Flow

Disclaimer

Vaadin Flow uses different mechanisms for the dev and production builds of the React component. Remember to test your custom components on the production build, as some integration issues may only become visible during this phase. 

Also, if Node.js is present in your build environment, Vaadin will try to download and install it into your home directory (that might not exist in some CI Runners environments).

Conclusion

We've shown how Vaadin Flow’s React adapter can help you add JavaScript tools, like Plotly, to your Java apps. It's clear how the Java part (ReactAdapterComponent) and the TypeScript React part are kept separate. However, features like Shadow DOM, which are supposed to keep styles separate and safe, often create more headaches for developers. It can make styling and finding bugs harder, not easier, turning what seems helpful into a real challenge. Bringing these two different worlds, Java and JavaScript, together naturally adds some extra complexity compared to just using standard Vaadin. While this connection works, it definitely comes with its own set of difficulties.

Even with these tricky parts, it's good to remember what Vaadin Flow does really well: it lets developers build UIs, especially admin pages, quickly and efficiently, mostly using Java. Think of this React integration as a special tool to use when you really need a particular JavaScript library, not as the everyday way to do things. 

Always keep in mind the important warnings: test your custom components carefully in a production-like setup and pay attention to how Node.js behaves within your build systems. If you manage these extra complexities carefully, you will have more options to expand your Vaadin applications, but be prepared for the additional effort it may require.

Chart JavaScript Vaadin Flow (web browser) React (JavaScript library)

Opinions expressed by DZone contributors are their own.

Related

  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Mastering React App Configuration With Webpack
  • Overcoming React Development Hurdles: A Guide for Developers

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • [email protected]

Let's be friends: