HUGO
Menu
GitHub 88836 stars Mastodon

Host on Vercel

Host your project on Vercel.

Use these instructions to enable continuous deployment from a GitHub repository. The same general steps apply for other Git providers such as GitLab or Bitbucket.

Do not commit the contents of the publishDir directory to your repository. Hugo recreates this directory when you build your project.

Prerequisites

Please complete the following tasks before continuing:

  1. Create a Vercel account.
  2. Log in to your Vercel account.
  3. Create a GitHub account.
  4. Log in to your GitHub account.
  5. Create a GitHub repository for your project.
  6. Create a local Git repository for your project with a remote reference to your GitHub repository.
  7. Create a Hugo project within your local Git repository and test it with the hugo server command.
  8. Commit the changes to your local Git repository and push to your GitHub repository.

Procedure

Step 1
Create a vercel.json file in the root of your project.
vercel.json
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "installCommand": "",
  "buildCommand": "chmod a+x build.sh && ./build.sh",
  "outputDirectory": "public"
}
Step 2
Create a build.sh file in the root of your project, adjusting the tool versions and time zone as needed.
build.sh
#!/usr/bin/env bash

#------------------------------------------------------------------------------
# @file
# Builds a Hugo project hosted on Vercel.
#------------------------------------------------------------------------------

# Exit on error, undefined variables, or pipe failures
set -euo pipefail

# Define tool versions
DART_SASS_VERSION=1.101.0
GO_VERSION=1.26.4
HUGO_VERSION=0.163.3
NODE_VERSION=24.16.0

# Set the build time zone
TZ=Europe/Oslo

# Set the build cache directory
HUGO_CACHEDIR="${PWD}/.vercel/cache/hugo"

# Perform cleanup
cleanup() {
  if [[ -n "${build_temp_dir:-}" && -d "${build_temp_dir}" ]]; then
    rm -rf "${build_temp_dir}"
  fi
}

# Register the cleanup trap
trap cleanup EXIT SIGINT SIGTERM

main() {
  # Export the build time zone
  export TZ

  # Export the build cache directory
  export HUGO_CACHEDIR

  # Create a temporary directory for downloads
  build_temp_dir=$(mktemp -d)

  # Create a local tools directory
  mkdir -p "${HOME}/.local"

  # Install Dart Sass
  echo "Installing Dart Sass ${DART_SASS_VERSION}..."
  curl -sfL --output-dir "${build_temp_dir}" -O "https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
  tar -C "${HOME}/.local" -xf "${build_temp_dir}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
  export PATH="${HOME}/.local/dart-sass:${PATH}"

  # Install Go
  if [[ -f "go.mod" ]]; then
    echo "Installing Go ${GO_VERSION}..."
    curl -sfL --output-dir "${build_temp_dir}" -O "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz"
    tar -C "${HOME}/.local" -xf "${build_temp_dir}/go${GO_VERSION}.linux-amd64.tar.gz"
    export PATH="${HOME}/.local/go/bin:${PATH}"
  fi

  # Install Hugo
  echo "Installing Hugo ${HUGO_VERSION}..."
  curl -sfL --output-dir "${build_temp_dir}" -O "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
  mkdir -p "${HOME}/.local/hugo"
  tar -C "${HOME}/.local/hugo" -xf "${build_temp_dir}/hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
  export PATH="${HOME}/.local/hugo:${PATH}"

  # Install Node.js
  if [[ -f "package-lock.json" ]]; then
    echo "Installing Node.js ${NODE_VERSION}..."
    curl -sfL --output-dir "${build_temp_dir}" -O "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz"
    tar -C "${HOME}/.local" -xf "${build_temp_dir}/node-v${NODE_VERSION}-linux-x64.tar.gz"
    export PATH="${HOME}/.local/node-v${NODE_VERSION}-linux-x64/bin:${PATH}"
  fi

  # Log tool versions
  echo "Logging tool versions..."
  command -v sass &> /dev/null && echo "Dart Sass: $(sass --version)" || echo "Dart Sass: not installed"
  command -v go &> /dev/null && echo "Go: $(go version)" || echo "Go: not installed"
  command -v hugo &> /dev/null && echo "Hugo: $(hugo version)" || echo "Hugo: not installed"
  command -v node &> /dev/null && echo "Node.js: $(node --version)" || echo "Node.js: not installed"

  # Configure Git
  echo "Configuring Git..."
  git config --global core.quotepath false

  # Fetch full Git history
  if [[ $(git rev-parse --is-shallow-repository) == true ]]; then
    echo "Fetching full Git history..."
    git fetch --unshallow
  fi

  # Initialize Git submodules
  if [[ -f .gitmodules ]]; then
    echo "Initializing Git submodules..."
    git submodule update --init --recursive
  fi

  # Install Node.js dependencies
  if [[ -f package-lock.json ]]; then
    echo "Installing Node.js dependencies..."
    npm ci
  fi

  # Build the project
  echo "Building the project..."
  hugo build --gc --minify
}

main "$@"
Step 3
In your project configuration, change the location of the image cache to the cacheDir as shown below:
caches:
  images:
    dir: :cacheDir/images
[caches]
  [caches.images]
    dir = ':cacheDir/images'
{
   "caches": {
      "images": {
         "dir": ":cacheDir/images"
      }
   }
}

See configure file caches for more information.

Step 4
Commit the changes to your local Git repository and push to your GitHub repository.
Step 5
In the upper right corner of the Vercel dashboard, press the Add New button and select “Project” from the drop down menu. screen capture
Step 6
Press the “Continue with GitHub” button. screen capture
Step 7
Press the Authorize Vercel button to allow the Vercel application to access your GitHub account. screen capture
Step 8
Press the Install button to install the Vercel application. screen capture
Step 9
Select the GitHub account where you want to install the Vercel application. screen capture
Step 10
Authorize the Vercel application to access all repositories or only select repositories, then press the Install button. screen capture

Your browser will be redirected to the Cloudflare dashboard.

Step 11
Press the Import button to the right of the name of your GitHub repository. screen capture
Step 12
On the “New Project” page, leave the settings at their default values and press the Deploy button. screen capture
Step 13
When the deployment completes, press the **Continue to Dashboard" button at the bottom of the page. screen capture
Step 14
On the “Production Deployment” page, click on the link to your published site. screen capture

In the future, whenever you push a change from your local Git repository, Vercel will rebuild and deploy your site.