Nowadays, it is rare to implement all software with a single technology. There are different teams and requirements, which is a good reason to allow a certain amount of variance in the software toolkit. The same goes for UI frameworks, and that's the way it should be. Hosting static HTML files generated by Jekyll can be one of the best choices for the majority of your public site, but then you need that critical application-like extranet part, where Vaadin is your tool of choice.
But your site should look uniform. This is especially important in the parts used by your customers who don't visit your site every day – not just for UX and brand image but also for trust. In the era of phishing attacks, people might hesitate to use an essential part of your site if it looks very different or broken.
Let's discuss a couple of strategies to make your Vaadin application fit better into the rest of your site.
Colors, typography, spacing, padding, logo - the theme
Adjusting the overall look and feel is the place to start. And, quite often, it can even be the only step to take. Adding a company logo to a page corner and using a similar color scheme and typography already do miracles.
The nasty thing for Java developers about theme building is that you can't do that with pure Java. As with virtually all other web pages, you'll use CSS to adjust these things. The good thing is that you can outsource it to someone who knows how to use CSS, and Vaadin comes with a parameterizable theme called Lumo, which makes doing these customizations efficient.
There are also a couple of tools that can make adjusting the theme easier, especially if you aren't yet a CSS wizard yourself. The project generator in start.vaadin.com contains a “Theme” tab that allows you to make rather versatile adjustments to the theme of the generated application – without touching a single line of CSS. The theme from a generated project can be easily moved to your existing application: copy the theme folder from the frontend/themes folder and adjust the name and value to match in the @Theme annotation of your current application.
For those getting deeper into Lumo theme customization, I highly recommend installing the new Vaadin Theme Assistant plugin to Chrome or Firefox. This new community effort extends the browser's web inspector with helpers for Lumo theme hacking.
Embedding Vaadin into your site
Embedding a Vaadin application into an existing web site, aka creating mashups, aka micro-frontends, is a powerful concept when you want to have a single Vaadin view in a part of a host page that is, for example, part of a larger portal. A typical example on vaadin.com is the discussions, embedded at the bottom of the blog posts and on each add-on page in the Directory. These are reusable dynamic parts, built with Vaadin Flow, that provide extra functionality to the main host page. In certain cases, as in the example case of Directory, the host page may be implemented with the same technology as the embedded part itself.
There are two approaches to implementing embedding: using the good old iframe element, or embedding as an “exported web component” – a web component that contains a rather normal Vaadin Flow application. The iframe approach is rock-solid and easy to implement, but has severe limitations when it comes to fluid layouts. Potentially variable size content in the iframe can’t easily make the host page grow. With iframes, you are basically stuck to fixed-size viewports or scrollable areas. If this is OK for your application, go with iframes.
The web component approach is the more flexible one and “academically correct”, but is slightly more complex to set up. For example, if your Vaadin application is hosted from a different domain, cookie policies and cross-domain restrictions in browsers may cause some headaches. While there are tools like CORS to override these restrictions, my pro tip is to use a front-proxy for all pieces of your site, like nginx, HAProxy or Apache, so that from the browser’s point of view, everything is coming from the same server.
The discussion portion in the Vaadin Directory is an example of embedded Vaadin application. In this case embedded inside another Vaadin application.
Most often there is some information you want to share with your “host page” and embedded Vaadin application. With iframes you can pass query parameters to your Vaadin application, exported web components can pass their properties to the server-side UI logic.
Unifying the look and feel with the “host page”, the topic discussed in the previous section, is even more essential when embedding your Vaadin application. The embedded part may look rather broken, if e.g. the used font is different in the main part and in the embedded forum part. With the exported web component approach you can in theory use the same stylesheet of your host page, but most likely adjusting the Lumo variables is the main tool to theme your embedded Vaadin application as well.
The docs site contains technical instructions on how to do embedding using web components. I’m preparing some more extensive examples and tips for working with the “exported web component” approach, so stay tuned!
Embedding your site decorations into your Vaadin app
If the Vaadin part is the page's primary content, there are multiple views, and the application requires deep linking, there is a high chance that changing the direction of embedding is the way to go. Instead of embedding Vaadin view into an existing page, it might make more sense to embed the site decorations, such as the header and footer of the site, into your Vaadin application. This way, you have a full-featured Vaadin application that still looks like a natural part of the rest of your site.
There are two tactics to embed pieces of your site to the Vaadin Flow part: edit the "host page" used by Vaadin or create Flow components of e.g., header and footer of your site. The former is more straightforward, especially with the latest versions, the latter more versatile. To demonstrate both approaches, I created an example project that decorates a simple Vaadin application into a basic Bootstrap template that consists of a header, footer, and the actual content area.
A screenshot of the example application. The Vaadin part is in the center of the page, everything else (header, footer and styles) are exactly like in the original Bootstrap example. In the example we did nothing for the Lumo theme to adjust it.
Since version 15, Vaadin generates an index.html page where the actual Vaadin application is rendered. In earlier versions, the “host page” was always generated on the fly. In both cases, the host html page can be modified. In my example project, I simply merged the Bootstrap template with the generated index.html file. The other static resources and css files are in the example in the resources directory, but in a real world case you can also load those directly from the actual site.
A slightly more flexible approach is to create Vaadin components from the blocks of the web site. In this example those were WebsiteHeader and WebsiteFooter classes. With this approach you could potentially put some dynamic content inside those parts as well and for example render the app navigation naturally inside the main navigation of the application. There are multiple tactics to create these parts. For this example, I chose to use Lit templates which also allows one to put CSS and scripts inside shadow DOM. With shadow DOM there is no risk of collisions with the Vaadin app and the site content.
Another potential solution would be to dynamically load the website html and snippets from the website or from a shared file system and inject the content to the components. The content can then be rendered using the Html component or simply using the Element API and innerHTML property. The latter is much more efficient for the server, but the former allows you to programmatically edit the DOM structure. The good part in this setup is that editing the website footer is only needed on the main site and the Vaadin application would pick up the changes automatically. For performance reasons, you still probably want to cache the content for a period of time in the JVM memory.
Did you find this article helpful? Let us know in the discussion below. If you are looking to build a Vaadin app, get started today!