How to use a custom Jekyll plugin on Github pages

2 minute read

Image source: Jekyll


GitHub pages use a white list to put the plugins that a user can use: see For example, the version of Jekyll itself that can be used to deploy a GitHub page is 3.9, yet as of the time of writing, Jekyll is already of version 4.2.

If we want to use a custom plugin or a newer version of Jekyll, for example, the Jekyll scholar plugin page to manage .bib files used in my research page,

group :jekyll_plugins do
  gem 'jekyll-scholar'

we need to build the _site locally in a branch other than master or gh-pages, and then sync and merge ONLY the built html files to either of these two branches.

Simple workflow to use a custom plugin on Github pages

This simple workflow follows mostly of Alexandre Rademaker’s guide, with some simplification.


  • We need to have a master branch, and a source branch (any name would do draft, working, etc). master is where GitHub pages are deployed; source is where we work on writing the posts, css, js, etc.
  • _site folder (where the site is built into) should be in the .gitignore.
  • .nojekyll is a file that prevents GitHub pages from showing the _site folder, we need to create it in the master branch. Meanwhile, in the _config.yml of the source branch, under the include key, we need to add - .nojekyll.


Writing things, configuring the sites, commit and push the changes in the source branch. If we want to preview the site locally we use

bundle exec jekyll serve

Whenever we feel the changes are ready to deploy. We build the site using

JEKYLL_ENV=production bundle exec jekyll build

into _site folder. It is important that run a production build as usually the dev build will have code snippets disabling certain features such as Google analytics (for example, google_analytics html has the following condition if jekyll.environment == 'production' checked).

Sync the site to the master

Change to the master branch, copy the files under the _site folder to the root folder (because it is ignored, it gets carried over between branches), add the .nojekyll file (we only need to add this file once, i.e., the second time using touch is unnecessary), and commit and push the changes.

git checkout master
cp -r _site/* . && rm -rf _site/ && touch .nojekyll
git add .
git commit -m "blah blah meaningful message"
git push --all origin

and we are done.

Remark on linking site with an upstream

In another guide by Drew Silcock, the _site folder itself is linked the remote upstream origin/master. Then, we could use an even simpler workflow as pushing to the source is equivalent to pushing to master. However, as of right now, --set-upstream is not working in git anymore.