Jamstack & Gitlab Pages

Publié il y a plus d’un an~3 min

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:

1npx create-next-app
2# ou
3yarn 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:

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

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:

1image: node
2
3before_script:
4 - npm install
5
6cache:
7 paths:
8 - node_modules
9
10pages:
11 before_script:
12 # Clean public folder
13 - find public -mindepth 1 -maxdepth 1 -type d | xargs rm -rf
14 - find public -type f -name "*.html" | xargs rm -rf
15 script:
16 # Build application and move content to public folder
17 - npm run publish # Eq. to 'next build && next export'
18 - mv out/* public
19 after_script:
20 # Cleanup
21 - rm -rf out
22 artifacts:
23 paths:
24 - public
25 only:
26 - 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! 🙂