Responsive Design and PWA

This section documents the current Vaadin release line — Vaadin 24 LTS / 25.x, Java 17+, Spring Boot 3 / Jakarta EE 10 — as published at the official Vaadin documentation, which is the reference these pages are written and verified against. No specific patch version is pinned. Flow (server-side Java) is the authoring style used throughout, with Hilla / React shown where it differs; Vaadin 7 and the pre-Flow architecture appear only as migration contrast.

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, since Vaadin ships major releases roughly twice a year and its ecosystem iterates.

This section’s bibliography lists the reference material consulted while preparing these pages.

Vaadin components carry responsive behaviour, and a few annotations turn a Vaadin app into an installable Progressive Web App. This page follows the Lumo breakpoint utilities, the PWA guide, and Designing Apps.

Responsive components

Several components adapt on their own once configured:

// FormLayout: one column on narrow screens, two from 30em up
form.setResponsiveSteps(
        new FormLayout.ResponsiveStep("0", 1),
        new FormLayout.ResponsiveStep("30em", 2),
        new FormLayout.ResponsiveStep("60em", 3));

// AppLayout: the drawer overlays instead of pushing below a breakpoint (its default),
// with a toggle in the navbar
appLayout.addToNavbar(new DrawerToggle());
appLayout.setPrimarySection(AppLayout.Section.DRAWER);

// Grid: let columns size to content, and one column absorb the slack
grid.getColumns().forEach(c -> c.setAutoWidth(true));
grid.getColumnByKey("description").setFlexGrow(1);

Breakpoint utilities

Lumo ships responsive variants of its utility classes — prefix a class with a breakpoint name and it only applies at that width and up. Combined with LumoUtility they cover most layout shifts without media queries:

layout.addClassNames(
        LumoUtility.Display.FLEX,
        LumoUtility.FlexDirection.COLUMN,
        "md:flex-row",            // horizontal from the medium breakpoint up
        LumoUtility.Gap.MEDIUM);

The breakpoints (sm, md, lg, xl, xxl) are listed at Responsive utility classes. For a hand-written media query, target the theme stylesheet.

The viewport

Flow sets a sensible viewport tag by default. Override it with @Viewport on the shell class when you need a different scale or zoom policy:

@Viewport("width=device-width, initial-scale=1, viewport-fit=cover")
public class AppShell implements AppShellConfigurator { }

Progressive Web App

@PWA on the shell class generates the web app manifest, icons and a service worker, so the app is installable and its shell loads offline:

@PWA(
    name = "Acme Field Service",
    shortName = "Acme FS",
    offlinePath = "offline.html",
    offlineResources = { "images/logo.png" })
public class AppShell implements AppShellConfigurator { }

The generated service worker caches the application shell; server-driven views still need a connection, so provide an offlinePath fallback and, for genuinely offline flows, a Hilla view with client-side state (see Hilla and React Views). See Creating a PWA.

Web Push

Web Push delivers notifications when the app is closed. Register the subscription on the client, store it, and send from the server through the WebPush API:

WebPush webPush = new WebPush(vapidPublicKey, vapidPrivateKey, "mailto:ops@example.com");

// after the user grants permission and the client posts its subscription
webPush.sendNotification(subscription,
        new WebPushMessage("Job assigned", "Ticket #4821 is now yours"));

See Web Push.

Designing apps

Designing Apps is the non-code companion: guidance on color and contrast, typography scale, size and space, and responsiveness patterns — all expressed in the same Lumo tokens the theme uses.

See also