I Coded My Personal Site With Web Components
Tags: webcomponents, webdev, career, showdev
Published: 2020-05-06 19:43:00

Ugh. The chore of refactoring a personal site. We all should do it but who has the time? This is the seventh iteration of my personal site, so I was in dire need of some inspiration. I'm looking for a part-time job teaching web development, so that was some motivation. 

I needed more to get me excited. All it took was solving problems with vanilla JavaScript and CSS. I'm over JavaScript frameworks. I’m done trying to wrangle all the tooling needed to develop modern JavaScript anything. I kept it simple. I designed the site mainly in browser which led to some fits and starts but the payoff was worth it. Little things like the way the nav animates made me excited to keep going. It was nice getting back to my roots. A decade ago I was a one man full service agency, designing and developing marketing sites and e-commerce solutions for small businesses. It helped I was also building something fun.

The last iteration of the site was very different. At the time in 2015 I wanted to showcase my mastery over AngularJS and WebGL. The site drained your battery due to all the graphics processing, was not very SEO friendly (SPA), and well we know how well AngularJS has aged. Any modern JavaScript framework is a better alternative, however for a site that is mostly static content I decided to move in a different direction.

![scrolling through my new personal site](https://dev-to-uploads.s3.amazonaws.com/i/xek9ooa4ot3f1m4yk63g.gif)

Nope, this is not Gatsby. Sorry folks. I don't believe in the hype. I do believe in spec. I decided to implement my entire site with the custom elements v1 spec. As long as the solution could meet several criteria I would be fine.

1. be viable five years into the future
2. demonstrate my ability to architect and implement UI 
3. SEO friendly
4. fun and easy to update, minimal maintenance

I chose Web Components instead of a modern JavaScript UI framework for several reasons. Spec is relatively future proof. Browsers will continue to implement the custom elements v1 spec for years to come, while JavaScript frameworks go in and out of fashion. I don't want to be in the same place in five years, regretting that I implemented my site with a JavaScript framework that is no longer supported. No... I want to look back and think "I made it so I only have myself to blame." 🤣

Last year I developed a microlibrary for coding Web Components with TypeScript decorators called [Readymade](https://readymade-ui.github.io/readymade/). I used this library throughout the project, implementing each view and component with Readymade. Readymade is a thin layer around the custom elements spec, reducing some of the typical boilerplate while adding some features with minimal overhead. If I went with another library I would have used Stencil or LitElement, but I chose to stay the course with Readymade despite some shortcomings.

Coding my personal site with Web Components just feels right. I honestly don't understand the JavaScript community's aversion to custom elements. I definitely prefer this way of working compared to React. There are some quirks when it comes to styling custom elements, but when isn't there? I feel like abstracting CSS to make styles reusable is always a problem no matter what you are doing. With Readymade I get one-way data binding, but the library doesn't have the equivalent of `ngFor` in Angular: a way to loop over a data model and bind it to template. That would be handy for dynamic layouts. To be honest that is the only feature I miss from frameworks. I don't miss the dependency management. I don't miss the tooling. I don't miss Virtual DOM. This is a fantastic way to work!

To make my new site SEO friendly, I needed to server side render each view. Server side rendering Web Components was a breeze. One of the few third party packages I used in the project was `@skatejs/ssr`, a package that enables SSR in node.js for the custom elements v1 spec. 

SkateJS needs to interpret the JavaScript for each component, so I bundled the components for the server, exporting each custom element tied to a route. Some of the components act as a view, while other components are smaller units of functionality. I devised a [route config](https://github.com/steveblue/personal/blob/master/src/client/server.ts) that could be injected into the [server-side code](https://github.com/steveblue/personal/blob/master/src/server/middleware/ssr.ts), which is also Express middleware. When a user visits a particular route, SkateJS renders the components on the server and then Express responds to the request for the route with the compiled HTML. One of the pain points for this project was when I ended up having to implement a Router that was compatible with both Readymade and SkateJS. It turned out not to be so bad. [76 lines of code later](https://github.com/steveblue/personal/blob/master/src/client/app/router/src/router.ts) and I had a router that worked.

I used [Parcel](https://parceljs.org/) for a development environment, coupled with a separate node process running an Express server that hosts a REST API. The API is only for the blog page. I display post thumbnails and descriptions from my posts on dev.to. To limit the amount of requests going to the DEV API, I setup my environment to query for the posts and then store them locally in production. I implemented a simple [JSON database with LowDB](https://github.com/typicode/lowdb) which seems to be proficient for this project.

Web Components will be supported in web browsers well into the future, so when deciding which client-side technology would be viable in five to ten years custom elements seemed like a no-brainer. I can still do all the things I could have with a JavaScript library, only with a smaller footprint and less tooling. My hands touched virtually everything end to end. I feel like I learned a lot. I had a lot of control over the stack, so I could pivot easily. 

Possibly the best story to come out of this project is about performance. The site when bundled for production weighs in around 23Kb (gzipped). That includes the microlibrary, router, the HTML, CSS, and JavaScript that actually displays content on the page. 23Kb is smaller than some JavaScript libraries. I consider that a huge win. Users don't have to download a ton of JavaScript. The homepage can load ~3.5sec over the "Fast 3G" network emulation in Chrome Dev Tools.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/15yoh7raucfgdx9xpnc6.png)


The site was just released so there are probably some minimal production bugs lurking around in some responsive states and devices. I decided to ship the MVP and circle back later to fix some of these issues.

Visit [stephenbelovarich.com](https://stephenbelovarich.com) if you're interested in viewing my new personal site. The [code is public on Github](https://github.com/steveblue/personal) for anyone interested in what the development environment looks like.

What do you think?