Documentation

Learn how to build, publish, and launch your site with Adobe Experience Manager.

Resources

Widgets

Introduction

Widgets are the application parts of a website, the places where there is no content and often a significant amount of “placeholders.” Typical examples are forms, product listing pages, search results, filtering and other indexes, dealer locators, sign-in and account management, and calculators. In many cases a widget is used in only a few places on a website, and sometimes it exists only once.

This makes widgets different from blocks. Blocks add form and function to content that authors create in a document. Widgets, by contrast, are self-contained pieces of application logic that an author references by simply pasting a URL. There is no table to fill in and usually no content to author, since the widget brings its own markup, styling, and behavior.

How widgets relate to blocks

Widgets are structurally very similar to blocks. A block lives in the /blocks/ folder and consists of a .css file and a .js file. A widget lives in the /widgets/ folder and, in addition to .css and .js, it also ships its own .html file and often a .json file for configuration or data.

A typical widget therefore looks like this:

/widgets/hello-world/hello-world.html
/widgets/hello-world/hello-world.css
/widgets/hello-world/hello-world.js
/widgets/hello-world/hello-world.json   (optional)

The .html file provides the static markup and placeholders the widget needs, the .css file styles it, and the .js file decorates it, wiring up behavior exactly the way a block’s decorate function does.

Keeping widgets in their own folder, separate from blocks, is a deliberate choice. It avoids polluting the block library with components that have little to do with everyday content authoring, and it isolates the author from all of the functionality that needs to be part of a website but simply doesn’t play a big role in their day-to-day work. Authors keep working with a clean, content-focused set of blocks, while the application machinery such as forms, search, and account management lives quietly alongside it in /widgets/.

Referencing a widget

Widgets are referenced simply by inserting a URL that points to the widget’s .html file. In your document, add a link whose target is the widget, for example:

https://main--your-repo--your-org.aem.page/widgets/hello-world/hello-world.html

When the link is the only thing in its paragraph, it is automatically turned into a widget block during page rendering. Behind the scenes the link is replaced with a widget block, the widget’s .html is fetched and injected, and its .css and .js are loaded. The resulting element is given a class matching the widget name (for example hello-world), so you can target it from CSS just like a block.

You can also pass parameters to a widget by appending a query string to the URL. Each parameter becomes a data- attribute on the widget element, which the widget’s JavaScript can read:

https://main--your-repo--your-org.aem.page/widgets/hello-world/hello-world.html?name=World

In this example the widget element receives a data-name="World" attribute that the widget code can use.

A hello world widget

Let’s build the simplest possible widget. Create the folder /widgets/hello-world/ and add the three files below.

The markup, hello-world.html:

<p class="greeting">Hello, <span class="name">world</span>!</p>

The styles, hello-world.css:

.hello-world .greeting {
  font-size: 2rem;
  font-weight: 700;
  text-align: center;
  padding: 2rem;
}

.hello-world .name {
  color: var(--link-color, #3b63fb);
}

The behavior, hello-world.js:

export default function decorate(widget) {
  // Parameters from the widget URL are available as data attributes.
  const name = widget.dataset.name || 'world';
  const target = widget.querySelector('.name');
  if (target) target.textContent = name;
}

The decorate function receives the widget element after its .html has been injected. Here it reads the optional name parameter from the URL (exposed as widget.dataset.name) and updates the greeting.

To use the widget, reference it from a document with a single link:

https://main--your-repo--your-org.aem.page/widgets/hello-world/hello-world.html?name=AEM

This renders as a centered greeting that reads “Hello, AEM!” with no content authoring beyond the link itself.

When to use a widget

Reach for a widget when you are building an application-like part of the site rather than presenting authored content. Forms, search and results pages, faceted filtering, dealer locators, sign-in and account management, and calculators are all good candidates, especially when they appear in only one or a handful of places. For repeated, content-driven structures that authors fill in across many pages, a block remains the right tool.

Conclusion

Widgets give you a clean way to drop self-contained application functionality into a page with nothing more than a URL. They reuse everything you already know about blocks, including a decorate function, scoped CSS, and a folder per component, while adding their own HTML and optional JSON so they can stand on their own without authored content.