vaadinweb-componentvaadin23

web components not deployed in vaadin flow production


I'm using vaadin flow 23.2 and I've built a couple of web components.

The web components work fine in my development environment however they don't appear to work when I deploy them to production.

The most obvious sign is that in development the tags have a shadow DOM where in production there is no shadow dom.

I should perhaps mention that this components are only used client side. I have a server side component for each web-component but the server side component isn't being used to create the component. Instead the components are rendered by sending raw html to the browser.

This is the code for one of the components:

import {  css, html, LitElement } from 'lit';
import { property } from 'lit/decorators.js';



export class HintBlock extends LitElement {

    @property()
    colour = 'green';

    static styles = 
        css`
    
    .red {
        border-left: 4px solid red;
        padding: 10px;
        margin: 10px;
    }
     .green {
        border-left: 4px solid green;
        padding: 10px;
        margin: 10px;
    }
     .blue {
        border-left: 4px solid blue;
        padding: 10px;
        margin: 10px;
    }
    .orange {
        border-left: 4px solid orange;
        padding: 10px;
        margin: 10px;
    }
    `;

    render() {
        return html`
    <div class=${this.colour}>
        <slot></slot>
    </div>

    `;
    }
}
customElements.define('hint-block', HintBlock);

The unused server side component:

package dev.onepub.components;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;


/**
 * Server side for HintBlock Web Component 
 * @author bsutton
 *
 */

@Tag("hint-block")
@JsModule("./components/hint-block/hint-block.ts")
public class WCHintBlock extends Component {
    
    static Logger logger = LogManager.getLogger();

    private static final long serialVersionUID = 1L;

    public WCHintBlock(String content) {
        this.setContent(content);
        
    }
    
    private void setContent(String content) {
        getElement().setProperty("content", content);
    }
    
}

On my development system the block is rendered as:

hint-block

On production the same block is rendered as:

hint-block

Do I need to perform some action to have the custom web components included in the production build? I though the @JsModule and @Tag annotations were sufficient?


Solution

  • If you are using the web component indirectly, e.g. in your other templates, you need to add some hint for Vaadin's build plugin to pick the component. One way to do this is to add @Uses annotation in the view class where it is used or main layout.

    @Uses(WCHintBlock.class)
    

    It is actually irrelevant where it is as it is used build time. However those two locations are probably making most sense semantically.

    I have covered the case also in my blog post about creating custom components.