Jamstack & Gitlab Pages

Deploy a Next.js project (SSG) on Gitlab Pages

J Paul Lescouzères
3 min readFeb 16, 2021

The development of static site generators (SSG) has greatly strengthened in recent years, with the promise of more efficient, safer and easier to host websites. A simple CDN may suffice, which then simplifies even more the publication of your project on the web.

Gitlab provides free static hosting for each code repository. So why not take the opportunity to host our Jamstack project?

Based on a Next.js project, we will see how to configure the Gitlab CI/CD, thanks to the .gitlab-ci.yml file and some tweaks, to deploy directly to Gitlab Pages!

Prerequisites

  1. Node.js (>= 10.13)
  2. A Gitlab account 😲

A demonstration project has been created for this article, so do not hesitate to refer to it for more details (scripts, …)!

Project creation

Next.js allows us to quickly create a new project, thanks to the following commands:

npx create-next-app
# or
yarn create next-app

The site’s documentation is pretty comprehensive, and their Github repository is full of information and examples.

Project configuration

Gitlab Pages offers by default specific urls for each type of page:

  1. If it’s a user or group page (repository name is <username|groupname>.gitlab.io), then the site url will be https://<username|groupname>.gitlab.io/
  2. If it’s a project page (from a user or a group), then the site url will be https://<username|groupname>.gitlab.io/<projectname>/

Next.js (like all SSG) is not aware of this specificity, so it may be necessary to indicate the domain in which it is located, so that the links of exported assets (in the _next folder) are not broken. 💔

So in the case of a project page, you’ll simply have to specify the domain name as value of the parameter assetPrefix:

const isProd = process.env.NODE_ENV === 'production'module.exports = {
assetPrefix: isProd ? '/<projectname>/' : ''
}

Note that to preserve our links in the local environment (development), we will use the Node environment variable to define this parameter more specifically.

The Gitlab file

Gitlab Pages automatically activates in presence of a .gitlab-ci.yml file with a pages entry.

In addition to this configuration file, you will also have to ensure the visibility of the site in the repository parameters (in Parameters > General > Visibility).

And finally here is the file:

image: nodecache:
paths:
- node_modules/
pages:
before_script:
# Clean public folder
- find public -mindepth 1 -maxdepth 1 -type d | xargs rm -rf
- find public -type f -name "*.html" | xargs rm -rf
# Install packages
- npm install
script:
# Build application and move content to public folder
- npm run publish
- mv out/* public
after_script:
# Cleanup
- rm -rf out
artifacts:
paths:
- public
only:
- master

The particularity of this deployment lies in the constraints of Gitlab Pages and Next.js: the first one accepts for only entry point a public folder ... which is also a reserved folder for the second one, and therefore in which we cannot do our exports! 🤯

The solution proposed here is to split our script into three phases:

  1. We make sure that the public folder is cleaned of all residual files and/or folders (otherwise Next.js will refuse to export the project)
  2. We compile and export our project as static pages, before moving the generated content to the public folder (available to Gitlab)
  3. Once these two steps completed, we delete the Next.js export folder (by default out)

🎉

Et voilà ! Despite a little gymnastics imposed by the respective constraints of Gitlab Pages and Next.js, the file remains simple and readable! 💪 We are now free to publish our content quickly, without having to worry about an additional and unnecessary service! 🙂

This article was originally published (in french & english) on my blog.

--

--