---
slug: "how-to-deploy-project-to-vercel-includes-private-submodules"
title: "How to Deploy a Project with Private Git Submodules to Vercel"
description: "During the build process on Vercel, it is not possible to retrieve submodules that are in a private repository. It is necessary to use a fine-grained personal access token to retrieve them via HTTP."
url: "https://www.ytyng.com/en/blog/how-to-deploy-project-to-vercel-includes-private-submodules"
publish_date: "2024-05-26T15:38:40Z"
created: "2024-05-26T15:38:40Z"
updated: "2026-04-12T07:44:06.409Z"
categories: []
keywords: ""
featured_image_url: "https://media.ytyng.com/resize/20250611/8fcbaed531cd44eeb4dfe1dc24aaa10a.png.webp?width=768"
has_video: true
has_music: true
video_urls: ["https://media.ytyng.net/ytyng-blog/307/featured-video-1.mp4", "https://media.ytyng.net/ytyng-blog/307/featured-video-2.mp4", "https://media.ytyng.net/ytyng-blog/307/featured-video-3.mp4"]
music_urls: ["https://media.ytyng.net/ytyng-blog/307/featured-music-307-1.mp3", "https://media.ytyng.net/ytyng-blog/307/featured-music-307-3.mp3"]
lang: "en"
---

# How to Deploy a Project with Private Git Submodules to Vercel

When building with Vercel, you cannot retrieve submodules that are set as private repositories.

Even if you grant permissions to the Vercel app on Github, it won't work.

You need to retrieve them using an HTTP fine-grained personal access token.

## 1. Create a fine-grained personal access token

Go to the following page: https://github.com/settings/tokens?type=beta

Click on "Generate new token."

![Image](https://media.ytyng.com/20240526/0a228df2565f4ac1817d0929eec86427.png)

For Repository access, select "Only select repositories" and choose the minimum necessary repositories.

For Repository permissions, grant Read-only access to Contents only.

![Image](https://media.ytyng.com/20240526/6693893421ac4859b01d28814dbfd622.png)

Click the "Generate token" button to create the token.

## 2. Register the token as an environment variable in Vercel

Register it in the Settings → Environment Variables section of your Vercel project. I registered it under the name GITHUB_PAT.

![Image](https://media.ytyng.com/20240526/0d26432e112a457eb11379b82e889997.png)

## 3. Create a build script

Create a file named `sh/build-for-vercel.sh`.

### Recommended: Using GIT_ASKPASS

Embedding tokens directly in URLs poses a security risk, so using `GIT_ASKPASS` is the recommended approach.

`GIT_ASKPASS` is an environment variable that specifies a script to be automatically executed when git needs authentication credentials. It is safe because the token is not stored in the URL or git config.

```shell
#!/usr/bin/env bash

cd $(dirname $0)/../ || exit

set -e

if [ -z "${GITHUB_PAT}" ]; then
  echo "The environment variable GITHUB_PAT is not set. Please regenerate the GitHub Fine-grained token and register it as the GITHUB_PAT environment variable in Vercel."
  echo "https://github.com/settings/tokens?type=beta"
  exit 1
fi

# Pass token via GIT_ASKPASS (no token in URLs)
ASKPASS_SCRIPT="$(mktemp)"
trap 'rm -f "${ASKPASS_SCRIPT}"' EXIT
cat > "${ASKPASS_SCRIPT}" <<'SCRIPT'
#!/usr/bin/env bash
case "$1" in
  *Username*) echo "x-access-token" ;;
  *Password*) echo "${GITHUB_PAT}" ;;
  *) echo ;;
esac
SCRIPT
chmod 700 "${ASKPASS_SCRIPT}"
export GIT_ASKPASS="${ASKPASS_SCRIPT}"
export GIT_TERMINAL_PROMPT=0

git submodule set-url <my-submodule> "https://github.com/ytyng/<my-submodule>.git"
git submodule sync
git submodule update --init

# Your original build script
npm run generate
```

Key points:
- The temporary script specified by `GIT_ASKPASS` automatically provides the token when git requests authentication
- `trap` automatically deletes the temporary script after the build completes
- The token is not included in the submodule URL, so it never persists in git config
- `GIT_TERMINAL_PROMPT=0` disables interactive prompts

### Previous method (not recommended)

The following method embeds the token directly in the URL. It works but has security risks, so the GIT_ASKPASS method above is recommended.

```shell
#!/usr/bin/env bash

cd $(dirname $0)/../ || exit

if [ -z "${GITHUB_PAT}" ]; then
  echo "The environment variable GITHUB_PAT is not set. Please regenerate the Vercel submodule token on Github and register it as the GITHUB_PAT environment variable in Vercel."
  echo "https://github.com/settings/tokens?type=beta"
  echo "https://vercel.com/<my-own-projects>/<project-name>/settings/environment-variables"
  exit 1
fi

git submodule set-url <my-submodule> "https://${GITHUB_PAT}@github.com/ytyng/<my-submodule>.git"

git submodule sync
git submodule update --init

# The original build script
npm run generate
```

## 4. Write the vercel.json

Since this is for generating static content with Nuxt, it will look like this:

```
{
  "buildCommand": "sh/build-for-vercel.sh",
  "outputDirectory": ".output/public"
}
```

# Note

At the beginning of the build, you will inevitably see the warning:
```
Warning: Failed to fetch one or more git submodules
```
but you can ignore it.

![Image](https://media.ytyng.com/20240526/641ef9a05fb44fca8cbb7b81daf0f9be.png)

# Additional Information

You can also make it work by re-cloning instead of updating the submodule.

```
rm -r <my-submodule>
git clone --depth 1 --branch main "https://${GITHUB_PAT}@github.com/ytyng/<my-submodule>.git" <my-submodule>
```

