Web Component Based Architecture

Ryan Mackey-Paulsen
5 min readMay 27, 2019

--

Solving the UI Rubix Cube

Sure, for web development, we have several options with how we go about building an application. Libraries and frameworks are everywhere with their own takes on rendering and application structure, but if there is one thing that they all share in common, it’s building with components.

React and Vue.js are pretty much libraries for building components. Angular is structured around building components and grouping them with modules. Polymer/lit-html are also great for building sharing components that work regardless of the rest of your tech stack. Heck, just use the native Web Component APIs and polyfill for older browsers.

The trick with this, though, is visualizing how to do this and it’s not always easy to do. I have seen several examples of ‘component’ use that really just masks the old way of building apps with monolithic templates or components that really just break up existing templates. There is nothing immediately wrong with these if you need to get something out the door quickly, but the chances of code reuse and flexibility go right out the door and it’s hard to go back and fix things if you have been building on something that is misguided in the first place. So, let’s take a look at what this architecture is and how it can help us in the future.

Thinking About Components

Thinking about how to break things down into components is the first step that I see people having trouble with. For many who miss this, the concept of a component is a way of breaking up templates, but that is only part of the story. One image that best sums up how to visualize a component tree is from the React docs.

As you can see, everything is highlighted with a color that represents an opportunity to create a component. Some share the same color, so we can create a single component and reuse it. Not only can we reuse it here, but we can reuse it everywhere if we think about what its purpose actually is. Here, we might think that this is a product list so we would create a ProductList component. However, take a second look and you might realize that that is simply a list with groupings and list items.

So, a reusable pattern for the image above would be to create some sort of List component that can hold a ListGroup with a header and ListItem s. This leaves this open to the possibility of being reused anytime you need a list. But, why do this when you can just use ul or ol ?

This is the hard part because it would be incredibly easy to just throw a ul under the form and keep moving, but think about your UI as a whole. What if your style library or current list styles are targeting something like <div class="listItem"> ? What if you want to switch to ul s? If you didn’t create a generic list component, you would have to change your templates everywhere there is a list. With a generic component, you just have to make the change in a single place.

A list component seems pretty trivial to change and unlikely that you would change the markup very often, but apply the generic component thinking to something like an accordion or a modal or even the layout of a form. It would be so much easier to update or apply a bug fix to the component and have it update everywhere it is used rather than find everywhere it is used and make the changes there.

Component Trees

The next big concept is components that contain other components (and those could contain other components and ……). Nested components is something that all of the libraries I mentioned at the start support. Even angular.js has transclusion. Without the nesting of components, your options are limited to something like passing data to the component and then the component having a set of conditionals within the template or components that are too specific to be shared and then are copied and pasted to other similar components. Boooooo.

One thing I like to point out about component usage is how it is giving us the ability to make our own HTML elements. Think about this, you don’t pass content to a div through an attribute or property. For a custom button, you wouldn’t do this:

<my-button class="btn" text="Click Me" icon="search"></my-button>

Instead, we do this:

<my-button><i class="search"></i>Click Me</my-button>

If you look at the difference, one thing you should note is that the second example does not really care about what goes in between the tags. We could put anything in there, within reason, and make a button. However, what would happen in the first example if the icon property only took SVGs but we had a png? What if the content wasn’t a string, but more HTML? Would it handle that or do we create a one-off button to do what we need that could then get lost when our buttons get updated?

So, once we have a component that can take content, we can create other components that reuse them and end up with something like this:

<my-actions>
<my-button>
<my-icon>search</my-icon>
Click Me <span class="small">(or don't)</span>
</my-button>
</my-actions>

Looking For Inspiration

One idea for grasping what is actually doable or how to break up UIs into smaller reusable pieces is to look at the UI as a library and not as an application. That’s right, even though you might already be using a library, you could still wrap the components you are using with your own custom components and then reap the benefits.

Are you using Bootstrap? Cool, create a modal component that just using the modal markup for a bootstrap modal. Can you guess how easy it will be to change all of your modals throughout your application when you decide to remove bootstrap from your project or use a different modal library? Well, you will only have to change modals in a single place rather than everywhere, so my guess is much easier.

If it is still hard think about what can be reused, I would also suggest looking at the libraries that are already out there. Also, look at how they are used. For angular devs, https://material.angular.io/ is obviously a go to, but if you look at the APIs and code examples for some of the components, you can get ideas for how you can make components specific to your application, but reusable throughout your application (or even applications).

Wrap Up

This is just a starting point to get the idea of building complex applications with components. Here, we are not just using components as a way to break up our templates into smaller pieces, but see how we can reuse components by making them generic enough. We can reduce the size of our apps by defining these components in a single place and also make changes to those components much less of a headache by containing the markup, styles, and logic in a single place.

And this is just the beginning, but this line of thinking will help to build a strong foundation for the rest of your application to grow on.

--

--

Ryan Mackey-Paulsen

Web App Developer, Web Component Enthusiast, Musician, Human