Hugo vs Nuxt.js - A Blog-Off
Tags: javascript, programming, career, vue
Published: 2022-04-08 12:23:59

I have been researching different Tools for blogging and two that have caught my eye were Hugo and Nuxt.js.

Being a developer who uses Vue.js quite heavily, Nuxt.js with its content module seemed like a good choice.

Hugo intrigued me because many say it is really fast and is based on Go, another language I am using more and more.

I thought the may be some of you are also looking at starting a blog or are looking to create a static site and would like to know more about two tools that you can use.

## Requirements
Choosing a framework is all about looking at what you need and then deciding which one suits your needs the best.

Seeing as I also want to showcase my design-skills, I will be looking at how much I can customize my blog.

## Static-Site-Generators

I would just like to get into what Static-Site-Generators are and why they seem to be getting really popular.

Not too long ago, you didn't have much choice when it came to creating your own blog - you had WordPress and then further being Drupal and Typo3 and others.

These were all heavy Content-Management-Systems that saved your posts in a database and retrieved them, when they were needed.

This made them a bit slow, because the client has to wait until a post has been retrieved from the database.

Enter Static Site Generators.

As the name suggests, we have no dynamic pieces of code here - we do not query a database for our posts.

The posts are written in markdown format and a the tool (Hugo, Nuxt.js, Next.js, Jekyll and many more) take that markdown and convert it to a static html page that gets presented to the user when it is called for.

That makes them really quick.

Additionally, because we have no server-side code that needs to be run, these sites can be run on any static-hosting service.

This also makes them really cost-effective alternatives to larger Content-Management-Systems.

Now let us get into our two contenders today.

### Hugo
Seeing as I am on a Mac, it was really easy to setup using brew to install Hugo:

`brew install Hugo`

After installing Hugo, we can create a new site by first navigating to where we want our Site to live and the typing in the following command:

`hugo new site <site-name>`

Simply replace `<site-name>` with your project name - this will be used to create a directory with that exact name.

Once that has been completed, we can add a theme to our blog.

## Themes
Like I already said in the introduction, I am looking to out my own stamp on the design of the site.

Therefore we won't be looking at the themes readily available for Hugo.

Of course your requirements are going differ from mine.

If you do find a theme that suits your need then that is great!

### Creating your own theme for Hugo
In Hugo this is done by creating my own theme.

We first add a new theme using the following command:

`hugo new theme <theme-name>`

This will create the skeleton structure we need to create a new theme for our blog.

The first thing we need to do is create our partials. If you are familiar with components, then partials are exactly that. They are re-usable pieces of code that we can use to make our code less repetitive.

We will first ensure that our metadata is correct in our head.html file:

![Screenshot of head.html file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gpc2r498e4f40s1fqobd.png)

Next we can define how our header is going to be styled:

![Screenshot of header.html](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6pn3i5hdr3s3affismhn.png)

Next we can write the markup that will be displayed on our landing page:

![Screenshot of landing page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ln057mxiqey9oq0m450d.png)

Finally, we need to tell Hugo that we want our theme to be used:

![Screenshot of configuration file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7c3jf0ye43wilkuuiyvl.png)

And if we now start up our development server using `Hugo server` we will see the end result:

![Screenshot of blog theme in browser](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1pfgl8tw52h617x6u8p.png)

The partials work because they are added in our base.html file:

![Screenshot of baseof.html file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z3ndhh02duig0ali2gbv.png)

We can also create our own partials by placing them in the partials folder and then referencing them in our template.

There are other default base styles available such as list.html for rendering a list of posts and single.html, for displaying a single blog post.

## Creating a new Post
We first define how our blog post should be structured. For this, we can use our single.html file:

![Screenshot of single.html](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vxc608u06wa7jwsq6kiz.png)

We are pulling in the title and our content.

Now let us create some content!

Create a new blog post:

`hugo new posts/testpost.md`

This will create our markdown file in a new posts directory within content.

Let us add a bit of content to the file and then start our development server:

![Screenshot of markdown file for content](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ph98droj1rvu9pcwx52a.png)

If we start up our development server `hugo server -D` we can see that our site is exposed at `http://localhost:1313`.

We can view our post by navigating to `http://localhost:1313/posts/testpost`:

![Screenshot of post detail page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pybyy048bov0hvi90cxm.png)

That worked out rather easily.

I would like to add in the name of the author. To not have to do this every time we write a post, I am going to make use of partials.

Let us create a new file in our partials directory called `post meta.html`:

![Screenshot of postmeta partial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/un4jyjzk0p8ko4npk2uc.png)

This will be used to display the author name.

Now we add this information to our single.html file:

![Screenshot of single.html with author name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gj1mgbm4ejivy6ht2sg4.png)

Now if we look at the post in our browser we see that the author name we defined in our markdown file has also been rendered:

![Screenshot of post in browser with author name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/szy1avpwguf7l7knhzgp.png)

This way we can include additional information about our post, such as the date it was published on, tags etc.

Lastly, we can also style our posts.

In our static directory we can add a new main.css file in our css directory:

### Nuxt.js
Now let us have a look at Nuxt.js.

To use Nuxt.js we can start by installing the necessary dependencies: 

`npx create-nuxt-app <project-name>`

Again, `<project-name>`is the name that you choose for your project.

We will then be asked a few questions:

![Screenshot of Terminal output with questions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1y366ra8p8jahhlib11.png)

For this project I decided to stick to JavaScript because we won't be dealing with anything data-heavy.

As a UI-Framework I went for Tailwind, but you can choose whatever you feel most comfortable with.

We can then also add in the Content-Module that will form the basis of your blogging app.

We then choose our Rendering mode to be `Universal (SSR / SSG)` and our deployment target we set to `Static (Static/Jamstack hosting)`.

We will use git as our version control system, since I have it already installed.

Then hit enter wait until everything is installed.

We can quickly check that everything works as expected by changing into our directory and starting up the development server:

```
cd <project-name>

npm run dev
```

After everything has compiled, you can navigate to `http://localhost:3000` to see the website:

![Screenshot of landing page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w5f8g97ejpu8lm8j5iyt.png)

Great! Everything installed perfectly fine.

No we can start by creating a new post.

## Creating a post
We can now quickly create a new post by first creating a new directory `articles` in our content directory that was created for us:

`mkdir articles`

And then create a new markdown file for us write our post:

`touch content/articles/testpost.md`

We can quickly add a few lines of markdown:

![Screenshot of markdown](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l9r635z7qhktnm7dd97o.png)

To expose our post we need to create a Vue component that will house our markdown.

For that, we can create a new directory in our pages directory called `blog`.

Inside blog, we can then create a new file called `_slug.vue`.

The file name allows us to make use of the params.slug parameter that we receive with from the vue-router. That way, when we finally navigate to `http://localhost:3000/blog/testpost`, we will see our freshly created page.

Before we can do that however, we need to prepare our newly created page:

![Screenshot of Component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijvdjnmzph9h2x5gbyig.png)

In the JavaScript above we are fetching our articles directory we created earlier alongside our params that we need for our routing to work.

The content is then rendered using the `<nuxt-content />`component that takes in the article variable we created.

The markdown then gets rendered to the browser like this:

![Screenshot of blog post](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dyetwn7wpxlggcelimy3.png)

The styling here is rather scarce - apart from the basic Tailwind style, there is not much happening here.

Let us change that.

## Styling
We already installed our tooling for getting started with styling our blog.

Nuxt.js as such does not have the theming-capabilities of Hugo, which does mean that we will need to develop our theme for our blog from scratch.

This does however give you more freedom to let your imagination run wild.

Do quickly show you how we can style our markdown, I made some changes to our _slug.vue file:

![Screenshot of Component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijvdjnmzph9h2x5gbyig.png)

Using the `nuxt-content` class followed by the element-tag we want to select, we can directly apply style using the tailwind utility classes.

It gives our page a bit more structure:

![Screenshot of styled page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v7eeinpc0kwbmdq5bf92.png)

## Final Impressions
Both frameworks offer something different to developers.

Hugo makes setting up a static site very quickly - even when creating your own theme, Hugo helps you along the way.

Nuxt.js on the other hand gives you a lot more freedom to build the site you want. If you are familiar with Vue.js, then you should be able to pick up Nuxt.js pretty quickly.

One major difference between the two is that Hugo does have a set of themes that you can use for your blog - Nuxt.js does not. This does allow you to hit the ground running really quickly.

If you have tried either one for a side-project or your blog, I would like to know how you found working with them.