Skip to content

Deploy a Single Page Application

This how-to guide shows you how to deploy your Single Page Application (SPA) to the CDN and NAIS without building and deploying a Docker image.

Prerequisites

  • A NAIS team.
  • A GitHub repository that the team has access to.
  • The application must build and package as a folder with an index.html, and its other static files.

Limitations

  • Versioning is not supported
  • Clean-up of old static files are not supported
  • Changing of app name is not supported

Deploy with the SPA action

name: Deploy SPA

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    permissions:
      contents: 'read'
      id-token: 'write'

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run build
      - uses: nais/deploy/actions/spa-deploy/v2@master
        with:
          app: my-frontend
          team: <team slug> # Required, e.g. "team-name"
          ingress: https://team.nav.no/my-frontend
          source: <The path to your build folder or assets>
          environment: dev
          identity_provider: ${{ secrets.NAIS_WORKLOAD_IDENTITY_PROVIDER }} # Provided as Organization Secret
          project_id: ${{ vars.NAIS_MANAGEMENT_PROJECT_ID }} # Provided as Organization Variable

For more information on the inputs and outputs of the action, see the SPA deploy action reference.

The different values for env can be found under Environments.

Static files will be uploaded with the following CDN address:

https://cdn.nav.no/<team>/<app>/<env>/

Multiple ingresses

If you want your app exposed on multiple ingresses you can use a comma separated list in the ingress field:

- uses: nais/deploy/actions/spa-deploy/v2@master
  with:
    ...
    ingress: https://team.nav.no/my-frontend, https://team.nav.no/my-other-ingress

Custom ingress

If you have your own domain that you want to host your SPA on, you need to supply the action with ingressClass and set the environment-field to the cluster you want to deploy to.

- uses: nais/deploy/actions/spa-deploy/v2@master
  with:
    ...
    ingress: https://your-domain.no
    ingressClass: nais-ingress-external # Internal addresses should use "nais-ingress"
    environment: <env> # e.g. "prod-gcp"

App configuration

Create React App

To get the correct link in the static files generated by your Create React App you need to set the PUBLIC_URL variable. This can be done in one of two ways:

  • Either in a .env file:
PUBLIC_URL=https://cdn.nav.no/<team>/<app>/<env>/
  • Or with an env in your GitHub Actions when you run npm run build:
steps:
  - run: npm run build
    env:
      PUBLIC_URL=https://cdn.nav.no/<team>/<app>/<env>/

Next.js

You need to run next export and set assetPrefix in next.config.js when building a static Next.js application:

const isProd = process.env.NODE_ENV === 'production'

module.exports = {
  // Use the CDN in production and localhost for development.
  assetPrefix: isProd ? 'https://cdn.nav.no/<team>/<app>/<env>/' : undefined,
}