How to include secondary Jekyll website using submodule

Caveat

The technique explained in this article expects that you own an HTTP server that you can run ruby/bundler on and build your Jekyll site on. This technique is not available for GitHub Pages.

The problem

After several month of Jekylling, I found it tedious to build my site locally and to upload it with scp, rsync, or something. I wanted my site to be built on the server, so that’s what I did. Then I realized I had another website which was hosting a blog at the “root directory” of your website while serving another Jekyll site at the different directly inside that.
Specifically, I had my dev blog and it also had product pages in the subdirectory and that page took advantage of _data directory and so on. It would be less confusing if you could source-control the two blogs separately by isolating them into different repositories.

https://example.com/  # A Jekyll site (A)
|- /2022/06/20  # Root level blog for site (A)
|- /another_product  # Separate Jekyll site (B)

I have tinkered around the Jekyll configuration and managed to pull it off, which I’ll share with you here.

TL;DR

  • Create a source directory in your root blog project and move source there. Remember the dir name, you will use that later
  • Include your secondary site as a submodule at the project root
  • Edit your root site _config.yml to exclude that submodule from root site build procedure
    source: ["src"]  # The source directory you have created.
    
  • Build the submodule site
    cd submodule_site
    JEKYLL_ENV=production bundle exec jekyll build
    cd ..
    
  • In the output directory of your root Jekyll site, create a symlink (e.g., submodule_site) pointing to the output directory of secondary Jekyll site
    cd $PROJECT_ROOT/_site
    ln -s ../submodule_site/_site submodule_site  # This will be a part of your actual link!
    
  • Edit your root site _config.yml to include this line
    keep_files: ["submodule_site"]
    
  • Build both sites
  • Profit

First thing first

When you do something like this, you should consider moving your website source into a directory of your choice, as including another Jekyll website as a submodule may confuse Jekyll. This is because, by default, most of the stuff in the project root is considered the source for the blog. Having another Jekyll project in such place can mangle everything. Consult my other post on how to do this:

You can read the same post on dev.to

Jekyll wants to play clean

If you put a symlink to the output directory of your submodule site into your source directory (by default it is your project root,) everything blows up at build time for some reason.

Now, the only thing we could possibly do is to create a symlink to the output dir of the submodule site into the output dir of the root site.

cd root_site/_site
ln -s ../submodule_site/_site submodule_site

But this does not work as everything in _site directory is wiped clean every build.

There is, however, a configuration key to stop this behavior.

The keep_files key

There is an official documentation page for configuration file syntax: https://jekyllrb.com/docs/configuration/options/

Buried in there is the fact that you can use keep_files key to tell Jekyll to leave specific files/directories behind before performing a clean on build. This key works for symlinks, too!

keep_files: ["submodule_site"]

Time to build

By building both the submodule site and the root site, you will have created a working site in the _site directory. By symlinking the output dir of the root site to your webroot, you can serve the website!