Application Basics

A Fusion application is written in TypeScript and runs in a single HTML page. An application consists of one or more views, each bound to a route or a URL path. To access business data and logic, an application can have server-side endpoints written in Java.

An Introduction to Reactive UIs

Views in Fusion applications are programmed in reactive rather than in imperative manner, as you would with Vaadin Flow, jQuery, and so forth. Reactive views have fewer moving parts and because of this they are easier to understand and debug. In reactive UI programming, the application UI is the value of a function. The function gets the component’s state as a parameter and returns HTML. Whenever the state changes, the UI is re-rendered.

The following example is given in both imperative (Flow/Java) and reactive (Fusion/TypeScript):

Open in a
new tab

In imperative UI programming, like with Vaadin Flow, there are two states: the data model and the UI. It is your responsibility as a developer to keep them in sync. You need to keep references to elements so you can update their values when the underlying state (the Contact) changes.

@Route("imperative-view")
public class ImperativeView extends Div {
  int count = 0;

  public ImperativeView() {
    Span text = new Span("Never clicked before");

    Button button = new Button("Click me!", event -> {
        count++;
        text.setText("The button has been clicked " +
                     count + " times");
      });

    add(new Div(text), button);
  }
}

Application Architecture

Most of the application logic is handled in application views. You could have a login view, registration view, main view, and various other views. To have a typical main view with menu navigation and multiple sub-views, you can use the App Layout component.

The entry point of a Fusion application is the application shell, which consists of the following files:

frontend/index.html

A bootstrap page that loads the application. You do not normally need to modify the file.

frontend/index.ts

The TypeScript entry point of the application. This is where you set up routing and other application tasks. To navigate between views, you need to define routes (see Defining Routes for more details).

If the application has server-side views implemented with Vaadin Flow, the routing configuration starts a server session and loads routes to the server-side views. See Starting the Application on how to run a Fusion application initially stateless and then start a session from TypeScript code.

Most of an application consists of views, as described next.

Adding a View

Views in Fusion are custom HTML elements that extend LitElement, which handles rendering the component state reactively. You minimally need to implement a render() function that returns the rendered HTML representation of the component. You can also provide custom styling by implementing a styles() function that returns custom CSS. See LitElement Basics for a more thorough introduction to using LitElement.

The following is an example of a view in Fusion:

Open in a
new tab
@customElement('my-view')
export class MyView extends LitElement {
  render() {
    return html`<vaadin-button @click="${this.sayHello}">Say hello</vaadin-button>`;
  }

  private sayHello() {
    alert('Hello');
  }
}

Basic Routing

In order to see the new client-side view in the browser, you need to define a new client-side route for it. A route is a path in the URL. That requires the following changes in the index.html and index.ts files:

import { Flow } from '@vaadin/flow-frontend';
import { Router } from '@vaadin/router';

import './my-view';

const {serverSideRoutes} = new Flow({
  // @ts-ignore
  imports: () => import('../target/frontend/generated-flow-imports')
});

const routes = [
    {path: '', component: 'my-view'},
    ...serverSideRoutes
];

export const router = new Router(document.querySelector('#outlet'));
router.setRoutes(routes);

Now my-view is accessible by the root path, that is, http://localhost:8080/. All the other routes are handled by the server-side router. See Defining Routes for more information.

Prerequisites

Fusion applications have some prerequisites.

To write the bootstrapping code for an application or create views in TypeScript, make sure that:

  • Client-side bootstrapping is enabled.

  • The index.html page template and the index.ts entry point exist in the frontend/ folder.

If you are starting with a starter application, they should already have been taken care of.

After that, any .ts file imported from index.ts (statically or dynamically) is going to be built as a part of the application.

Accessing Backend Data

Fusion provides a type-safe and secure way to access data from backend in frontend views by using generated TypeScript code. Vaadin scans the backend code during development and generates TypeScript code that can be used to call the corresponding Java methods. The generated code is processed through the same way as other TypeScript views. Only the necessary code is included in the production application bundle.

See Accessing Java Backend for more information.