> Markdown version of [Preserving the State on Refresh](https://vaadin.com/docs/next/flow/advanced/preserving-state-on-refresh). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# Preserving the State on Refresh

When a URL is entered into a browser, Vaadin’s routing subsystem resolves it into a view component by [inspecting @Route class annotations](https://vaadin.com/docs/next/flow/routing.md). By default, a new instance is created when a matching class is found. This also happens when the user refreshes the page in the same browser tab. However, in certain situations you may want to keep the state of the view when it’s refreshed.

One such situation might be if the view contains many data entry components, and the user is likely to refresh the page — intentionally or unintentionally — before the data is saved on the backend. By preserving the view, you ensure that the data entries aren’t lost and therefore provide a better user experience.

Another use case is supporting browser, tab-specific "sessions" as an alternative to the standard cookie-based session. The `@PreserveOnRefresh` annotation instructs Vaadin to reuse the view component of a route whenever the route is reloaded in the same browser tab. The routed component instance is then the same server-side object that was created in the first request, with all its state preserved — such as member fields, subcomponent hierarchy, and so on.

## <a id="preserving-the-state-of-a-component"></a>Preserving the State of a Component

To cause a single-view component to preserve its content on refresh, add the `@PreserveOnRefresh` annotation to the class.

**Example**: Adding the `@PreserveOnRefresh` annotation to the `PreservedView` class.

```java
@Route("myview")
@PreserveOnRefresh
public class PreservedView extends VerticalLayout {

    public PreservedView() {
        add(new TextField("Content will be preserved"));
        // ...
    }
}
```

If the view component has a [router layout](https://vaadin.com/docs/next/flow/routing/layout.md) via the `layout` parameter of the `@Route` annotation, the router layout is also preserved on refresh. As an alternative, you can add the `@PreserveOnRefresh` annotation to a class that implements `RouterLayout`.

**Example**: Adding the `@PreserveOnRefresh` annotation to an implementation of `RouterLayout`.

```java
@PreserveOnRefresh
public class PreservedLayout extends FlexLayout
        implements RouterLayout {

    public PreservedLayout() {
        // ...
    }
}
```

The `PreservedLayout` instance itself, as well as any view laid out inside it, is preserved on refresh.

Any elements that aren’t direct children of the view component, such as notifications and dialogs, are also preserved. This means that if your `@PreserveOnRefresh` annotated view class opens a dialog in which the user makes edits and then refreshes, the dialog remains visible in its edited state.

### <a id="partial-view-chain-preservation"></a>Partial View Chain Preservation

Partial chain preservation is supported by setting `partialMatch = true` for the `PreserveOnRefresh` annotation. This will enable reusing partial chain components from the preserved view chain.

This means that when navigating from a preserve on refresh target to a new url in the same client window context, where windowName matches, the router layouts that have been preserved will be reused without re-creation for the new route.

## <a id="preconditions-and-limitations"></a>Preconditions and Limitations

Using the `@PreserveOnRefresh` annotation has some conditions and limitations. They are as follows:

- The annotation must be placed in a component class that’s a route target — typically annotated with `@Route` — or on a component that implements `RouterLayout`.

- The component is made to persist only when reloaded in the same browser tab — the `window.name` client-side property is used to identify the tab — and only if the URL stays the same. Visiting another route or changing a URL parameter discards the component state permanently.

- Vaadin 10 and later don’t preserve the `UI` instance between refreshes. The view is detached from its previous `UI` and then attached to a freshed `UI` instance on refresh. The new `UI` instance does, however, keep the locale of the previous one, so a locale set with `UI.setLocale()` carries over to the preserved view instead of resetting to the session’s locale.

- The `AttachEvent` and `DetachEvent` events are also generated when a preserved component is moved to a new `UI`. As a consequence, during the lifetime of a view component, it should expect multiple calls to `onAttach()` and listeners registered through `addAttachListener()`.

- Navigation lifecycle events `BeforeEnterEvent` and `AfterNavigationEvent` are generated on refresh. The method `isRefreshEvent` can be used to distinguish a refresh of the view so that any data updates can be skipped.

`DABDBD3E-00C4-475C-A425-50B1AC48283E`
