Skip to content

Web Components 101

Dave Lockhart edited this page Feb 19, 2019 · 16 revisions

This topic is a basic introduction to web components and the motivations behind using them at D2L.

web components logo

Topics:

What's a Web Component?

From webcomponents.org:

Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps. Custom components and widgets build on the Web Component standards, will work across modern browsers, and can be used with any JavaScript library or framework that works with HTML.

They're the holy grail of web development: the ability to define your own tags and then use those tags in any application, just as you would any regular tag.

First, define an element:

class MyCarousel extends HTMLElement {...}
window.customElements.define('my-carousel', MyCarousel);

Then, include and use it in any application:

<script type="module" src="my-carousel.js"></script>
<my-carousel></my-carousel>

This concept has been available through frameworks like Angular and React for years, but the main difference with Web Components is that they're part of the web platform, natively implemented in modern browsers -- no framework required.

Why are web components great for D2L?

The web is constantly evolving, arguably faster than any other area of development. Browsers are releasing monthly with new capabilities. It seems like no sooner has one web framework gained a following of faithful developers than another shinier framework unseats it.

various web frameworks

At D2L, we've seen a shift to a new web ecosystem approximately every five years. From ASP -> ASP.NET -> .NET MVC -> free-range apps, which can be built using any number of modern web frameworks. The future is uncertain, but we do know that there will definitely be another shift at some point!

It's for this reason that web components are so appealing. They're built using a web platform standard, so they're natively understood by modern web browsers. They're framework agnostic, and therefore relatively future proof.

Polyfills

Of course "natively implemented in modern browsers" means you'll need a polyfill for older browsers or for browsers who haven't fully implemented the various specs that make up the web components set of standards:

A single polyfill has been built which has a handy loader that will dynamically load only the parts needed for each browser.

<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>

More on the web component polyfill...

Starting with the v1 specifications, custom elements are defined using ES6 classes. These are natively supported in all browsers today with the exception of IE11. For IE11, you'll need a transpile-to-ES5 step like Babel as part of your build.

Which browsers do we currently need to support? Refer to the Platform Requirements document on the Brightspace Community.

Polymer

Web components may be everything we've ever wanted as developers, and while the APIs are very flexible, as with a lot of close-to-the-metal APIs, writing against them can be verbose and involve a lot of boilerplate code. With other modern frameworks, we've also grown accustomed to having features like data-binding that aren't specifically part of the web component standards.

For these reasons, as well as to protect us against breaking changes to the specs as they were initially being defined, we chose to write our web components using Google Polymer.

Polymer logo

Polymer had a lot of qualities that were appealing to us when we began on our web component journey in 2016:

  • Backing and support of a large corporate player (Google), which was and remains the main driving force behind making web components a reality
  • Great documentation
  • Open source
  • Tooling for automated tests, producing documentation, linting, building & bundling for production
  • A collection of existing web components both visual and utility

Since its initial releases, Polymer has matured and become more focused on its primary goals. With Polymer 2, it aligned itself with the ratified v1 web component specs, and with Polymer 3 came ES6 Module support and a transition to NPM from Bower for package management. Polymer 3 will be the last release though, replaced by the hyper-focused and minimalist LitElement.

D2L will continue to build and keep pace with advances to the Polymer ecosystem. We'll be constantly re-evaluating the best path forward for us, which may include a migration to LitElement or another web component platform in the future. For now though, Polymer is what you should be using to build web components. Wherever we end up, beneath it all lies a web platform standard, so our components will always continue to work!

Types of Web Components

The term "reusable/shared component" gets thrown around a lot to describe the different ways we define and create reusable bits of UI. This section attempts to lay out shared terminology we can use when we talk about "components".

Design Web Components

These are typically what designers think of when they picture "components". They're the primitive building blocks and styles we use to create any front-end application. Examples: buttons, menus, spinners, tabs, sliders, typography, iconography and so on. Our design web components fire events, contain behaviour and styling, but no baked in application logic.

UI primitives

All design web components must have design documentation on design.d2l and their code can be found in the BrightspaceUI GitHub organization.

Application Web Components (aka Hypermedia Web Components)

Unlike our design web components, application (aka data-driven or hypermedia components) are specific to D2L. They're the result of coupling a web component to one of our hypermedia APIs for a particular entity -- such as a user, a course or an activity.

Qualities:

  • As attributes, they have an href representing the location of the entity and a token for auth
  • Make an API call to fetch an entity and related resources
  • Cache the results for future reuse and to avoid duplicate requests
  • Understand the hypermedia response and render accordingly, exposing or hiding functionality based on the presence or absence of hypermedia classes, properties or actions
  • May make subsequent requests back to the hypermedia APIs based on user interactions

Non-Visual Application Components

Application web components can be very simple on the outside, with no visible styles or behaviours. An example would be a <d2l-user-name> component. Visually, it's just text. But that doesn't mean the logic on the inside is trivial. In fact, resolving our various permissions and privacy rules around displaying a user's name (or not!) can actually be quite complex.

Typically, non-visual application components do not require involvement from design -- they're purely technical in nature.

Visual Application Components

On the other end of the spectrum, application web components can verge on miniature applications.

For example, imagine we had a series of basic application web components for the user entity: <d2l-user-picture>, <d2l-user-name>, <d2l-user-role>. They could then be combined with the design components <d2l-card> and <d2l-button> components to create a more complex <d2l-user-card>:

user card hypermedia web component

We can go even further! To show a list of everyone in a particular course, we could combine those components in a different way to create a new <d2l-organization-class-list> application web component:

class list hypermedia web component

Application web components which have a significant visual element will have a corresponding entry on design.d2l and their code can be found in the BrightspaceHypermediaComponents GitHub organization.

For a more in-depth look: Application Web Components

What web components exist today?

See: Where to find existing Web Components

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.