> Markdown version of [Site Content](https://vaadin.com/docs/v24/tools/dspublisher/editing). Section index: [llms.txt](https://vaadin.com/docs/v24/tools/llms.txt)

# Site Content

## <a id="content-folder"></a>Content Folder

Documentation pages are located in the `articles` folder by default. This content root path can be configured with the [`ARTICLES_PATH` property](https://vaadin.com/docs/v24/tools/dspublisher/configuration.md#options).

## <a id="project-structure"></a>Project Structure

The most important files in the documentation project are shown here with their directory tree placement:

```
my-docs               (1)
├── articles/         (2)
├── dspublisher/
│   └──docs-theme
│      └──global.css  (3)
├── frontend/         (4)
├── src/main/java/    (5)
└── pom.xml           (6)
```

1. The root folder name is the short name provided to the initialization script.

2. Page content in AsciiDoc files.

3. Website style customizations.

4. TypeScript component examples.

5. Java component examples.

6. Maven Project Object Model (POM) for theme and component dependencies.

## <a id="page-hierarchy"></a>Page Hierarchy

The file and folder hierarchy defines the website URL and navigation structure directly. Each [AsciiDoc](#asciidoc) file (`.adoc` or `.asciidoc`) inside the content folder corresponds to a page on the website.

For example:

| Path                                    | URL                                              | Navigation hierarchy                    |
| --------------------------------------- | ------------------------------------------------ | --------------------------------------- |
| `articles/components/button/style.adoc` | `https://localhost:8000/components/button/style` | **Components** **›** **Button → Style** |

Each folder should have an `index.adoc` file, which defines the title and description of that section, and perhaps some content for the index page. An empty index page displays an automatically generated [section outline](#section-outline) (i.e., a listing of the sub-pages and sub-sections in that section).

## <a id="metadata"></a>Page Metadata (Front Matter)

Each AsciiDoc file starts with a YAML formatted metadata block called the "front matter", defined between lines with three dashes. The following front matter attributes can be defined in this block. Only the `title` attribute is required.

- `title` string

  **Required**. The page’s title as shown in the navigation menus/trees, breadcrumbs, search results, and social media share previews. This title can be different from the main page heading (i.e., the largest heading on the page), which is defined using AsciiDoc. For tabbed pages, this title attribute defines the main page heading, as well.

- `description` string

  Page description. Shown under the main page heading and in section outlines. Also used in social media share previews.

- `layout` string

  Only useful for `index.adoc` pages. Set to `tabbed-page` to display the pages in this section as tabs on the index page instead of as child items in the navigation tree.

- `tab-title` string

  The title displayed for this page when it is displayed as a tab. Useful if you want to show a shorter title in the tab and a longer one in the breadcrumb or search results.

- `page-links` list of string

  Links which are displayed in the page header. Can be used for linking, for example, to the component repository, Figma file, or other resources. The links are defined using AsciiDoc syntax, and they can also contain simple formatting.

- `order` number

  Overrides the placement of the page in the navigation tree among the sibling pages in the same section. By default, pages are ordered alphabetically based on the title. Pages without an order are placed after ordered pages. It’s a good practice to make them spaced by 10 or 100, so you can add pages between existing ones without changing the number in other pages.

- `banner` string

  Define a banner which is shown directly under the site header. A banner defined in the root `index.adoc` file is shown on all documentation pages, but it can be overridden with a page level banner.

- `banner-style` string

  Define the banner style. Possible values are `tip`, `important`, `warning`, and `caution`.

- `banner-id` string

  Define the banner ID. If defined, the user can dismiss the banner permanently on their device. A banner without an ID is displayed again after a page reload.

- `section-nav` string

  Allows you to control the page navigation item. Possible values are:

  - `expanded`: Expand this section in the navigation tree by default. Only applicable for `index.adoc` pages, which are not using tabbed page layout.

  - `hidden`: Hide this page from the navigation tree, section outlines, and page navigation at the bottom of each page. If you set this on an `index.adoc` page, all sub-pages are also hidden from the navigation tree, but they are not hidden from section outlines or page navigation.

  - A custom value, or a combination of values (e.g., `expanded custom-value`). The complete value is used as a class name on the corresponding HTML element in the navigation tree and section outlines, which allows you to add custom CSS styles for that item.

- `url` string

  Define an external URL to link to. This causes the page to not be created on the documentation website (i.e., all content in that file is ignored). The navigation item is instead a link to this external URL.

The following is a comprehensive example of the page metadata attributes:

`articles/components/accordion/index.adoc`

```yaml
---
title: Accordion
description: Accordion is a vertically stacked set of expandable panels. It reduces clutter and helps maintain the user's focus by showing only the relevant content at any time.
layout: tabbed-page
tab-title: Usage
page-links:
  - https://github.com/vaadin/vaadin-flow-components/releases/tag/24.10.12[Flow 24.10.12]
  - https://github.com/vaadin/web-components/tree/v24.10.8/packages/accordion[Web Component 24.10.8]
order: 10
banner: See the new https://example.org/blog[blog post]!
banner-style: tip
banner-id: my-new-blog-post
section-nav: expanded beta-component
---

// This is the main page heading...
= Accordion

// ...and the rest of the page content goes here
```

## <a id="page-partials"></a>Page Partials

Files whose names start with an underscore (e.g., `_shared.adoc`) and which don’t define any [page metadata](#metadata), don’t appear as pages in the website. Those files can be used to share content using AsciiDoc’s [include directive](https://docs.asciidoctor.org/asciidoc/latest/directives/include/).

## <a id="main-landing-page-site-name"></a>Main Landing Page & Site Name

The main landing page of the documentation website is defined with the `articles/flow/index.adoc` file. The `title` front matter attribute defines the visible name in the website header.

## <a id="asciidoc"></a>AsciiDoc Syntax

The content of each page is written in the AsciiDoc syntax, which has some [similarities with Markdown](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/#markdown-compatibility). See the [AsciiDoc Syntax Quick Reference](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/) for a comprehensive list of AsciiDoc features.

## <a id="section-outline"></a>Section Outline

Using the section outline macro, section index pages (i.e., all `index.adoc` files) can include an automatically generated outline of its sub-pages and sub-sections. The outline lists each sub-page or sub-section name and description.

For example:

`index.adoc`

```asciidoc
---
title: Section Name
description: This section contains multiple sub-pages and sub-sections.
---

= Section Name

Here's a brief overview of the contents in this section.
You can learn more from the following pages:

// tag::snippet[]
section_outline::[]
// end::snippet[]
```

This macro is not part of the standard AsciiDoc syntax, but an extension Design System Publisher provides.

## <a id="code"></a>Code Examples

To display monospace text within regular text, wrap words in backticks (i.e., the `` ` `` character). For example:

A paragraph with `monospace` text.

AsciiDoc

```asciidoc
A paragraph with `monospace` text.
```

Use [source code blocks](https://docs.asciidoctor.org/asciidoc/latest/verbatim/source-blocks/) to display code or command-line examples. Syntax highlighting for various languages is supported. The most commonly used ones are `java`, `typescript`, `html`, and `css`. For example:

```java
Button button = new Button("My Button");
```

AsciiDoc

```asciidoc
// tag::snippet[]
[source,java]
// end::snippet[]
----
Button button = new Button("My Button");
----
```

### <a id="source-title"></a>Source Code Block Title

By default, the source code language is used as the title of the block. You can define a [custom title](https://docs.asciidoctor.org/asciidoc/latest/blocks/add-title/#add-a-title-to-a-block-with-attributes), as well. For example, you could define a file name to illustrate the location of the code like so:

`MyButtonExample.java`

```java
Button button = new Button("My Button");
```

AsciiDoc

```asciidoc
// tag::snippet[]
.`MyButtonExample.java`
// end::snippet[]
[source,java]
----
Button button = new Button("My Button");
----
```

### <a id="source-tabs"></a>Combine Related Code Examples Together

You can combine multiple code examples together if you specify them inside an `.example` style open block. This is a good practice for showing a UI source code example, while having a data model or resource files available.

`VirtualListExample.java`

```java
List<Person> people = DataService.`getPeople(); // See Person.java`
VirtualList<Person> list = new VirtualList<>();
list.setItems(people);
```

`Person.java`

```java
public class Person {
  // The source of the Person object
}
```

`Address.java`

```java
public class Address {
  // The source of the Address object
}
```

AsciiDoc

```asciidoc
[.example]
--
.`VirtualListExample.java`
[source,java]
----
List<Person> people = DataService.`getPeople(); // See Person.java`
VirtualList<Person> list = new VirtualList<>();
list.setItems(people);
----

.`Person.java`
[source,java]
----
public class Person {
  // The source of the Person object
}
----

.`Address.java`
[source,java]
----
public class Address {
  // The source of the Address object
}
----
--
```

## <a id="code-include"></a>Code Examples from Source Files

You can include code examples from any file in the documentation project, by using the AsciiDoc [include directive](https://docs.asciidoctor.org/asciidoc/latest/directives/include/) — primarily from files in the `frontend` and `src/main/java` source code folders, but practically from any folder in the project. The benefit of including them from the source code folders is that those files are compiled during the build. This ensures that any compilation errors in the code examples are detected early.

Use the AsciiDoc include directive to include them in code blocks as follows:

AsciiDoc

```asciidoc
[source,java]
----
include::{root}/src/main/java/path/to/MyExample.java[]
----
```

Use the `{root}` attribute reference at the start of the path, if you want to use an absolute reference — starting from the project root. Otherwise the path is relative to the AsciiDoc file where the include directive is used.

By default, the name of the file included is used as the title for the source code block. You can [customize the title](#source-title) if needed.

### <a id="include-parameters"></a>Include Parameters

You can pass various parameters to the include directive, between the trailing square brackets, to affect how the code example is included.

- `render`

  Renders a interactive example, as described in [Rendered UI Examples](#rendered-examples).

- `tags=<name>`

  Specifies tags for extracting a source code snippets. See [Snippets](#snippets) for more information.

- `indent=<spaces>`

  Specifies the indentation of the code inside the listing. Without the parameter, the indentation in the source listing is used. You should use `indent=0`.

- `group=<name>`

  Groups the file under a group tab. You can use this for language groups, such as `group=Java` and `group=TypeScript` in corresponding include statements. You shouldn’t use it if you only have a single group, as it would show an unnecessary tab. See [Group Source Code Blocks](#example-groups) for more information.

- `hidden`

  Hides the example. This is necessary for TypeScript counterparts of Java examples, which are only included to load component styles, as described in [Client-Side Dependencies of Java Examples](#typescript-counterparts).

### <a id="snippets"></a>Snippets

Snippets — known as [Tagged Regions](https://docs.asciidoctor.org/asciidoc/latest/directives/include-tagged-regions/) in AsciiDoc — are segments of code examples. They’re displayed by default, instead of the entire source code of an included file.

The **Expand code** button in the example reveals all the lines of the source code. This can be useful for making it easier for readers to see the most relevant part.

For example:

`ButtonBasic.java`

```java
Button button = new Button("Button");
Paragraph info = new Paragraph(infoText());
button.addClickListener(clickEvent -> {
    counter += 1;
    info.setText(infoText());
});
```

AsciiDoc

```asciidoc
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/component/button/ButtonBasic.java[tags=snippet]
----
```

Use snippets by adding the `tags` attribute in the brackets following the path, indicating which named snippet to include (i.e., `include::path/to/example[tags=snippet]`).

#### <a id="defining-snippets"></a>Defining Snippets

Snippets are defined in the source code as comments: `tag::snippet[]` marks the start of the snippet; and `end::snippet[]` marks the end of the snippet.

The snippet name between the colons and square brackets can be any string. You don’t need to name it "snippet", but you need to use the string for both the starting and the ending comment.

Write the comment in the format defined for the example’s syntax highlighting. For TypeScript examples, this means that code tagged with `[source,html]` must use HTML comments within an HTML literal in the code. Here are examples for commonly used languages in the documentation:

Java

```
public MyComponentExample() {
  // tag::snippet[]
  MyComponent myc = new MyComponent("My component");
  // end::snippet[]
  add(myc);
}
```

TypeScript

```
render() {
  // tag::snippet[]
  return html`
    <!-- tag::another-snippet[] -->
    <my-component>My component</my-component>
    <!-- end::another-snippet[] -->
  `;
  // tag::snippet[]
}
```

HTML

```
<div>
  <!-- tag::snippet[] -->
  <my-component>My component</my-component>
  <!-- end::snippet[] -->
</div>
```

CSS

```
/* tag::snippet[] */
html {
  color: black;
}
/* end::snippet[] */
```

### <a id="hidden-source-lines"></a>Excluding Source Code Lines

Part of the source code can be entirely omitted from the rendered code examples by appending a specific comment after the line (i.e., `hidden-source-line`). For example, here’s how you would hide an annotation in a Java example:

`MyComponentExample.java`

```java
// The following line isn't shown
// if this file is added using the include directive
public MyComponentExample() {
  MyComponent myc = new MyComponent("My component");
  add(myc);
}
```

`MyComponentExample.java`

```java
// The following line isn't shown
// if this file is added using the include directive
// tag::highlight[]
@SomeAnnotation // hidden-source-line
// end::highlight[]
public MyComponentExample() {
  MyComponent myc = new MyComponent("My component");
  add(myc);
}
```

AsciiDoc

```asciidoc
[source,java]
----
include::path/to/MyComponentExample.java[]
----
```

This is useful for excluding code that’s only needed for a [rendered UI example](#rendered-examples), but not relevant for normal use of a component.

This isn’t a standard AsciiDoc feature, but an extension that Design System Publisher provides.

### <a id="example-groups"></a>Group Source Code Blocks

When you [combine related code examples together](#source-tabs), they can be grouped to create collections of related source files by including the `group` attribute in the include directive. Each group can include a description for its contents written before each source code block.

A common use case for the grouping is to show alternative approaches for achieving the same end result. For example, how to implement a certain user interface in either Java or TypeScript:

Here’s some text to describe the TypeScript example. You could mention things like the `Person.ts` file.

**TypeScript** — `virtual-list-basic.ts`

```html
<vaadin-virtual-list
  .items="${this.people}"
  ${virtualListRenderer(this.personCardRenderer, [])}
></vaadin-virtual-list>
```

**TypeScript** — `Person.ts`

```typescript
import type Address_1 from "./Address.js";
interface Person {
    firstName: string;
    lastName: string;
    email: string;
    birthday: string;
    id: number;
    subscriber: boolean;
    membership: string;
    pictureUrl: string;
    profession: string;
    address: Address_1;
    managerId?: number;
    manager: boolean;
    status: string;
    fullName?: string;
}
export default Person;
```

**TypeScript** — `Address.ts`

```typescript
interface Address {
    street: string;
    city: string;
    state: string;
    zip: string;
    country: string;
    phone: string;
}
export default Address;
```

Here’s some text to describe the Java example. You could mention things like the `setRenderer()` method.

**Java** — `VirtualListBasic.java`

```java
VirtualList<Person> list = new VirtualList<>();
list.setItems(people);
list.setRenderer(personCardRenderer);
add(list);
```

**Java** — `Person.java`

```java
package com.vaadin.demo.domain;

import java.util.Date;

import javax.annotation.Nonnull;


// tag::snippet[]
public class Person {

    @Nonnull
    private String firstName;

    @Nonnull
    private String lastName;

    @Nonnull
    private String email;

    @Nonnull
    private Date birthday;

    @Nonnull
    private Integer id;

    @Nonnull
    private Boolean subscriber;

    @Nonnull
    private String membership;

    @Nonnull
    private String pictureUrl;

    @Nonnull
    private String profession;

    @Nonnull
    private Address address;

    private Integer managerId;

    @Nonnull
    private Boolean manager;

    @Nonnull
    private String status;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getFullName() {
        return firstName + " " + lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public boolean isSubscriber() {
        return subscriber;
    }

    public void setSubscriber(boolean subscriber) {
        this.subscriber = subscriber;
    }

    public String getMembership() {
        return membership;
    }

    public void setMembership(String membership) {
        this.membership = membership;
    }

    public String getPictureUrl() {
        return pictureUrl;
    }

    public void setPictureUrl(String pictureUrl) {
        this.pictureUrl = pictureUrl;
    }

    public String getProfession() {
        return profession;
    }

    public void setProfession(String profession) {
        this.profession = profession;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        return id;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Person)) {
            return false;
        }
        Person other = (Person) obj;
        return id == other.id;
    }

    public Integer getManagerId() {
        return managerId;
    }

    public void setManagerId(Integer managerId) {
        this.managerId = managerId;
    }

    public boolean isManager() {
        return manager;
    }

    public void setManager(boolean manager) {
        this.manager = manager;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}
// end::snippet[]
```

**Java** — `Address.java`

```java
package com.vaadin.demo.domain;

import javax.annotation.Nonnull;

public class Address {

    @Nonnull
    private String street;

    @Nonnull
    private String city;

    @Nonnull
    private String state;

    @Nonnull
    private String zip;

    @Nonnull
    private String country;

    @Nonnull
    private String phone;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZip() {
        return zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

}
```

AsciiDoc

```asciidoc
[.example]
--
Here's some text to describe the TypeScript example.
You could mention things like the `Person.ts` file.
[source,html]
----
include::{root}/frontend/demo/component/virtuallist/virtual-list-basic.ts[group=TypeScript,tags=snippet,indent=0]
----
[source,typescript]
----
include::{root}/frontend/generated/com/vaadin/demo/domain/Person.ts[group=TypeScript]
----
[source,typescript]
----
include::{root}/frontend/generated/com/vaadin/demo/domain/Address.ts[group=TypeScript]
----

Here's some text to describe the Java example.
You could mention things like the `setRenderer()` method.
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/component/virtuallist/VirtualListBasic.java[group=Java,tags=snippet,indent=0]
----
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/domain/Person.java[group=Java]
----
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/domain/Address.java[group=Java]
----
--
```

## <a id="rendered-examples"></a>Rendered UI Examples

You can render a [code example](#code-include) as an interactive UI example by including the `render` attribute in the include directive. Only Java and TypeScript examples can be rendered. The following is an example of a rendered Java example:

`ButtonBasic.java`

```java
package com.vaadin.demo.component.button;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.router.Route;

@Route("button-basic")
public class ButtonBasic extends Div {
    private int counter = 0;

    public ButtonBasic() {
        // tag::snippet[]
        Button button = new Button("Button");
        Paragraph info = new Paragraph(infoText());
        button.addClickListener(clickEvent -> {
            counter += 1;
            info.setText(infoText());
        });
        // end::snippet[]

        HorizontalLayout horizontalLayout = new HorizontalLayout(button, info);
        horizontalLayout.setAlignItems(FlexComponent.Alignment.BASELINE);
        add(horizontalLayout);
    }

    private String infoText() {
        return String.format("Clicked %d times", counter);
    }

}
```

AsciiDoc

```asciidoc
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/component/button/ButtonBasic.java[render]
----
```

Client-Side Dependencies of Java Examples

Styles for components that are used in an example are only loaded for TypeScript examples. You therefore always need a TypeScript counterpart for any Java example. Otherwise, the components aren’t styled and the example appears broken. The TypeScript example doesn’t need to be functional, it only needs to import the needed components.

The TypeScript `include` shouldn’t have a `group` parameter, and it should have the `hidden` parameter instead of `render`.

For example, the AsciiDoc source for the previous example is actually the following:

AsciiDoc

```asciidoc
[.example]
--
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/component/button/ButtonBasic.java[render]
----
[source,typescript]
----
include::{root}/frontend/demo/component/button/button-basic.ts[hidden]
----
--
```

Alternatively, you can use the `DOCS_IMPORT_EXAMPLE_RESOURCES="true"` [configuration option](https://vaadin.com/docs/v24/tools/dspublisher/configuration.md#options) to load all frontend resources up front. Then it’s sufficient to include the Java code example without an additional, or hidden TypeScript example. Add it as before the start-up or build command:

```terminal
DOCS_IMPORT_EXAMPLE_RESOURCES="true" npm run dspublisher:start
```

Use [code example groups](#example-groups) to show both a TypeScript and Java implementation for the same UI. For example, here’s the same example as before, now with a corresponding TypeScript version included.

**Java** — `ButtonBasic.java`

```java
package com.vaadin.demo.component.button;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.router.Route;

@Route("button-basic")
public class ButtonBasic extends Div {
    private int counter = 0;

    public ButtonBasic() {
        // tag::snippet[]
        Button button = new Button("Button");
        Paragraph info = new Paragraph(infoText());
        button.addClickListener(clickEvent -> {
            counter += 1;
            info.setText(infoText());
        });
        // end::snippet[]

        HorizontalLayout horizontalLayout = new HorizontalLayout(button, info);
        horizontalLayout.setAlignItems(FlexComponent.Alignment.BASELINE);
        add(horizontalLayout);
    }

    private String infoText() {
        return String.format("Clicked %d times", counter);
    }

}
```

**TypeScript** — `button-basic.ts`

```typescript
import '@vaadin/button';
import '@vaadin/horizontal-layout';
import { html, LitElement } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { applyTheme } from 'Frontend/generated/theme';

@customElement('button-basic')
export class Example extends LitElement {
  protected override createRenderRoot() {
    const root = super.createRenderRoot();
    // Apply custom theme (only supported if your app uses one)
    applyTheme(root);
    return root;
  }

  @state()
  private counter = 0;

  protected override render() {
    return html`
      <!-- tag::snippet[] -->
      <vaadin-horizontal-layout theme="spacing" style="align-items: baseline">
        <vaadin-button @click="${() => this.counter++}">Button</vaadin-button>
        <p>Clicked ${this.counter} times</p>
      </vaadin-horizontal-layout>
      <!-- end::snippet[] -->
    `;
  }
}
```

AsciiDoc

```asciidoc
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/component/button/ButtonBasic.java[render,group=Java]
----
[source,typescript]
----
include::{root}/frontend/demo/component/button/button-basic.ts[render,group=TypeScript]
----
```

### <a id="always-show-source-code"></a>Always Show Source Code

Use the `show-code` style to show the source code immediately, so that the user doesn’t need to click the **Show code** button to reveal it. You can apply the style on a standalone source code block, or an `.example` style open block.

`ButtonBasic.java`

```java
Button button = new Button("Button");
Paragraph info = new Paragraph(infoText());
button.addClickListener(clickEvent -> {
    counter += 1;
    info.setText(infoText());
});
```

AsciiDoc

```asciidoc
// Source code block
// tag::highlight[]
[source,java,role="show-code"]
// end::highlight[]
----
...
----

// Example open block
[.example.show-code]
--
...
--
```

### <a id="always-hide-source-code"></a>Always Hide Source Code

Use the `render-only` style to hide the source code. This doesn’t disable the [example group tabs](#example-groups), which can still be used to choose which rendered example is shown.

`ButtonBasic.java`

```java
Button button = new Button("Button");
Paragraph info = new Paragraph(infoText());
button.addClickListener(clickEvent -> {
    counter += 1;
    info.setText(infoText());
});
```

AsciiDoc

```asciidoc
// Source code block
// tag::highlight[]
[source,java,role="render-only"]
// end::highlight[]
----
...
----

// Example open block
[.example.render-only]
--
...
--
```

## <a id="writing-examples-to-be-rendered"></a>Writing Examples to be Rendered

Before you can add a rendered UI example on a page, you need to create the example itself.

Add dependencies for custom components to the `pom.xml` file the same way as a [custom theme JAR](https://vaadin.com/docs/v24/styling/advanced/multi-app-themes.md). Components and themes can be included in the same dependency.

### <a id="java-examples"></a>Java Examples

Place Java-based examples in sub-folders inside the `src/main/java/` folder. Each example needs to be in its own file. To add examples for a new component, create a new folder inside the `component` folder with a Java file inside it. For example, see the `MyComponentExample.java` file:

```
my-docs
└── src/main
    └── java/com/vaadin
        └── demo
            └── component
                ├── accordion
                ⋮   ├── AccordionBasic.java
                ⋮   ├── AccordionDisabledPanels.java
                ⋮   ⋮
                ├── mycomponent
                ⋮   ├── MyComponentExample.java
                ⋮   ⋮
```

`src/main/java/com/vaadin/demo/component/mycomponent/MyComponentExample.java`

```java
package com.vaadin.demo.component.mycomponent;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.router.Route;
import com.vaadin.demo.DemoExporter; // hidden-source-line
import com.example.MyComponent;

@Route("my-component-example") // (2)
public class MyComponentExample extends Div { // (1)

    public MyComponentExample() {
        MyComponent myc = new MyComponent("My component");
        add(myc); // (3)
    }

    // (4)
    public static class Exporter extends // hidden-source-line
        DemoExporter<MyComponentExample> {} // hidden-source-line
}
```

1. A class that extends `Div` or some other container like `VerticalLayout`.

2. with an optional `@Route` annotation with a route name that’s unique within the entire website.

3. and a constructor that adds the desired UI as a child to the class.

4. A static inner class that extends the `DemoExporter` class with a type parameter matching the example class.

Design System Publisher uses `spring-boot-devtools` to rebuild automatically the Java examples when you modify and save them — assuming you configured your editor or IDE to do so. Rebuilding the Java examples typically takes about thirty seconds, after which the page must be reloaded manually.

### <a id="typescript-examples"></a>TypeScript Examples

Place TypeScript-based examples in sub-folders within the `frontend/` folder. Each example needs to be in its own file.

```
my-docs
└── frontend
    └── demo
        └── component
            ├── accordion
            ⋮   ├── accordion-basic.ts
            ⋮   ├── accordion-disabled-panels.ts
            ⋮   ⋮
            ├── my-component
            ⋮   ├── my-component-example.ts
            ⋮   ⋮
```

To add examples for a new component, create a folder with a TypeScript file inside it. For example:

`frontend/demo/component/my-component/my-component-example.ts`

```typescript
import '../../init'; // hidden-source-line
import { applyTheme } from 'generated/theme';
import { html, LitElement, customElement } from 'lit-element';

import '@my-org/my-component/my-component';

@customElement('my-component-example') // (1)
export class Example extends LitElement { // (2)
  protected createRenderRoot() { // (3)
    const root = super.createRenderRoot();
    applyTheme(root);
    return root;
  }

  render() { // (4)
    return html`
      <my-component>My component</my-component>
    `;
  }
}
```

1. A `@customElement` annotation with a name that’s unique within the entire website.

2. A class that extends `LitElement`.

3. A `createRenderRoot()` method that calls the `applyTheme(root)` method. This applies your custom theme to the example.

4. A render method that returns the HTML for the example.

TypeScript code examples don’t refresh automatically. The code example displayed below a rendered example isn’t refreshed when you edit the source AsciiDoc file in your text editor. To refresh the code example, the page’s text content needs to be re-saved for Design System Publisher to rebuild the page, and you need to reload the page.

`6DF51E1C-15BB-4E15-A3C7-5C616B7BFC35`
