How to Deploy a Jekyll Site to Netlify (Complete 2026 Guide)
Everything you need to deploy Jekyll to Netlify — netlify.toml setup, build environment, custom domains, redirects, Netlify Forms, and environment variables.
Netlify was the platform that made deploying static sites simple and it remains one of the best choices for Jekyll in 2026. Automatic deploys from Git, preview URLs for every pull request, built-in form handling, serverless functions, and a generous free tier make it a strong option for everything from personal blogs to production sites.
Why Netlify for Jekyll
- Git-based deploys — push to GitHub, GitLab, or Bitbucket and Netlify builds automatically
- Preview deployments — every pull request gets a unique live preview URL
- Netlify Forms — handle contact form submissions without a backend
- Netlify Functions — add serverless API endpoints alongside your static site
- Free tier — 100GB bandwidth/month, 300 build minutes/month, unlimited sites
- Split testing — A/B test different branches of your site
Prerequisites
- A Jekyll site in a GitHub, GitLab, or Bitbucket repository
- A
Gemfileand committedGemfile.lockin your repo - A Netlify account (free at netlify.com)
Step 1: Prepare your repository
Ensure your repository has a Gemfile:
source "https://rubygems.org"
gem "jekyll", "~> 4.3"
gem "jekyll-feed"
gem "jekyll-seo-tag"
gem "jekyll-sitemap"
Generate and commit Gemfile.lock:
bundle install
git add Gemfile.lock
git commit -m "Add Gemfile.lock for Netlify"
git push
Step 2: Create a netlify.toml file
The netlify.toml file in your repository root controls every aspect of your Netlify build. Create it now:
[build]
command = "jekyll build"
publish = "_site"
[build.environment]
JEKYLL_ENV = "production"
RUBY_VERSION = "3.2.2"
# Production context — runs on pushes to main
[context.production]
command = "jekyll build"
# Deploy preview context — runs on pull requests
[context.deploy-preview]
command = "jekyll build --drafts"
# Branch deploy context — runs on other branches
[context.branch-deploy]
command = "jekyll build"
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
Commit this file to your repository.
Step 3: Connect to Netlify
- Go to app.netlify.com and log in
- Click Add new site → Import an existing project
- Choose your Git provider (GitHub, GitLab, or Bitbucket) and authorise Netlify
- Select your Jekyll repository
- Netlify detects
netlify.tomland pre-fills the build settings
Review the settings:
- Build command:
jekyll build - Publish directory:
_site
Click Deploy site. Netlify runs the build and your site is live at a URL like random-name-123456.netlify.app.
Step 4: Configure environment variables
For sensitive values (API keys, Sendy list IDs) that should not be in your repository, add them in the Netlify UI:
- Go to Site configuration → Environment variables → Add a variable
- Add key-value pairs
In your Jekyll code, reference them as normal site.* config values. To inject Netlify environment variables into Jekyll at build time, use _config.yml overrides:
# In netlify.toml — pass env var to Jekyll config
[build]
command = "jekyll build --config _config.yml,_config.production.yml"
Create _config.production.yml to merge at build time:
# _config.production.yml — overrides for Netlify production builds
url: "https://jekyllhub.com"
baseurl: ""
Step 5: Set up a custom domain
Option A: Use a domain already with Netlify DNS
- Go to Domain management → Add a domain → enter your domain
- Netlify provisions SSL automatically
Option B: Use a domain registered elsewhere Add a CNAME record with your domain registrar:
- Name:
www - Value:
your-site.netlify.app
For the root domain (@), use an ANAME or ALIAS record pointing to your-site.netlify.app. Not all registrars support ALIAS — Netlify DNS does, and it is free to use.
Redirects with Netlify
Create a _redirects file in your Jekyll source root:
# Redirect non-www to www (or vice versa — pick one)
https://www.jekyllhub.com/* https://jekyllhub.com/:splat 301!
# Redirect old blog URLs
/2025/:month/:day/:slug/ /blog/:slug/ 301
# Proxy an API endpoint (useful for analytics or forms)
/api/* https://your-api.example.com/:splat 200
# Custom 404
/* /404.html 404
Add to _config.yml so Jekyll copies it to _site/:
include:
- _redirects
Netlify processes _redirects at the CDN level — no server involved.
Using Netlify Forms with Jekyll
Netlify Forms let you collect form submissions without a backend. Add a netlify attribute to any HTML form:
<!-- _includes/contact-form.html -->
<form name="contact" method="POST" data-netlify="true" netlify-honeypot="bot-field">
<input type="hidden" name="form-name" value="contact">
<!-- Honeypot field (hidden) -->
<div style="display:none">
<input name="bot-field">
</div>
<label>Name <input type="text" name="name" required></label>
<label>Email <input type="email" name="email" required></label>
<label>Message <textarea name="message" required></textarea></label>
<button type="submit">Send Message</button>
</form>
Netlify detects the data-netlify="true" attribute during the build and wires up form handling. Submissions appear in Forms in your Netlify dashboard, and you can set up email notifications.
Build minutes and the free tier
Netlify’s free tier includes 300 build minutes per month. A typical Jekyll build takes 30–60 seconds, so you have roughly 300–600 deploys per month before any charges.
To reduce build time, add caching to netlify.toml:
[build]
command = "jekyll build"
publish = "_site"
[build.environment]
BUNDLE_PATH = "vendor/bundle"
JEKYLL_ENV = "production"
The BUNDLE_PATH = "vendor/bundle" setting caches your Ruby gems between builds — cutting build time from ~60 seconds to ~10 seconds after the first build.
Deploy with the Netlify CLI
For local testing or CI deployments:
npm install -g netlify-cli
netlify login
netlify deploy --dir=_site --prod
The --prod flag deploys to production. Without it, Netlify creates a draft preview URL.
Useful Netlify features for Jekyll sites
Branch deploys: Any branch pushed to GitHub can have its own Netlify URL. Enable in Site configuration → Build & deploy → Branch deploys.
Deploy notifications: Get a Slack or email notification when deploys succeed or fail. Set up in Site configuration → Build & deploy → Deploy notifications.
Analytics: Netlify Analytics (paid, $9/month) gives server-side analytics with no JavaScript required — accurate data that ad blockers cannot hide.
Large Media: Store large image files in Git LFS and serve them via Netlify’s CDN — keeps your repository size manageable.
Troubleshooting
Bundler::GemNotFound during build
Commit Gemfile.lock and ensure the Ruby version in netlify.toml matches your local environment.
Build succeeds but styles are missing
Check url and baseurl in _config.yml. For a root-domain Netlify site, baseurl should be empty ("").
Form submissions not appearing
Ensure data-netlify="true" is on the <form> tag and the hidden form-name input matches the form’s name attribute. Jekyll must build the page (not exclude it) for Netlify to detect the form.
Redirect loops
Avoid redirecting both www → non-www and non-www → www. Pick one canonical form and redirect only from the other.
Netlify’s balance of simplicity, features, and a generous free tier makes it one of the top choices for Jekyll hosting. The netlify.toml file gives you reproducible, version-controlled build configuration — the same way your Jekyll config works.