> Markdown version of [Limitations](https://vaadin.com/docs/next/flow/component-internals/templates/limitations). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# Template Limitations

- The framework considers any attribute other than `theme` or one of the [HTML 5 global attributes](https://www.w3.org/TR/html52/dom.html#global-attributes) for server-side initialization. However, if the attribute value isn’t a constant, that is, it contains bindings such as `${…​}` and `{{…​}}`, it isn’t parsed and the property isn’t initialized on the server side. Only attributes are parsed. Properties defined by nested elements, such as grid columns and items, aren’t parsed from the template but must be initialized on the server side.

- You can add components and elements to a template structure, but you can’t remove anything present in the original template. However, overriding component properties is possible.

- For `LitTemplate`, you can’t configure the column renderers for `Grid`, `TreeGrid` or `GridPro` in HTML. The column configuration and driving of data needs to happen from Java to the `@Id`-mapped component. `LitTemplate` differs from `PolymerTemplate` in this regard.

- Calling `setText()` from Java on a template-based component causes the removal of child elements. For example, if the template is `<div id="myDiv">Some text<vaadin-button id="myButton">My Button</vaadin-button></div>`, calling `myDiv.setText()` causes the `myButton` element to be removed. To keep children, instead wrap the text content in a separate child alongside `myButton`, and call `setText()` on that element: `<div id="myDiv"><span id="myTest">Some text</span><vaadin-button id="myButton">My Button</vaadin-button></div>`.

## <a id="out-of-sync-methods"></a>Out-of-Sync Methods

**Example**: `MainPage` JavaScript Polymer template file.

```javascript
class MainPage extends LitElement {
  render() {
    return html`
      <div id="header">Main page</div>
      <div id="content"></div>
      <hr>
      <div id="footer">
        <a href="mailto:someone@example.com?Subject=Hello" target="_top">Send Mail</a>
      </div>
    `;
  }
}

customElements.define("main-page", MainPage);
```

**Example**: Mapped Java template class.

```java
@Tag("main-page")
@JsModule("./com/example/main-page.js")
public class MainPage extends LitTemplate {

    @Id("content")
    private Div content;

    public void setContent(Component content) {
        this.content.removeAll();
        this.content.add(content);
    }
}
```

In the previous template class example, you could additionally map the `div` element with a `"footer"` identifier using the `Div` component and `@Id("footer")` annotation. However, the hierarchical structure is not available on the server side using the Java API.

The injected `Div` instance doesn’t have a server-side child, even though the `a` (anchor) element is available on the client side. The `getChildren()` method in the injected instance returns an empty `Stream`. Similarly, the `getText()` method of the `Div` instance injected using the `@Id("header")` annotation returns an empty string.

To summarize:

- Server-side `Component` or `Element` read methods aren’t always in sync with the client side.

- You can still use mutation API methods, such as `appendChild()`, `setProperty()` or `setAttribute()` from the server side, without issues.

- Getter methods return values that are set from the server side only.

## <a id="enabled-state"></a>Enabled State

Since the hierarchical structure in the template isn’t reflected on the server side, the `setEnabled()` method called on an `@Id` injected component doesn’t disable any other `@Id` injected component, even though such a component may be a descendant in the shadow DOM. (See also [Component Enabled State](https://vaadin.com/docs/next/flow/component-internals/enabled-state.md)).

**Example**: Disable an `@Id` injected component.

```java
@Tag("main-layout")
@JsModule("./com/example/main-layout.js")
public class MainLayout extends LitTemplate {

    @Id("layout")
    private VerticalLayout layout;
    @Id("textfield")
    private TextField textField;
    @Id("button")
    private Button button;

    public void onSomeAction() {
        layout.setEnabled(false);

        System.out.println(textField.isEnabled()); // prints "true"
        System.out.println(button.isEnabled()); // prints "true"
        // call explicitly setEnabled(false) to disable a component
        button.setEnabled(false);
        System.out.println(button.isEnabled()); // prints "false"
    }
}
```

```javascript
class MainLayout extends LitElement {
  render() {
    return html`
      <div>
        <vaadin-vertical-layout id="layout">
          <vaadin-text-field id="textfield"></vaadin-text-field>
          <vaadin-button id="button"></vaadin-button>
        </vaadin-vertical-layout>
      </div>
    `;
  }
}

customElements.define("main-layout", MainLayout);
```

## <a id="template-disabled-attribute"></a>Template Disabled Attribute

LitTemplate doesn’t support using the `disabled` attribute for an id-mapped component and throws an `IllegalAttributeException` with information on where it’s used. Id-mapped components should always be disabled from the server side using the `setEnabled(false)` method.

**Faulty sample**

```javascript
class MainLayout extends LitElement {
  render() {
    return html`
      <div>
        <vaadin-button id="button" disabled></vaadin-button>
      </div>
    `;
  }
}

customElements.define("main-layout", MainLayout);
```

```java
@Tag("main-layout")
@JsModule("./com/example/main-layout.js")
public class MainLayout extends LitTemplate {

   @Id("button")
   private Button button;
}
```

This throws an `IllegalAttributeException` with the message:

```
Lit template 'com.example.MainLayout' injected element 'vaadin-button' with id 'button' uses the disabled attribute.
Mapped components should instead be disabled using the 'setEnabled(false)' method on the server side.
```

> **Note:** PolymerTemplate doesn’t throw an exception for using the `disabled` attribute, but only stores it as a property of the element, leaving the element enabled on the server side.

## <a id="removing-mapped-elements"></a>Removing Mapped Elements

A virtually mapped `Element` is connected to the `ShadowRoot` of the `LitTemplate`, even if it’s actually deeper in the shadow tree. You can’t remove virtually mapped components from the DOM by removing them on the server side.

> **Note:** You can detect whether a component is used in a `LitTemplate` by using the `isTemplateMapped()` method. See the [Detecting Component Mappings](https://vaadin.com/docs/next/flow/component-internals/templates/component-integration.md) for more.

> **Note:** The same limitations apply to Polymer template classes.

`CDBCA1D4-E735-4258-9AB6-3BE9C36482A9`
