Cached Vaadin Routes

If you need to preserve the state of certain route during the duration of user’s session (e.g. to preserve a half-filled form so that the user can return to the form and fill it afterwards, or to create a multi-route wizard with a back+forward navigation), you may use the following code to cache the route components in your session.

The trick here is to create a customized Instantiator which, instead of creating new instances of routes, would store the instances into the session and reuse them afterwards.

For Vaadin 14.5.x and lower, customizing Instantiator is a bit tricky, see+vote Vaadin Flow #8427 for more details. The code looks like this:

@WebServlet(urlPatterns = "/*", asyncSupported = true)
public class MyServlet extends VaadinServlet {

    protected VaadinServletService createServletService(DeploymentConfiguration deploymentConfiguration) throws ServiceException {
        VaadinServletService service = new VaadinServletService(this,
                deploymentConfiguration) {
            protected Instantiator createInstantiator() throws ServiceException {
                return new MyInstantiator(this);
        return service;

    public static class MyInstantiator extends DefaultInstantiator {
        public MyInstantiator(VaadinService service) {

        public <T extends HasElement> T createRouteTarget(Class<T> routeTargetType, NavigationEvent event) {
            if (routeTargetType == MainView.class) {
                final MainView view = RouteSessionCache.getOrCreate(MainView.class);
                return ((T) view);
            return super.createRouteTarget(routeTargetType, event);

    public static class RouteSessionCache implements Serializable {
        private final Map<Class<?>, Serializable> routeCache = new HashMap<>();

        public static <T extends HasElement> T getOrCreate(Class<T> clazz) {
            RouteSessionCache cache = VaadinSession.getCurrent().getAttribute(RouteSessionCache.class);
            if (cache == null) {
                cache = new RouteSessionCache();
                VaadinSession.getCurrent().setAttribute(RouteSessionCache.class, cache);
            final Serializable instance = cache.routeCache.computeIfAbsent(clazz,
                    (c) -> ((Serializable) ReflectTools.createInstance(clazz)));
            final T route = clazz.cast(instance);
            return route;

For Vaadin 14.6+ you can simply provide your own implementation of InstantiatorFactory in order to produce MyInstantiator; you will no longer need to create a custom MyServlet.

Written on April 8, 2021