Using Web Components in plain Java

Web Components is a major effort to solve an issue among JavaScript hackers that has been working well in the Java world for ages: modularization. Using four emerging standards, Custom Elements, Html Imports, Templates and Shadow DOM, one can finally package UI components in such a way that they don't mess up the host page and the host page doesn’t mess them with its styles, javascript namespace and more.

Web Components isn’t yet supported in all major browsers, but by leveraging the polymer project you can start using this emerging technology already today. Polymer is a "polyfill" to make Web Components work today, even if the browser doesn’t have full support available. It can't make them 100% compatible, e.g. some CSS might still leak from the host page, but for a selected audience, the technology is available already today.

Creating Vaadin wrappers for Web Components is pretty analogous to creating wrappers for JS components: easy. There are two approaches: with a GWT wrapper for the client side counterpart or with the "JS wrapper". Both approaches give you the same clean and efficient server side Java API. With the GWT wrapper you'll have a more fine grained control and can re-use the client side Java API in full client side apps or in offline mode for Vaadin TouchKit.

For simpler integrations you can choose the JS wrapper approach. Getting started with this approach is a bit faster as well. To demonstrate this I created a server side Java API for a Web Component presenting a chess board.

The JS integration has the following steps:

  • Inject Polymer and the possibly needed EC6 polyfill to your host page
  • Create a server side component extending AbstractJavaScriptComponent
  • Create a JS file that includes the client side integration
  • Implement the API you wish to use from the server side

There are multiple ways the Polymer injection can be done, and the best method probably depends on your deployment, but I decided to inject it by creating a BootstrapListener to modify the default host page. There we can just find the head element and inject the required scripts into the host page.

The full server side class for the ChessBoard looks like this:

public final class ChessBoard extends AbstractJavaScriptComponent {

    public ChessBoard(String boardState) {

    public ChessBoard() {
        this("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");

    public void move(String from, String to) {
        callFunction("move", from, to);

    public void setBoardState(String boardState) {
        callFunction("setBoardState", boardState);


The relevant parts are the @JavaScript annotation that injects the client side logic and the actual API methods: move and setBoardState. They just forward the parameters to the client side counterpart with similarly named functions. In case you wonder what is the cryptic string in the void constructor, that is the starting position expressed using Forsyth–Edwards Notation.

In the vaadinintegration.js the actual chess-board custom html tag aka Web Component is introduced. This is done with the link element like this:

var el =  document.createElement("link");
el.rel = "import";

The import of the Web Component could just as well be done in the BootstrapListener, like we did for polyfills above, but this way the element is injected lazily and only if the component is actually used in your server side code.

The rest of the integration JS is just standard Vaadin integration stuff. In the setBoardState the content is reset with the chess-board html tag and given state and in the move method we just modify the existing Web Component using its public JavaScript API.

Pretty simple I'd say - in case you master both JS and Java. In case you don't want to touch JS code, I just suggest to follow the updates in our Directory. I bet there will be several Web Component based Vaadin add-ons published in the future, and you can use Web Components in plain Java!

Play with the example integration

Trackback URL:

No comments yet. Be the first.