Creating a Static Site with Jekyll and Tailwind CSS
Your mission, should you choose to accept it, is to create a blog / static site using Jekyll, with Tailwind CSS to style it, and host it on Cloudflare Pages.
Well, I guess we won’t have to call Ethan Hunt to handle this, it should be doable by anyone, following this step-by-step tutorial.
First, we need a working ruby environment
Maybe the easiest way is to install rbenv. There are detailed instructions on the linked page for various operating systems. Then you need to install your preferred (if you don’t have one, choose the latest stable) version of ruby.
To list the latest stable versions:
From this list we can see that the latest version of the official interpreter is 3.1.2 at the time of writing this post, so we can install it with
Next, we install Jekyll
The above command set up the RubyGems package manager as well, and we’ll use that to install Jekyll and bundler, the gem dependency manager. Yep, it’s managers all the way down.
After this step, we have a working, although bare-bones Jekyll installation.
Creating a new site
We could use the
command to create a site that has a basic theme, a sample post, and other defaults included. Jekyll will create a subfolder with the site’s name (in this case my_blog
) in the current directory to contain the site’s data. If you don’t plan to tinker with the setup and just want to hit the ground running, this could be your way.
Instead of this simple path, we’ll choose the slightly more involved one, and we’ll use the
command, which copies the bare minimum to the site’s folder, letting us do the rest.
Let’s check out the contents of the folder that Jekyll created.
There is a detailed description of each folder/file in the docs. Before starting with the configuration, we should create a git repository to track the changes to our site. We’ll add a .gitignore
file with the following content to skip the files/folders we don’t want to track:
Then, we create the repository and check in the current state of the site.
With the --blank
option Jekyll didn’t create a Gemfile
, so we’ll create it ourselves. For now, we’ll add the jekyll
gem to it, as well as the webrick
gem, since we are using Ruby 3.0.0+.
We can check the current state of the site by running
and pointing our browser to http://127.0.0.1:4000/.
Adding Tailwind
Since we’ll use Tailwind CSS for styling, we’ll set it up now. We’ll need node and npm. Similarly to ruby above, it’s practical to use a version manager, in Node’s case, nvm. It’ll make juggling different Node versions much easier. Installation instructions are on the linked nvm page.
For Tailwind, we’ll install five npm packages:
- tailwindcss, the framework itself
- @tailwindcss/typography: typography plugin for Tailwind
- postcss, so we can transform the CSS with Javascript
- autoprefixer, to add vendor prefixes to the CSS rules
- cssnano, to optimize the CSS for production
We’ll also use the jekyll-postcss gem to integrate postcss to the Jekyll workflow. Add the following line to Gemfile
:
Then, add these lines to _config.yml
:
The first part adds the gem as a plugin to the Jekyll build system, the second part disables caching of the generated CSS. This part is needed because Tailwind’s just-in-time compiler will regenerate the CSS every time any of the HTML sources is modified.
Next, we’ll configure postcss, so create a file named postcss.config.js
, with this content:
This will add three previously installed plugins to postcss. cssnano will only be added if we specified the production
environment for Jekyll, since that’s the only case when we need to optimize the generated CSS.
We’ll also need to configure Tailwind itself, with a file named tailwind.config.js
, the contents should be this:
What you should put in content
varies depending on your site structure, and where your .html and .md files will be. By default, Jekyll stores drafts in the _drafts
folder and finished posts in the _posts
folder, but you can devise any structure you like, and then you should simply update the lines in the content array.
My site will have a dark mode toggle, so I also added a line that tells Tailwind that dark mode is toggled by a class and not set by OS preference.
Since the vast majority of our CSS will be written as Tailwind classes in the HTML files, we won’t use the Sass CSS preprocessor integrated with Jekyll. So we’ll remove the _sass
folder and rename the assets/css/main.scss
file to assets/css/main.css
, replacing its content with this:
The two triple-dashed lines (front matter) need to be added so Jekyll will process the file. Then we simply add the directives for each tailwind layer.
What remains is to add a link to the generated CSS to our layout:
Whew! That’s all it took to add Tailwind to our site.
Useful Jekyll plugins
You can find tons of useful Jekyll plugins on the Awesome Jekyll Plugins list. These are the ones that I currently use:
- jekyll-sitemap: generates a sitemap for your site
- jekyll-seo-tag: add metadata tags for search engines and social networks to better index and display your site’s content
- jekyll-feed: generates an Atom feed of posts
- jekyll-archives: Automatically generate post archives by dates, tags, and categories. I have a separate post about setting it up
- jekyll-compose: Streamline your writing in Jekyll with some commands
- reading_time: to estimate how long the note will take to read
Things you’ll also need
A favicon is, while not strictly necessary, nice to have. There are many online favicon generators, like https://favicon.io/, if you don’t have one already. They even have code snippets to include in your HTML.
In case someone tries to visit an invalid URL of the site, they’ll get an unfriendly message about the page not being available. To fix this, we’ll need a proper 404 page. Since we’ll host the site on Cloudflare, we’ll need to place a 404.html page at the root of the site, mine simply redirects to the notes archive (/notes).
We’ll wrap up the first part here. We have a functioning site, but it’s without any styling at the moment. I have a post about layouts here. We also don’t have it online yet, but we can test the functionality locally. I wrote a separate post about hosting our static site on Cloudflare Pages.
Thanks for reading! If you have any comments, additions, or corrections, feel free to reach me via e-mail.