Making DRY work with GitLab pages and review apps

This is a common problem I run into with review apps and pages, and I wondered whether anyone has a neat solution for it.

I have a pipeline with stages that include build and deploy, and if the pipeline is running in a feature branch, the build job will look like this:

.rules-review: &rules-review
    rules:
        - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
          when: never
        - when: on_success

.build: &build
    stage: build
    script:
        - ...
    artifacts:
        paths:
            - site

build:review:
    <<: *build
    <<: *rules-review
    environment:
        name: &env-name-review review/$CI_COMMIT_REF_NAME
        action: prepare
        url: &env-url-review "https://GROUP.gitlab.io/-/$CI_PROJECT_NAME/-/jobs/$CI_JOB_ID/artifacts/public/index.html"

I don’t want to build the site twice, so the deploy job will look like this:

.deploy: &deploy
    stage: deploy
    script:
        - mv site public
    artifacts:
        paths:
            - public

deploy:review:
    <<: *deploy
    <<: *rules-review
    environment:
        name: *env-name-review
        url: *env-url-review
        auto_stop_in: 2 weeks

However, build:review and deploy:review will have different values for $CI_JOB_ID, so the base URL for the site will be wrong, and hyperlinks in the review app will go to 404s.

Is there a trick I’m missing here?