Documentation versions (currently viewingVaadin 24)

Embedded Application Limitations

List of limitations in embedded applications.

Some Vaadin features aren’t available in embedded applications.

Limitations in embedded applications include:

  • Navigation and routing: Both features are unavailable for embedded applications. You don’t need to annotate your classes with the@Route annotation, because it isn’t possible to navigate to the route target. You also can’t use the router link, whether via the RouterLink class or in a custom way.

  • Theming: You can specify only one @Theme annotation. See Theming Embedded Applications for more.

  • Push: You can use only one @Push annotation. See Configuring Push in Embedded Applications for more.

  • Progressive Web Applications: Neither the @PWA annotation nor any PWA features are available in embedded applications.

  • Cross-site embedding: Any Vaadin application is a Java Servlet-based application. Java Servlet applications use cookies to store a session ID. Sometimes, some browsers (for example, Safari) don’t allow cookies for an embedded page if it has a different domain. In this case, embedding requires SSL tracking mode to work. See the "Using an external Embeddable Application" section of Overview of Embedding Applications for how to configure embedded applications to work in this situation.

  • CORS headers: Cross-Origin Resource Sharing (CORS) headers aren’t defined automatically. If the Vaadin servlet providing the embeddable application is outside the servlet container that provides the page in which it’s embedded, these headers need to be provided.

The responses from the Vaadin servlet should contain appropriate CORS headers. You can add these by configuring the servlet container (see the documentation on adding HTTP headers for responses for your specific container), or by packaging the embeddable application with a custom VaadinServlet.

Below is an example with a custom VaadinServlet that adds CORS headers:

public class CustomServlet extends VaadinServlet {

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        setAccessControlHeaders((HttpServletResponse) res);
        super.service(req, res);

    private void setAccessControlHeaders(HttpServletResponse resp) {
        resp.setHeader("Access-Control-Allow-Origin", "http://localhost:80");
        resp.setHeader("Access-Control-Allow-Methods", "*");
        resp.setHeader("Access-Control-Allow-Headers", "Content-Type");
        resp.setHeader("Access-Control-Allow-Credentials", "true");

This example assumes that the embedding (host) site is served from the same host mapped to port 80 (be it a servlet container or a custom Python HTTP server). The servlet container with the Vaadin servlet is bound to, for example, port 8080.

Theme resources should be available on the server of the embedding page or embedded in CSS (as data URLs).

When embedding the application on a different server, relative CSS URLs target the embedding server and not the embedded application server.

Retrieve the target server address from the request as follows:

StringBuffer requestURL = ((HttpServletRequest) VaadinRequest.getCurrent()).getRequestURL();

You can then prepend that to the resource URL. For example:

new Image(requestURL.toString() + "themes/app-theme/img/logo.png", "logo");