I migrated a couple sites to Vercel (previously called Zeit), because they have a point of presence on their CDN in Tokyo where I am (whereas Netlify does not, if you are not paying for “enterprise”), which makes them a bit snappier compared to Netlify for me.
They’re the people who build next.js
, so it’s built with node in mind, but it works well for Hugo, but defaults to building with an old version. I forked Bjørn Erik’s GitHub - bep/hugo-starter-tailwind-basic: A basic and simple to set up Hugo with TailwindCSS starter project. and it worked out of the box on Vercel, as long as I specified the Hugo version, which you can do in two ways:
- make an environment variable in your Vercel dashboard, under the project, in settings - e.g.:
HUGO_VERSION
=0.88.1
. - add a
vercel.json
in the root of your repo, and add this, adjusting the version as needed:
{
"build": {
"env": {
"HUGO_VERSION": "0.88.1"
}
}
}
I like having the vercel.json
because it’s right there and easy to change. The settings environment variable takes precedence, if it exists.
Vercel has a vercel
command which you can install via brew
on Mac, and you run that to initialize a project. It adds a .vercel
folder to specify the account and project id’s, and pushes your project to Vercel, prompting for some various settings. It failed on one of my repo’s saying it could not find git, which I did not suss out. I just went to the Vercel GUI, connected the project to the connected Github project, and then a push to master
/ main
triggered the deploy.
If Vercel autodetects your project is Hugo, it will set a default Hugo build command, but you can override that in project settings. I have a project that uses the sass flavor of Tachyons CSS, which needs a git clone
of the source files before it can build using toCSS
in the head partial.
...
{{ $styles := resources.Get "rc-main.scss" | resources.ExecuteAsTemplate "style.scss" . | toCSS | postCSS | minify | fingerprint }}
<link rel="stylesheet" href="{{ $styles.Permalink }}" integrity="{{ $styles.Data.Integrity }}" />
...
There’s a place to put the build command in your Vercel project settings, and you can set it to “override” and enter the command you want to use. I used something like:
echo "=== prepping for ACME ===" && ls && cd assets && git clone https://github.com/tachyons-css/tachyons-sass && cd .. && echo "=== build it ===" && hugo --gc --minify --ignoreCache --verbose
That took a bit of trial and error, but you can add typical bash-y commands in there separated by the &&
(if the previous succeeds, proceed to the next). The echo commands make the output a little easier to find in the log.
A little aesthetic thing: there’s no native Readme.md status badge you can add like Netlify provides, but this repo generates badges for Vercel projects that look like shields.io ones. For example if your project name in Vercel is acme-inc-site
, then you can add this to the top of your README.md to get a badge:
![Vercel](https://therealsujitk-vercel-badge.vercel.app/?app=acme-inc-site&style=for-the-badge)
Vercel apparently just auto detects and builds your package.json
, which then might use something like postcss.config.js
or tailwind.config.js
. I did not analyze it deeply, but @bep’s repo “just worked”, which was a pleasant surprise.
Vercel creates domains like acme-inc-site.vercel.app
, and you can add your custom ones by adding DNS entries. Just add whatever domain you need, and add the DNS entries that Vercel tells you to (so far, just A or CNAME) into your DNS hosting service. You can forward domains, which you would use if forwarding www
to the apex, and you can link a domain like preview.acme-inc.site
to a git branch like develop
. Then you just do your normal operations, pushing to master / main
or develop
, and it deploys on the expected URL.
A couple more things to note:
- the free / hobby version links to personal github repos only (edit: and are for personal, non-commercial only, per the comment below from @alexandros, thanks)
- the paid version is 20 USD / mo per team-member, and links to github organization repos only
- password protected previews are a 150 USD / month option on the paid version
- check the Vercel docs for how to set response headers for better security on your site - they go in your
vercel.json
.
Hope this might help someone looking to deploy Hugo on Vercel.
Update 20210918
Ok, this is not well tested so take it as a starting point, but you can add the headers in your vercel.json
like so:
{
"build": {
"env": {
"HUGO_VERSION": "0.88.1"
}
},
"headers": [
{
"source": "/(.*)",
"headers":[
{
"key": "Strict-Transport-Security",
"value": "max-age=31536000; includeSubDomains; preload"
},
{
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
},
{
"key": "Referrer-Policy",
"value": "strict-origin"
},
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Powered-By",
"value": "Hugo"
}
]
}
]
}
After deploying, checking the headers in any browser dev tool or via, say, curl -L -I acme-inc.site
shows they are set.
Update 20210919
You can set up Hugo configs to reflect the environment, such as production vs dev (different baseURLs etc), and pass that to the hugo
command:
hugo --gc --minify --ignoreCache --verbose --environment=dev
Hugo will find the config associated with “dev” in your config
folder, and override what’s in _defaults
:
❯ pwd
/Users/myuser/projects/acme-inc-site/config
❯ tree
.
├── _default
│ └── config.toml
├── dev
│ └── config.toml
└── master
└── config.toml
I set up mine to mirror the branches I use in git. If you’re working in a full CLI environment, something like this will work to grab the currently checked out branch:
hugo ... --environment=$(git rev-parse --abbrev-ref HEAD)
But CI VMs have specialized environments that won’t always work exactly as your local one does. Vercel lets you expose its system environment vars to the build environment (in project settings, environment variables), so you can use this. Your build command could take advantage of the fact that Vercel sets the current git branch into VERCEL_GIT_COMMIT_REF
:
echo "=== prepping for ACME ===" && ls && cd assets && git clone https://github.com/tachyons-css/tachyons-sass && cd .. && echo "=== build it ===" && hugo --gc --minify --ignoreCache --verbose --environment==$VERCEL_GIT_COMMIT_REF
This then picks up “master” for production, or “dev” for preview, so that your baseURL and other settings can be correct.