Jekyll Favicon Complete Guide

Master favicon setup in Jekyll: includes folder, config.yml, Liquid templates, and best practices for Ruby-based static site generator.

Jekyll Favicon Setup (3 Steps)

1. Root Folder

Place in site root

2. Create Include

_includes/favicon.html

3. Include in Head

Add to layout

Step 1: File Structure

Jekyll Directory Layout

my-jekyll-site/
  favicon.ico               ? Place in root
  favicon-16x16.png
  favicon-32x32.png
  apple-touch-icon.png
  android-chrome-192x192.png
  android-chrome-512x512.png
  site.webmanifest
  _includes/
    favicon.html            ? Create this
    head.html
  _layouts/
    default.html
  _config.yml
  index.md
Note: Files in the root directory are copied to _site/ during build. Accessible at /favicon.ico

Step 2: Create Favicon Include

_includes/favicon.html

Basic Favicon Include

<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="{{ site.baseurl }}/favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="{{ site.baseurl }}/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="{{ site.baseurl }}/favicon-16x16.png">
<link rel="apple-touch-icon" sizes="180x180" href="{{ site.baseurl }}/apple-touch-icon.png">
<link rel="manifest" href="{{ site.baseurl }}/site.webmanifest">
<meta name="theme-color" content="#ffffff">

Advanced Include with Config Variables

{% assign favicon_path = site.favicon_path | default: "/" %}

<!-- Standard favicons -->
<link rel="icon" type="image/x-icon" href="{{ favicon_path }}favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="{{ favicon_path }}favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="{{ favicon_path }}favicon-16x16.png">

<!-- Apple Touch Icon -->
<link rel="apple-touch-icon" sizes="180x180" href="{{ favicon_path }}apple-touch-icon.png">

<!-- Android/Chrome -->
<link rel="icon" type="image/png" sizes="192x192" href="{{ favicon_path }}android-chrome-192x192.png">
<link rel="icon" type="image/png" sizes="512x512" href="{{ favicon_path }}android-chrome-512x512.png">

<!-- Web App Manifest -->
<link rel="manifest" href="{{ favicon_path }}site.webmanifest">

<!-- Theme Color -->
<meta name="theme-color" content="{{ site.theme_color | default: '#ffffff' }}">

{% if site.safari_pinned_tab %}
<link rel="mask-icon" href="{{ favicon_path }}pinned-tab.svg" color="{{ site.safari_pinned_tab_color | default: '#5bbad5' }}">
{% endif %}

{% if site.ms_tile_color %}
<meta name="msapplication-TileColor" content="{{ site.ms_tile_color }}">
<meta name="msapplication-TileImage" content="{{ favicon_path }}ms-icon-144x144.png">
{% endif %}

_config.yml Settings

# Favicon configuration
favicon_path: "/"
theme_color: "#CC0000"
safari_pinned_tab: true
safari_pinned_tab_color: "#CC0000"
ms_tile_color: "#CC0000"

Step 3: Include in Layout

_layouts/default.html

<!DOCTYPE html>
<html lang="{{ site.lang | default: 'en-US' }}">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>{{ page.title }} | {{ site.title }}</title>
    
    {% include favicon.html %}
    
    <!-- Other head elements -->
  </head>
  <body>
    {{ content }}
  </body>
</html>
Done! The {% include favicon.html %} line includes your favicon on every page.

GitHub Pages Deployment

Special Considerations

baseurl Configuration

If deploying to GitHub Pages with a project name (e.g., username.github.io/project):

# _config.yml
url: "https://username.github.io"
baseurl: "/project"  # Project name

# Use in favicon.html:
<link rel="icon" href="{{ site.baseurl }}/favicon.ico">

Build & Deploy Commands

# Local development
bundle exec jekyll serve
# Test at http://localhost:4000

# Build for GitHub Pages
JEKYLL_ENV=production bundle exec jekyll build

# Files output to _site/ folder

GitHub Actions Workflow

# .github/workflows/jekyll.yml
name: Deploy Jekyll site to Pages

on:
  push:
    branches: ["main"]

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.1'
          bundler-cache: true
      - run: bundle exec jekyll build
      - uses: actions/upload-pages-artifact@v1

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/deploy-pages@v1
        id: deployment

Advanced Jekyll Features

Conditional & Dynamic Favicons

Environment-Specific Favicons

{% if jekyll.environment == "production" %}
  <link rel="icon" href="/favicon.ico">
{% else %}
  <link rel="icon" href="/favicon-dev.ico">
{% endif %}

Per-Page Favicon Override

Page front matter:

---
title: "Custom Page"
favicon: "/custom-favicon.ico"
---

Include template:

{% assign favicon = page.favicon | default: "/favicon.ico" %}
<link rel="icon" href="{{ favicon }}">

Jekyll Favicon Best Practices

? Best Practices

  • Place favicons in site root directory
  • Create reusable include file
  • Use site.baseurl for paths
  • Configure in _config.yml
  • Test with jekyll serve
  • Verify _site/ output folder
  • Use Liquid variables for flexibility
  • Test on GitHub Pages before deploy

? Common Mistakes

  • Placing favicons in _includes/ or assets/
  • Forgetting site.baseurl for subpaths
  • Not testing production build locally
  • Missing favicon.html include
  • Wrong paths in GitHub Pages deploy
  • Not clearing _site/ before rebuild
  • Hardcoding paths instead of config
  • Not testing on actual GitHub Pages URL

Generate Jekyll-Ready Favicons

Create optimized favicon packages for Jekyll static sites

Generate Favicons

Related Articles

An unhandled error has occurred. Reload 🗙