GitLab Pages Theme Submodules


At the end of the GitLab Pages Setup post, I described an issue I encountered with GitLab CI generating the static site.
The issue is caused by Hexo themes being linked as Git submodules - which means the default theme configuration is used.
At the time, I only had a single idea - but was not sure whether or not it would work.
Since then I have had a few more ideas about possible solutions and this post will describe them.

Overwrite Default Theme Configuration

The most straightforward approach was to add the modified configuration file to the repository.
Using the GitLab build configuration, the configuration file could be copied to the themes folder overwriting the default theme configuration.

The only benefit to this approach is it’s simplicity.
Adding the file is trivial and the modified GitLab build configuration would look something like this:

image: node:10.15.3


- node_modules/

- npm install hexo-cli -g
- test -e package.json && npm install
- mv themes/_config.yml themes/icarus/_config.yml
- hexo generate

- hexo generate
- public
- master

In case it isn’t clear because it’s only a line, the change is:

- mv themes/_config.yml themes/icarus/_config.yml

This approach has a few problems though.
The first inconvenience is if the theme allows configuration of branding images or avatars that utilize a path in the theme structure these files must also be copied or moved into the theme after the submodule has been initialized.
This could probably be overcome by mirroring the structure of the theme and modifying the command to move a folder into the theme during the build process.
Changing themes requires updating the theme config file, the GitLab build configuration file, and adding the theme as a submodule reference.
Most troubling however is that if the submodule is updated, there is no way to detect conflicts or updates that may break the theme except at runtime.
Overall, this does not seem like a good approach anymore.

Include Theme Contents

The second option could be to include the theme contents directly instead of referencing them as a submodule.
Doing so would eliminate the first two issues described with the previous method above.
However, it still suffers from the final issue, although slightly different.
Updates now are a completely manual process, which will likely entail overwriting the files - potentially leaving orphaned files.
Additionally, it also adds bloat to the Hexo content repository that probably is not necessary.
Overall, this solution is better than the previous one but still is less than ideal.

Fork and Update

The final idea I had is to fork the theme being used.
Updates can be made to this new repository that are specific to the Hexo instance.
Updates can be applied by merging the original master repository into this forked copy.
If the update changes something that was unexpected, a conflict will occur that the user will have to resolve in order to finish the merge.
The Hexo content repository would then have the Git submodule reference the forked copy.
Another great part about this is that the submodule can be edited directly and changes committed for it from the parent module.


I think the final solution eliminates most of the major risks associated with the other options and is what I will be using.
I can even make my forked repository private and have the GitLab runner still able to access it thanks to GitLab’s CI build permissions.
The only differences are that my submodule name will need to be the project name and the url will need to be changed from an absolute URL to a relative url:

[submodule "hexo-theme-icarus"]
path = themes/icarus

The other solutions should work fine but they seemed wrong for one reason or another.
Choose whichever option has risks that you can live with.

Six Reasons Why I Chose Hexo


For most small websites today, website speed and server security trump dynamic content. Once a small website has established a theme, it is not likely to need to change with the content. And even when dynamic content is needed; such as comments or contact forms, there are services which allow this dynamic content to be embedded using JavaScript. Which is exactly why static site generators have become all the rage for personal and/or developer blogs. Enough where the number of options can be overwhelming, just take a look at the size of the scrollbar on StaticGen when no filters are applied.

Three Reasons Why I Chose NodeJS

WordPress has been the de-facto choice for years. They even know how much of the internet is built using WordPress. Even I used to use WordPress, but only because I felt like I had no other choice. I was happy to finally have a way to get away from WordPress. Although their new Ghost blogging platform was a candidate I was considering it was eventually discarded due to some of the security concerns I had about it.

The first step to deciding which static site generator to use is to narrow it down by programming language. Conveniently, this is also a feature that StaticGen provides. The most popular ones that I had heard about were Jekyll (Ruby), Hugo (Go), Hexo (JavaScript), Pelican (Python), and DocPad (CoffeeScript). I could eliminate a few already based on my previous experience with the languages they used: namely Ruby and Go. This left me with three potential language choices. Since I had some experience with Python from my college days I thought I would try something new. And it would probably be a good thing for me to try to get over my blatant hate for all things JavaScript. This led me to the decision that the blogging framework had to be built with NodeJS. Unfortunately, JavaScript has several different flavors and StaticGen does not allow you to select multiple languages at a time. At least not by default.

Getting A List of Frameworks

I dug through the source code for StaticGen and found that I could use Developer Tools to select multiple languages. The edit turns the option value from this:

<option value=".lang-javascript">

to this:

<option value=".lang-javascript,.lang-coffeescript">

A separate option could also have been added, but I only wanted JavaScript based frameworks. The resulting list was still fairly large, but it was much better than before. To reduce the list down even further I made the rule that I would only consider projects that had more than 500 stars - which would allow me to test a few that were under DocPad. DocPad was the deciding factor because it was the lowest of the frameworks that I had heard about.

I had a pretty thorough plan that I was going to try each framework and rate it in it’s ease of installation, ease of use, ability to theme, and ability to upgrade. Honestly, there were still too many frameworks for this kind of analysis. However, I did go through them all and gave each framework an attempt to win me over. I may make a post with the results of this analysis.

Six Reasons Why I Chose Hexo

Hexo turned out to be the ideal blogging framework for me, and here are the reasons why:

1. Hexo Knows What It Is and What It Is Not

Hexo sells itself as:

A fast, simple, and powerful blog framework

Which is exactly what I was looking for. At this time, I only need a blogging platform for publishing blog posts. Should I ever need additional functionality, I may consider an alternate framework.

A lot of the other top frameworks on StaticGen are actually build tools that are better for sites that are not specifically designed to be a blogging platform.

2. Hexo Keeps It Super Simple

Everything about Hexo was easy.

  • Installation
  • Setup
  • Installing Themes
  • Installing Plugins
  • Custom Theming

And the documentation is thorough enough that should any questions arise, the answer can likely be found in it. The only time I became lost was when I tried to go through the source code to understand how it was passing variables from the configuration files to the plugins while trying to set up another framework to do something similar.

3. Hexo Is Still Actively Maintained

Hexo is still being actively developed/maintained. Both in the forms of themes, and plugins; but also the core repository.

4. Extensible

Hexo comes with sane default values that will work out of the box, but these can also be changed using the plugin library. Alternatively, entire themes can be applied that have been build by other people if you do not want to do any of the work yourself.

5. Cross Platform Support and Baked In Package Manager

Not specific to Hexo, but to NodeJS - but it still is a benefit to using Hexo as opposed to creating a custom static site generator. But even if Hexo does not have a plugin for a particular technology, a plugin can be created and added to npm.

6. PluralSight Author Endorsed

By far the weakest reason on this list, but I still included it here because it provides more resources to learn about Hexo.

In the video course the course author advocates for DocPad, but on Twitter the course author has switched to Hexo.


Hexo might not be for everybody, but it met (and exceeded) the criteria that I was looking to fill. Other frameworks would have been ideal in other situations - but for getting a blogging platform out quickly Hexo just made sense.

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

$ hexo new "My New Post"

More info: Writing

Run server

$ hexo server

More info: Server

Generate static files

$ hexo generate

More info: Generating

Deploy to remote sites

$ hexo deploy

More info: Deployment

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now