As it turns out, adding support to render LaTeX in a Jekyll blog isn’t all that hard, because other people have done most of the heavy lifting. There are two main ways to do this:

• Client-side rendering: After the page loads, a JS script is run to transform LaTeXy parts of the page to lovely, styled HTML.
• Build-time rendering: After Markdown files are compiled to HTML, a Jekyll plugin further transforms those LaTeXy parts to HTML as well. Here’s how you do either using $\KaTeX$.

# Client-Side $\KaTeX$

Inside of your HTML <head> tag, usually in _layouts/default.html for Jekyll blogs, add the following to conditionally load stylesheets and scripts.

{% if page.katex %}

<!-- CSS -->

<!-- JavaScript -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@latest/dist/contrib/auto-render.min.js"
delimiters: [
{ left: '$$', right: '$$',  display: true  },
{ left: '$', right: '$',   display: false },
{ left: '\$', right: '\$', display: true  },
{ left: '\$$', right: '\$$', display: false }
]});">
</script>

{% endif %}


This uses jsDelivr as the CDN to deliver the styles and scripts; replace latest in the URLs if you want to stick to a specific version. It uses KaTeX’s auto-render extension to render everything within the specified delimiters. display: true is equivalent to a displaymath environment, while display: false is equivalent to an inline math environment. Their documentation has a few more options you can set, like which tags and classes to ignore during processing.

To use LaTeX in a post, add katex: true to the front matter, and write your LaTeX within the specified delimiters. For instance, the body of the following:

---
layout: post
katex: true
---

This is an example of inline \$$\LaTeX\$$. The following is Stokes' theorem in a
displaymath environment: \$$\int_{\partial \Omega} \omega = \int_{\Omega} d\omega\$$


is displayed as below:

This is an example of inline $\LaTeX$. The following is Stokes’ theorem in a displaymath environment:
$\int_{\partial \Omega} \omega = \int_{\Omega} d\omega$

# GitHub Pages $\rightarrow$ GitLab Pages

Build-time rendering doesn’t work for GitHub Pages since they have a fixed set of Jekyll plugins. On the other hand, it will work for GitLab Pages, since the site generation is part of a CI pipeline. To port to GitLab, add the following to .gitlab-ci.yml.

image: ruby:2.7

pages:
script:
- apt-get update && apt-get -y install nodejs
- gem install bundler
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public


If you use Ruby 3 instead, you will need to add webrick to your Gemfile (see issue #8523 for the Jekyll repo).

group :jekyll_plugins do
gem "webrick"
gem "github-pages"
gem "jekyll-katex"
end