> Markdown version of [Tutorial](https://vaadin.com/docs/next/flow/integrations/embedding/exporter). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# Creating an Embedded Vaadin Application

It’s possible to create a basic embedded application: that is, an application that can be embedded in another page.

Incidentally, the technology you use to create the host page is irrelevant. You can use Vaadin or non-Vaadin server-side Java technologies, such as JSP, Thymeleaf, or servlet, or even a basic static HTML page.

To embed a Vaadin application, you need to do two things. First, you’ll need to create an entry point. This is achieved by creating a `WebComponentExporter` for the Vaadin `Component` you want to embed.

Second, you’ll need a `VaadinServlet` to handle requests to your web component. The servlet can be declared in a non-Vaadin application, or deployed separately as a standalone `WAR` file.

This scenario uses a single custom servlet to handle the main application logic: the servlet displays primarily static content; and the content differs, depending on whether a user is logged in.

It also uses an embeddable Vaadin `Component` to implement a log-in form.

> **Note:** `VaadinServlet` forms part of the application, but its mapping differs from the main servlet mapping.

## <a id="create-an-entry-point"></a>Create an Entry Point

You can start with a clean project, or start building on top of the [Vaadin Base Starter](https://vaadin.com/hello-world-starters) (download the "Plain Java Servlet" version).

First, create the `MainAppServlet` servlet class. This servlet serves the static page which embeds the log-in form as a web component.

```java
@WebServlet(urlPatterns = {"/example"})
public class MainAppServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        Object authToken = req.getSession().getAttribute("auth_token");
        boolean isAuthenticated = authToken != null;

        try (PrintWriter out = response.getWriter()) {
            out.println("<!DOCTYPE html>");
            out.println("<html><head>");
            out.println("<meta http-equiv='Content-Type' content='text/html; "
                    + "charset=UTF-8'>");

            if (!isAuthenticated) {
                out.println("<script type='module' src='/vaadin/web-component"
                        + "/login-form.js'></script>");
                out.println("<script type='text/javascript' "
                        + "src='/log-in.js' defer></script>");
            }
            out.println("</head><body>");
            if (isAuthenticated) {
                out.println("<h1>Welcome "
                        + UserService.getInstance().getName(authToken)
                        + "</h1>");
            } else {
                out.println("<login-form userlbl='Username' pwdlbl='Password'>"
                        + "</login-form>");
            }
            out.println("</body>");
            out.println("</html>");
        }
    }
}
```

The HTML content generated by `MainAppServlet` includes this line that loads the web component:

```html
<script type='module'
        src='/vaadin/web-component/login-form.js'>
</script>
```

The script `src` attribute starts with `/vaadin/`. This is the URI to use to map to the Vaadin servlet (see [step 3](#step-3) below).

The second part of the link URI,`/web-component/login-form.js`, is the standard URI to use to import the web component. It consists of the hard-coded `web-component` part, followed by `login-form.js`, which is the web component file. The web component file is generated by Vaadin, based on the configuration set in the exporter.

The name of the web component in this example must be `"login-form"`. It must be used in both the `super` constructor of the exporter (see `LoginFormExporter` in [step 5](#step-5) below) and the HTML code where the web component is inserted.

In this example, this is right under the `<body>` tag:

```html
<login-form userlbl='Username' pwdlbl='Password'>
</login-form>
```

The `"login-form"` web component has two properties: `userlbl` and `pwdlbl`. These values are passed from the HTML to a web component instance.

> **Note:** The generated `"login-form"` element is a web component which wraps the original `LoginForm` HTML representation element (`"div"` , see below). This element is inside wrapper’s shadow root and isn’t available outside it. Hence, its styles don’t leak to the page, and global page styles don’t affect the styles of the embedded component.

## <a id="handling-requests"></a>Handling Requests

Next, you’ll need to create the `UserService` class. This class contains the authentication logic and is shared between the `MainAppServlet` and the web component class (created in [step 5](#step-5) below). You can use any interface and implementation you like.

This example is a custom stub implementation and is provided as a reference.

```java
public final class UserService {

    private static final UserService INSTANCE =
            new UserService();

    private UserService(){
    }

    public static UserService getInstance() {
        return INSTANCE;
    }

    public String getName(Object authToken) {
        return "Joe";
    }

    public Optional<Object> authenticate(String user,
            String passwd) {
        if ("admin".equals(user) &&
                "admin".equals(passwd)) {
            return Optional.of(new Object());
        } else {
            return Optional.empty();
        }
    }
}
```

## <a id="register-the-vaadinservlet"></a>Register the VaadinServlet

Now you’ll need to register the `VaadinServlet`. Here’s how you might do that:

```java
@WebServlet(urlPatterns = { "/vaadin/*" }, asyncSupported = true, loadOnStartup = 1)
public class WebComponentVaadinServlet extends VaadinServlet {
}
```

As mentioned above, the `/vaadin/*` mapping allows the `VaadinServlet` to handle web component requests. You can use any URI, but be sure to use the same URI in the mapping and in the import declaration.

> **Note:** If you deploy a web component exporter as a standalone `WAR` application, an explicit servlet registration is unnecessary. A servlet instance is registered automatically with the `"/*"` mapping.

You’ll also need to create the `LoginForm` component class:

```java
public class LoginForm extends Div {
    private TextField userName = new TextField();
    private PasswordField password =
            new PasswordField();
    private Div errorMsg = new Div();
    private String userLabel;
    private String pwdLabel;
    private FormLayout layout = new FormLayout();
    private List<SerializableRunnable> loginListeners =
            new CopyOnWriteArrayList<>();

    public LoginForm() {
        updateForm();

        add(layout);

       Button login = new Button("Login",
                event -> login());
        add(login, errorMsg);
    }

     public void setUserNameLabel(
            String userNameLabelString) {
        userLabel = userNameLabelString;
        updateForm();
    }

    public void setPasswordLabel(String pwd) {
        pwdLabel = pwd;
        updateForm();
    }

    public void updateForm() {
        layout.removeAll();

        layout.addFormItem(userName, userLabel);
        layout.addFormItem(password, pwdLabel);
    }

    public void addLoginListener(
            SerializableRunnable loginListener) {
        loginListeners.add(loginListener);
    }

    private void login() {
        Optional<Object> authToken = UserService
                .getInstance()
                .authenticate(userName.getValue(),
                    password.getValue());
        if (authToken.isPresent()) {
            VaadinRequest.getCurrent()
                    .getWrappedSession()
                    .setAttribute("auth_token",
                            authToken.get());
            fireLoginEvent();
        } else {
            errorMsg.setText("Authentication failure");
        }
    }

    private void fireLoginEvent() {
        loginListeners.forEach(
                SerializableRunnable::run);
    }
}
```

The example uses several Vaadin components: `FormLayout`, `TextField`, `PasswordField` and `Button`.

The code takes care of authentication and sets an authentication token in the `HttpSession`, which makes it available while the session is live.

Because the main application servlet uses the same `HttpSession` instance, it changes behavior and redirects authenticated users to the main servlet, which now shows content specific to authenticated users.

You can do this in various ways: One way would be to execute JavaScript directly from your Java code and set the location to `"/example"` : `getUI().get().getPage().executeJs("window.location.href='/example'");`. You could also use a solution similar to this example: design the component code so that its logic is isolated and it doesn’t need to know anything about the embedding context. This method allows you to decouple the embedded component logic completely from the application that uses it.

In this example, the `addLoginListener()` method allows you to register a listener which is called in the `fireLoginEvent()` method.

## <a id="export-loginform-component"></a>Export LoginForm Component

The final step is to export the `LoginForm` component as an embeddable web component using the web component exporter.

```java
public class LoginFormExporter
        extends WebComponentExporter<LoginForm> {
    public LoginFormExporter() {
        super("login-form");
        addProperty("userlbl", "")
                .onChange(LoginForm::setUserNameLabel);
        addProperty("pwdlbl", "")
                .onChange(LoginForm::setPasswordLabel);
    }

    @Override
    protected void configureInstance(
            WebComponent<LoginForm> webComponent,
            LoginForm form) {
        form.addLoginListener(() ->
                webComponent.fireEvent("logged-in"));
    }
}
```

The exporter defines its tag name as `"login-form"` by calling the super constructor `super("login-form")`. `LoginFormExporter` constructor must be public. Otherwise, Vaadin won’t be able to instantiate it.

The `addProperty()` method defines the component properties (``userlbl='Username' and `pwdlbl='Password'``) to receive values from the HTML element to the web component instance. This example declares the labels for the user name field and password field via HTML, instead of hard-coding them in the `LoginForm` component class.

The `LoginFormExporter` class implements the abstract method, `configureInstance()`, which registers a log-in listener.

The login listener fires a client-side `"logged-in"` event, using the `webcomponent.fireEvent()` method. The main application needs to handle this event somehow.

The custom event is handled by the JavaScript file declared via the line `<script type='text/javascript' src='log-in.js'></script>` in `MainAppServlet`.

This is the `log-in.js` file content — place the `log-in.js` under `./src/main/webapp/`:

```html
var editor = document.querySelector("login-form");
editor.addEventListener("logged-in", function(event) {
    window.location.href='/example';
});
```

The embedding servlet uses the API provided by `LoginForm` via a custom event and adds an event listener for the event. The listener redirects the page to the `"/example"` location.

Run the application with `mvn jetty:run`. After Jetty has started, navigate to <http://localhost:8080/example>. Then type in the log-in information and click on the "Login" button: `admin` for both user and password.

`0E2FEAC2-C4A1-4CB9-9859-B6E890A937C0`
