Home Blog How to Deploy a Jekyll Site to Vercel (2026 Guide)
Tutorial

How to Deploy a Jekyll Site to Vercel (2026 Guide)

Deploy Jekyll to Vercel — step-by-step setup, vercel.json configuration, custom domains, environment variables, and the Vercel CLI.

How to Deploy a Jekyll Site to Vercel (2026 Guide)

Vercel is best known as the home of Next.js, but it works equally well for Jekyll sites. Its build infrastructure is fast, the developer experience is polished, and its free tier is generous. If you want a simple Git-connected deploy with a great CLI, Vercel is worth considering.

Why Vercel for Jekyll

  • Automatic Git deploys — push to GitHub, GitLab, or Bitbucket and Vercel deploys automatically
  • Preview URLs for every PR — every pull request gets a unique shareable preview
  • Fast global CDN — Vercel’s Edge Network serves files from locations worldwide
  • Vercel CLI — deploy from your terminal with a single command
  • Free tier — 100GB bandwidth/month, unlimited personal projects
  • Zero config needed — Vercel detects Jekyll automatically

Prerequisites

  • A Jekyll site in a GitHub, GitLab, or Bitbucket repository
  • A Gemfile with your dependencies
  • A Vercel account (free at vercel.com)

Step 1: Prepare your repository

Ensure you have a Gemfile at the project root:

source "https://rubygems.org"

gem "jekyll", "~> 4.3"
gem "jekyll-feed"
gem "jekyll-seo-tag"
gem "jekyll-sitemap"

Run bundle install and commit the lockfile:

bundle install
git add Gemfile Gemfile.lock
git commit -m "Add Gemfile for Vercel"
git push

Step 2: Import your project to Vercel

  1. Go to vercel.com/new
  2. Click Continue with GitHub (or GitLab/Bitbucket) and authorise Vercel
  3. Find your Jekyll repository and click Import
  4. Vercel detects the framework as Jekyll and pre-fills:
    • Framework Preset: Jekyll
    • Build Command: jekyll build
    • Output Directory: _site
    • Install Command: bundle install
  5. Click Deploy

That is it for a basic setup. Vercel runs bundle install then jekyll build and publishes _site/.

Step 3: Create a vercel.json configuration file

For more control, add a vercel.json to your repository root:

{
  "buildCommand": "jekyll build",
  "outputDirectory": "_site",
  "installCommand": "bundle install",
  "framework": "jekyll",
  "env": {
    "JEKYLL_ENV": "production"
  },
  "headers": [
    {
      "source": "/assets/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    },
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        }
      ]
    }
  ],
  "redirects": [
    {
      "source": "/old-post/",
      "destination": "/new-post/",
      "permanent": true
    }
  ],
  "rewrites": [
    {
      "source": "/blog/",
      "destination": "/blog/index.html"
    }
  ],
  "cleanUrls": true,
  "trailingSlash": true
}

Commit this file — Vercel picks it up automatically on the next deploy.

Step 4: Set environment variables

In the Vercel dashboard:

  1. Go to your project → SettingsEnvironment Variables
  2. Add variables for each environment (Production, Preview, Development)

Useful variables for a Jekyll project:

Variable Value Environment
JEKYLL_ENV production Production
JEKYLL_ENV development Preview
RUBY_VERSION 3.2.2 All

Step 5: Add a custom domain

  1. In your Vercel project, go to SettingsDomains
  2. Enter your domain and click Add
  3. Vercel shows the DNS records to add:
    • For the root domain: an A record pointing to 76.76.21.21
    • For www: a CNAME pointing to cname.vercel-dns.com

Add these records at your domain registrar. SSL is provisioned automatically once DNS propagates (usually within minutes).

Configuring redirects in vercel.json

Vercel handles redirects via vercel.json rather than a _redirects file:

{
  "redirects": [
    {
      "source": "/old-url/",
      "destination": "/new-url/",
      "permanent": true
    },
    {
      "source": "/blog/:year/:month/:day/:slug/",
      "destination": "/blog/:slug/",
      "permanent": true
    }
  ]
}

"permanent": true sends a 301 redirect. Use false for a 302.

Deploying with the Vercel CLI

The Vercel CLI is one of the best features for developers who prefer working in the terminal:

npm install -g vercel
vercel login

Deploy a preview:

vercel

Deploy to production:

vercel --prod

Pull environment variables to your local .env:

vercel env pull .env.local

The CLI is particularly useful for testing your production build locally before pushing:

JEKYLL_ENV=production bundle exec jekyll build
vercel --prod --prebuilt

Preview deployments and branch deploys

Every push to a non-production branch creates a preview deployment at a unique URL (https://your-project-abc123.vercel.app). Share this URL with teammates or clients for review before merging.

Configure which branches trigger deployments in SettingsGitIgnored Build Step.

Specifying Ruby version

Vercel uses a default Ruby version for builds. To pin a specific version, create a .ruby-version file in your project root:

3.2.2

Or set it via the RUBY_VERSION environment variable in your Vercel project settings.

Using GitHub Actions with Vercel (advanced)

For complex builds — fetching content from an API, running a pre-build script — use GitHub Actions:


# .github/workflows/deploy.yml
name: Deploy to Vercel

on:
  push:
    branches: [main]

env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: "3.2"
          bundler-cache: true

      - name: Build Jekyll
        run: JEKYLL_ENV=production bundle exec jekyll build

      - name: Install Vercel CLI
        run: npm install -g vercel

      - name: Pull Vercel environment
        run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

      - name: Deploy to Vercel
        run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

Vercel vs Netlify vs Cloudflare Pages for Jekyll

  Vercel Netlify Cloudflare Pages
Free bandwidth 100GB/month 100GB/month Unlimited
Build minutes 6,000/month 300/month Unlimited
Serverless functions Yes Yes Yes (Workers)
Form handling No Yes (built-in) No
CDN locations ~70 ~100 300+
CLI quality Excellent Good Good

Vercel’s free tier includes 6,000 build minutes — significantly more than Netlify’s 300. For teams with frequent deploys, this matters. Cloudflare Pages has truly unlimited builds and the largest CDN, but Vercel’s developer experience and CLI are the smoothest.

Troubleshooting

Build fails with Could not find gem Ensure Gemfile.lock is committed to your repository. Run bundle install locally and push the lockfile.

404 errors on Jekyll pages Add "cleanUrls": true and "trailingSlash": true to vercel.json to handle Jekyll’s URL structure correctly.

Assets return 404 Verify _site/ contains your assets folder. Check that no exclude: entries in _config.yml are accidentally excluding asset directories.

Custom domain SSL warning SSL is provisioned after DNS propagates. Check DNS propagation with dig yourdomain.com A and wait if records are not yet live.

Vercel is a polished, developer-friendly option for Jekyll deployment — especially if you value a great CLI and want generous build minutes on the free tier.

Vercel vs Netlify for Jekyll: which to choose?

Both Vercel and Netlify are excellent hosts for Jekyll sites, and the choice between them often comes down to personal preference and existing tooling. Vercel’s strengths are its polished developer experience, fast global edge network, and generous build minute allowance on the free tier. Netlify’s strengths are its broader feature set for static sites — form handling, identity, A/B split testing, and a mature plugin ecosystem.

For pure Jekyll hosting with no dynamic features, both work equally well. The build process is identical: connect your repository, set bundle exec jekyll build as the build command and _site as the publish directory, and Vercel (or Netlify) handles everything else. Deployment previews, custom domains, automatic SSL, and CDN distribution are standard on both platforms at no cost.

Where Vercel differentiates itself for Jekyll is in the analytics and performance tooling. Vercel Analytics (available on free and paid plans) provides Core Web Vitals data per page, giving you real-user measurement rather than synthetic Lighthouse scores. This is particularly valuable for content-heavy Jekyll blogs where page performance varies significantly between a short post and a long one with many code blocks.

Where Netlify differentiates itself is in form handling — Netlify Forms lets you add a contact form to a static Jekyll site without any backend code, simply by adding a netlify attribute to your HTML form element. For Jekyll sites that need contact forms without a third-party service like Formspree, this is a compelling advantage that Vercel does not match natively.

For most Jekyll deployments, choose whichever platform you are already familiar with or whose dashboard you prefer. Both will serve your site reliably, deploy in under a minute, and scale to handle any realistic traffic volume on the free tier.

Environment variables and build settings on Vercel

Vercel’s project settings provide a clean interface for managing environment variables that differ between environments. Set JEKYLL_ENV=production for your production deployment and use JEKYLL_ENV=preview for preview deployments. In your Jekyll templates, {% if jekyll.environment == 'production' %} conditionally includes analytics, cookie banners, and other production-only elements — keeping your preview deployments clean and your analytics data uncontaminated by test traffic.

The vercel.json configuration file gives you additional control over headers, redirects, and rewrites at the CDN level. Adding cache control headers for static assets directly in vercel.json complements Jekyll’s asset pipeline and ensures that browsers cache CSS, JavaScript, and image files for appropriate durations. A well-configured caching policy is one of the highest-leverage performance optimisations available for a static Jekyll site, and Vercel makes it straightforward to implement.

Vercel Edge Functions for dynamic Jekyll features

Jekyll is static, but Vercel Edge Functions allow you to add server-side logic at the edge layer — code that runs in Vercel’s global network on every request, without a traditional server. Edge Functions use the Web Platform API (Request, Response, Headers) and execute in V8 isolates, making them faster than Lambda functions for latency-sensitive operations.

Practical uses for Edge Functions on a Jekyll site include: personalising content based on the visitor’s country code (show different pricing or language variants), adding authentication-gated pages (redirect to a login page if no session cookie exists), rewriting URLs for clean routing (serve /api/themes.json from a different origin than your Jekyll files), and adding security headers to every response.

An Edge Function that adds security headers is worth implementing on any production Jekyll site. Create a vercel.json with a function configuration that intercepts all responses and adds X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, and a Content-Security-Policy header before the response is sent to the browser. These headers improve your site’s security posture and score on tools like securityheaders.com, which some enterprise clients check when evaluating vendors.

Edge Functions are included in all Vercel plans including the free Hobby tier, and their execution cost is negligible for typical blog traffic. The barrier to using them for Jekyll sites is primarily familiarity — they require JavaScript knowledge and comfort with Vercel’s function file structure. But for the security headers use case, the implementation is a dozen lines and the benefit is immediate.

Monitoring Vercel deployments

Vercel’s deployment dashboard shows real-time logs for every build and runtime function execution. When a Jekyll build fails, the logs show the exact Ruby error — a missing gem, a Liquid syntax error, a front matter YAML issue — making diagnosis fast. Click on any deployment in the dashboard to see its full build log, the commit that triggered it, and the deployment status.

Set up Vercel’s notification integrations to receive a Slack message or email when a deployment fails. Production deployment failures mean your latest content is not live, which is time-sensitive. The notification integration in Vercel’s project settings takes two minutes to configure and ensures you know about failures immediately rather than discovering them hours later when someone asks why the new post is not visible.

Vercel Analytics provides real-user performance data including Web Vitals metrics (LCP, INP, CLS) broken down by page, browser, and country. For a Jekyll blog with varied content length, this per-page breakdown is more useful than a site-wide average — you can identify specific long posts that perform poorly on mobile due to large images or embedded code blocks and optimise them individually.

Custom domains, SSL, and DNS configuration on Vercel

Adding a custom domain to a Vercel project is a three-step process: add the domain in Vercel’s project domains settings, update your domain registrar’s DNS to point to Vercel’s nameservers or add the required A/CNAME records, and wait for DNS propagation (typically 10-30 minutes, sometimes up to 48 hours). Vercel provisions an SSL certificate automatically via Let’s Encrypt once DNS propagates.

For apex domains (example.com rather than www.example.com), Vercel recommends using their nameservers rather than adding individual DNS records, because apex domain CNAME records are not standard and some registrars do not support them. Transferring nameservers to Vercel gives Vercel control over your entire DNS zone, which is convenient for Vercel-specific features but means you manage all DNS through Vercel’s dashboard rather than your registrar.

If you prefer to keep DNS at your registrar, the alternative for apex domains is an ALIAS or ANAME record (supported by Cloudflare, DNSimple, and others) that behaves like a CNAME but is valid at the zone apex. Cloudflare’s proxy mode (the orange cloud) also works well — add Vercel’s IP addresses as A records, enable Cloudflare proxy, and Cloudflare handles both CDN and SSL in front of Vercel’s edge network. This dual-CDN setup adds minimal latency and gives you Cloudflare’s DDoS protection and firewall rules in addition to Vercel’s routing.

Share LinkedIn