Automated workflows for websites
by Lea Rosema
A thing I did recently was adding some automated workflows to my blog so I can be sure my HTML, CSS, JS is valid and everything respects the editorconfig.
I also added linkedom for dom-like html transforms.
Credits for the automated checks and transforms go to Vadim Makeev
For validating HTML, I'm running the Nu HTML Validator against the dist directory. Validating HTML helps catching mistakes I might have otherwise missed. It also catches some accessibility bugs, like an
aria-labelledby pointing to an invalid id.
I installed it via
npm i -D vnu-jar and added an npm script for checking the html:
"lint:html": "java -jar node_modules/vnu-jar/build/dist/vnu.jar --skip-non-html --filterfile .vnurc dist"
In the filter file, you can specify regular expressions to ignore certain errors. I added the role about adding the list role on unordered lists, because Safari removes the role it when you add
list-style: none to the css.
The .list. role is unnecessary for element .ul.\.
This GitHub action executes these check on every commit.
In order to efficiently work with HTML, it would be cool to have a familiar API for manipulating the HTML structure, like a DOM API. A popular one for this use-case is JSDOM. I'm using Linkedom which has basically the same API but is more lightweight and also faster. Additionally, it provides possibilities to serialize dom trees to JSON, which is nice.
dom.document.appendChild. Afterwards, I can return it back as HTML via
The code for this is here: HTML transform configuration for Eleventy
For now, I just added a transform that adds ids for headlines, making headlines and sub-headlines linkable. Another potential use case for this kind of transforms is to also add additional automated accessibility checks. Check the document structure, test if everything has accessible names and check image descriptions, for example.
Another missing feature I plan to add through this is the recognition of external links and maybe open them in a new tab (I'm a bit divided on this, but when I do, I should also convey the information the link opens a new tab).
All I did here was to
npm install eslint, provide a basic configuration file and add an npm script to my
"lint:js": "eslint eleventy.config.js src/assets/js"
Additionally, I've set up a GitHub action for it which is run on every pull request and push to main.
Same as above for stylelint. I'm using a minimalistic stylelint configuration to avoid the most common pitfalls. I have to find out for myself which configuration works best for me. For now I went with
stylelint-config-recommended and I have also set up a github action for this.
I'm using semantic-release for version management. It automatically takes care of creating release download files and adding git tags.
To use it, it assumes a certain commit message structure. According to prefixes, version numbers are counted up and every release is shown on the GitHub repo page of this blog, including a Changelog in the description.
Fixes (all commits prefixed with
fix:) lead to a minor version upcount. Features (all commits prefixed with
feat:) lead to a middle version upcount. If you add "BREAKING CHANGE" to the commit description, this leads to a major version upcount. When doing a breaking change, also provide upgrade information in the breaking change.
For now, I just publish to GitHub, not to NPM (thus the
private field in the
To set it up, all I had to do was to
npm i -D semantic-release, setup the repository URL in the
package.json, setup a github action and set the permissions for actions inside my organization to read/write access.
I mainly used semantic-release for library code, not for websites yet. So this is more of an experiment, I don't know yet if it is too useful.
Of course, there is room for further improvement. One thing to look into are automated accessibility checks out there, like pa11y. There's a lot of stuff I have to experiment with and figure out what works best for me. Especially the html validation was very insightful and helped identifying some issues in the document structure, but I might not need it on every commit.