How to include secondary Jekyll website using submodule
Tags: ruby, jekyll, git, submodule
Published: 2022-07-05 08:55:52

---
title: How to include secondary Jekyll website using submodule
published: true
description: It is possible to do that at least on a server that you can control.
tags: ruby, jekyll, git, submodule
canonical_url: https://www.clpsplug.com/en/2022/06/23/jekyll-submodule.html
//cover_image: https://direct_url_to_image.jpg
---

## 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
  ```yaml
  source: ["src"]  # The source directory you have created.
  ```  
* Build *the submodule site*
  ```sh
  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*
  ```sh
  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
  ```yaml
  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 another post on how to do this:

{% embed https://dev.to/clpsplug/use-source-jekyll-configuration-to-avoid-deployment-mistake-gec %}



## 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.

```sh
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

{% embed https://jekyllrb.com/docs/configuration/options/ %}

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!

```yaml
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!