Nuxt Generation
August 31, 2021

Recently I replaced my old SSD which, resulted in me re-installing everything. All seemed fine. When I started to write new content to the site and run the command to generate it in order to verify if the layout was correct, errors. Lots of them. Apparently the packages in my Metalsmith tool chain became broken with the newer Node version. So I run the command to update the packages, in the hopes it would fix. Unfortunately it didn't. And apparently it became worse because instead of spitting lots of error messages the process just froze.

After spending a lot of time attempting to fix the generation, and failing, I decided to look up for a new static site generation tool. At first I thought it would be a long search since I had some rather limiting "constraints". Some of the key points were:

  1. The tool had to allow me to keep the output structure of the files at least very close to what I already had (ideally equal), even though it might not be the best. Reason for this is to not break any links.
  2. I didn't want to work with React nor Angular. Don't get me wrong, I don't consider any of those bad. It's just that neither of those two fit my personal coding/workflow preference.
  3. Although I have some rants over Markdown, I didn't want to spend time converting my content to any other format, so Markdown had to be supported by the generator.
  4. A mere few days before I found out that my site building was broken I started to follow a few Vue.js tutorials. Since I immediately liked it, I was able to remove a few constraints from the search.
  5. It had to be somewhat "understandable" for my non-web-developer-brain. This is something important. I'm not a web developer. And a lot of web technology names are presented as acronyms, extremely rarely with a hint of what those are.

So I wanted to see a list of static site generators, with a brief explanation of the capabilities of that tool. I found Jamstack . Bizarrely my eyes automatically filtered out any non JavaScript cards, even though they were there, which resulted in me finding Nuxt . My first query was to see if it supported Markdown. And indeed, there is NuxtJS/Content module that brings this feature. Every other feature that I required and queried, were there.

Before I jumped right into Nuxt I wanted to at least see a little bit of the other options. However I think my brain had already decided what my Nuxt step had to be. So after installing it and following a few of the official guides I was able to rather quickly configure everything and generate the files with the exact same structure of my already existing site. Of course I was still missing pretty much everything else. And so begun my journey into rebuilding my web site.

To understand a little bit of my ramblings here, let's go back into what I had before with Metalsmith. In there I had to manually install a plugin for pretty much every single "transformation" that I required. One to interpret Markdown files. One to take that and apply templates. One to help me organize the files into "collections" that would in the end become the different sections of the site. One to specifically provide data for pagination. Another to pack my CSS files into one. Another... I think you got the point.

Indeed, with Metalsmith we have to manually deal with pretty much every single step of the site generation, everything controlled by plugins. That is incredible powerful because we have absolutely full control over the output. That might become a nightmare because we have to know absolutely everything about what is going on. For someone like myself, with very little knowledge about web technologies, going with Metalsmith as a first tool was probably not exactly the best choice. And it became absolutely obvious when the building process broke.

Still, the fact that I could control everything about the output was something that I really liked. The output was exactly what I configured the system to be. No additional files. No additional code embedded into each file. Yet, most of process stated to become rather problematic because I had to know the exact order in which the plugins had to transform the input. Anything that I placed out of order and everything would fail. As an example, the test server stopped working for a long time and I had to rely on a different way to verify site updates.

Another problem that came with all that is related to how I had to handle Markdown. For my requirements, completely impractical and I have already ranted about it here.

As I began working with Nuxt and had the output structure in the desired way, so then began my actual Vue learning. This was my first obstacle. Not the technology in itself, but the fact that I was reading Vue's newest documentation and attempting to apply that into the project files I had. To put things in context, at the time of this writing Vue is at version 3 and Nuxt uses Vue 2. So, yeah. I had lots of problems until I realized this fact, at which point things went relatively smooth, even though many of the underlying systems I had missed some features.

One of the features of NuxtJS/Content is the fact that we can incorporate Vue Components within Markdown. That's huge! While this fact doesn't completely remove my rants about some of the impracticalities, it does reduce the problems a lot! To take things into perspective, I was able to simply write a component to take card rendering from something like this:

%%%card
%%%card__title
Title of the Card
%%%
%%%card__content
Contents of the card
%%%
%%%

Into this:

<cardnews card_title="Title of the card">

Contents of the card

</cardnews>

Indeed this made things a lot easier, although still mixing text with "html". I soon had components to deal with a lot of things. One of them is meant to deal with one of the limitations of NuxtJS/Content, which is related to adding images to articles. Basically we have to write full paths to the files rather than taking relative paths. With a component I was able to take a relative path and calculate the actual full path to the image. While that forced me to use yet another component from within Markdown, it is still very acceptable given that before I still had to utilize <img src="path_to_file"> tag directly from within Markdown anyways in my previous tool chain. Without manually doing this I had problems with the images lacking the CSS classes that I required in order for those to work in the desired way.

Yet, this component thing within Markdown turned into the biggest obstacle I have run when I was finally reaching the point where I could update my site again. That was related to the RSS generation. In the NuxtJS/Content there is a piece of the documentation specifically focusing on the RSS generation, which uses a Nuxt module. The problem is the fact that I wanted to incorporate the full body of my blog posts within the generated RSS entries.

My first attempt was to manually run the markdown processor into the contents of the input file and give that into the feed generation. Problem is, the processor doesn't know what to do with Vue components and, for some weird reason, everything was converted into <div> instead of the desired output. It became clear that I had to extract the body from something that was already rendered. So I did that. While the components were correctly handled, another problem appeared, which was the additional stuff that came with the output. Navigation bar, script importing and so on. So I created a dummy page meant exclusively to perform this rendering and serve as the main feed source. It greatly reduced the extra artifacts, but I still had to remove some other stuff. Luckily it wasn't hard to write two "replace" statements within the feed factory function and everything was working as desired. Bottom line, some of the components that I use throughout the site cannot be used in any article that may become part of the RSS because those may contain some UI functionalities that will not work in aggregators (anything that require script and/or CSS, out of question).

Now that dummy page thing is something really interesting. I wanted a way to have pages marked as draft and not be included within the generation. Thanks to how Nuxt generates Vue routes work I was able to do that using the same underlying idea of the dummy pages. If I mark a page as a draft I simply don't include it in any link within the pages when generating. With that I can preview the text in the dev environment while completely excluding those from the final output. Excellent!

All in all, my entire workflow has been improved by a system that does most of the things automatically for me. Although it's not entirely "free of problems". The thing is, I have lost a little bit of control over the output. A bunch of extra files are generated and imported into the final html code. I still believe this is a valid trade off and one that I'm whiling to accept.

If you did read this rambling, thank you very much for your time. If you have any feedback, please do send me it!

And this is how the Nuxt Generation of my site begins...