An Introduction to Web Components
Originally published at wearenorthern.com.
Throughout the history of the internet we’ve had various concepts of web components. jQuery plugins, Angular Directives, React, and others allowed developers to build custom components that other developers could use on their sites but they all have common drawbacks such as:
- Having to explicitly include dependencies of the library
- Having to add all script and style tags for the library
- Prefixing styles so that they would not leak into the host page
- Worrying about styles on the host page affecting the custom component
Web components are a set of standards defined by the W3C that allow developers to create custom elements while addressing the limitations mentioned above.
We’re going to introduce web components by writing two custom elements! The first element will be responsible for querying the reddit API for the top posts of a subject. It will display a title as well as create the second custom component and pass it the data from the API call.
We define a class called
RedditFeedElement which will query the reddit API to get the top posts for a subject. Our element has an attribute called
query that will allow the plugin consumer to specify the topic they’re interested in displaying on their site.
createdCallback is called whenever the element is created and before it is attached to the DOM.
We start by creating a shadow root with
this.createShadowRoot. This is part of the Shadow DOM specification and it allows us to create a HTMLNode which is isolated from the rest of the page. This means that styles will not be inherited from the host page which may mess with our custom component. Secondly any styles we define in the shadow node will not leak into the parent page.
We create a copy of our template, clone it, and then insert it into the shadow root. Using the
query attribute that was passed in we call the Reddit API and then interate over the first five results. For each result, we create a new
reddit-feed-row which is another custom component and append it to our shadow root.
In order to use our element we need to register it using:
Next we’ll define the component for rendering individual results.
The second component does that same setup as the first but with the addition of using the
attachedCallback which is called when the custom element is added to the DOM. The data from the API is already on the
data property of the component and was added during its creation in
reddit-feed. From there we select elements in the template and bind the data for title and image.
To view a demo of this component, take a look at this post on our website here. (Medium doesn’t like arbitrary HTML embeds).
In our next post we plan to cover converting this component into a Polymer component and explain the benefits this brings. Feel free to ask questions, provide feedback or let us know about what you’d like to hear more of in the comments!