> Markdown version of [Creating a Simple Component Using the Template API](https://vaadin.com/docs/v10/flow/polymer-templates/tutorial-template-basic). Section index: [llms.txt](https://vaadin.com/docs/v10/flow/llms.txt)

# Creating a Simple Component Using the Template API

There are multiple ways you can create a component. This tutorial uses the `PolymerTemplate` API with no additional elements or components. For other component tutorials, see:

- [Creating a Simple Component Using the Element API](https://vaadin.com/docs/v10/flow/creating-components/tutorial-component-basic.md)

- [Creating a Component Based on Many Elements](https://vaadin.com/docs/v10/flow/creating-components/tutorial-component-many-elements.md)

- [Creating a Component Using Existing Components](https://vaadin.com/docs/v10/flow/creating-components/tutorial-component-composite.md)

- [Creating a Component Which Can Contain Other Components](https://vaadin.com/docs/v10/flow/creating-components/tutorial-component-container.md)

For tutorials about how to use different template features, see:

- [Using \<slot> in PolymerTemplates](https://vaadin.com/docs/v10/flow/polymer-templates/tutorial-template-components-in-slot.md)

- [Handling User Events in a Template](https://vaadin.com/docs/v10/flow/polymer-templates/tutorial-template-event-handlers.md)

This tutorial is based on the [Hello Worlds technical demo](https://github.com/vaadin/flow-demo/tree/master/demo-hello-worlds). The demo shows three ways of achieving the same result: using components, element API and the template approach.

We’ll create a demo, that will be asking a user to input a name and will print a greeting on button click, using the input.

### <a id="client-side"></a>Client side

First, we need to define a template with all components:

```html
<link rel="import" href="../bower_components/polymer/polymer-element.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">

<dom-module id="hello-world">
    <template>
        <div>
            <paper-input id="inputId" value="{{userInput}}"></paper-input>
            <button id="helloButton" on-click="sayHello">Say hello</button>
            <div id="greeting">[[greeting]]</div>
        </div>
    </template>
    <script>
        class HelloWorld extends Polymer.Element {
            static get is() {
                return 'hello-world'
            }
        }
        customElements.define(HelloWorld.is, HelloWorld);
    </script>
</dom-module>
```

As you can see, this is a Polymer template. All features used in the example are standard Polymer features. If you’re unfamiliar with any of them, please refer to [Polymer project documentation page](https://www.polymer-project.org/2.0/docs/about_20).

> **Note:** The tag name of the template, which is defined by the `id` attribute on the `<dom-module>` element and the return of the function `is()`, should have at least one dash (`-`). The value `hello-world` is a valid tag name, but `helloworld` is not.

In the current demo, we have defined a regular template with regular elements, have specified one-way binding (`[[greeting]]`), two-way binding (`{{userInput}}`) and basic declaration for Polymer element in `<script>` class.

Note that there is an event handler `sayHello` that is triggered on `helloButton` click.

Notice that we have not specified the model at all, it will be propagated automatically from the server side.

We’ve also imported some dependencies:

- Polymer library

The `../bower_components/polymer/polymer-element.html` is a link to Polymer library that should be imported in order to have the functionality working.

> **Note:** You should take care about proper handling of the Polymer template file URL, it should be available via URL.

> **Note:** To get `polymer-element.html` into your project, you can use one of the ways provided by [official Polymer page](https://www.polymer-project.org/2.0/start/install-2-0) or use Maven plugins, such as [frontend-maven-plugin](https://github.com/eirslett/frontend-maven-plugin)

The latter way was used to create this example, you can reference [GitHub page](https://github.com/vaadin/flow-demo/) of a demo for more details.

- paper-input Polymer component

For clarity and demonstration purposes, this example uses [paper-input.html](https://github.com/PolymerElements/paper-input) component.

> **Note:** In order to retrieve and use the component in the demo, same rules as for `polymer-element.html` apply.

### <a id="server-side"></a>Server side

To be able to use this template you need to create a Java class which extends `PolymerTemplate`, set its tag name matching the Polymer `dom-module` id attribute and add the html imports for Polymer library (`polymer-element.html`) and our template:

```java
@Tag("hello-world")
@HtmlImport("/src/HelloWorld.html")
public class HelloWorld extends PolymerTemplate<HelloWorldModel> {
    private static final String EMPTY_NAME_GREETING = "Please enter your name";

    /**
     * Creates the hello world template.
     */
    public HelloWorld() {
        setId("template");
        getModel().setGreeting(EMPTY_NAME_GREETING);
    }

    @EventHandler
    private void sayHello() {
        // Called from the template click handler
        getModel().setGreeting(Optional.ofNullable(getModel().getUserInput())
                .filter(userInput -> !userInput.isEmpty())
                .map(greeting -> String.format("Hello %s!", greeting))
                .orElse(EMPTY_NAME_GREETING));
    }
}
```

Here we have defined a class with imports, tag, model and event handler.

There is also a model reference, that is defined the following way:

```java
/**
 * Model for the template.
 */
public interface HelloWorldModel extends TemplateModel {
    /**
     * Gets user input from corresponding template page.
     *
     * @return user input string
     */
    String getUserInput();

    /**
     * Sets greeting that is displayed in corresponding template page.
     *
     * @param greeting
     *            greeting string
     */
    void setGreeting(String greeting);
}
```

###### <a id="imports"></a>Imports

In order for a component to be processed correctly, we need to bind a Java class with the template, created earlier, by specifying `@HtmlImport` with path to a template

> **Note:** Java class name and template file name doesn’t have to match each other, this is just a resource file which you can put to any location. But you have to be sure that it’s accessible via the web.

The `/src/HelloWorld.html` is the URL of the Polymer template file declared earlier.

If needed, more html resources can be imported using the same approach.

###### <a id="tag"></a>Tag

The tag corresponds to `<dom-module id="hello-world">` id attribute, it sets the tag value to current component.

###### <a id="model"></a>Model

Model describes all properties that are passed to the html template and used on the client side. The model is simple Java interface, extending `TemplateModel` class and having getter and/or setter methods for properties. Model can be accessed via `getModel()` method after it’s specified as a generic type of `PolymerTemplate` class.

###### <a id="event-handler"></a>Event handler

Server side has method, annotated with `@EventHandler` annotation, that is used to react on event form the client side, triggered by the `helloButton` button.

###### <a id="call-the-server-side-method-from-the-client-side"></a>Call the server side method from the client side

Another way to call a server side method is `@ClientCallable` annotation which marks a template method as the method which should be called from the client side code using notation `this.$server.serverMethodName(args)`. It can be used somewhere in your client side Polymer class implementation. You can pass your own arguments in this method. Just make sure that their types matches to method declaration on the server side.

###### <a id="receiving-after-server-update-event"></a>Receiving "after server update" event

In some cases you may want to execute some client-side logic after the component is updated from the server during a roundtrip. E.g. the component constructor is called to create a component on the client side but this component is not yet initialized by data from the server side. So it’s too early to do anything with the component which is not yet ready. In this case you can use the method `afterServerUpdate`. If this method is defined for the component it will be called each time after the component is updated from the server side.

```html
<link rel="import" href="../bower_components/polymer/polymer-element.html">

<dom-module id="my-component">
    <template>
        <div>
            <div>[[text]]</div>
        </div>
    </template>
    <script>
        class MyComponent extends Polymer.Element {
            static get is() {
                return 'my-component'
            }

            afterServerUpdate(){
                console.log("The new 'text' value is: "+this.text);
            }
        }
        customElements.define(MyComponent.is, MyComponent);
    </script>
</dom-module>
```

### <a id="usage-in-code"></a>Usage in code

You can use `HelloWorld` like any other component.

```java
HelloWorld hello = new HelloWorld();

Div layout = new Div();
layout.add(hello);
```

> **Note:** To make your template-based product supporting non-ES6 browers like IE 11 and Safari 9, you need to configure the `vaadin-maven-plugin` in your `pom.xml`. See the chapter [Taking your Application into Production](https://vaadin.com/docs/v10/flow/production/tutorial-production-mode-basic.md) for more information.
