Publish multiple projects on a Monorepo on Cloudflare Pages

Emmanuel Gautier / June 29, 2022

3 min read

All the tooling provided by service providers is great and makes the developer's life much easier. Usually, those providers connect one git repository to an application (or a project depending on the provider naming). It works fine but it is not so easy when you work on a monorepo or if you want to make multiple deployments for more than one locale from only one source code.

This is the case for Cloudflare Pages. For now, you can not connect one Github repository to multiple Cloudflare Pages projects. In my case, this blog is available in English and French and linked to two domain names. So I have to make two deployments from the same source code. Hopefully, there are solutions.

Direct Upload with Continous integration

The first solution is to deploy with Direct Uploads, a way to upload files directly to Cloudflare without having to build on Cloudflare build environment. One month ago, Cloudflare announced that the deployment on Cloudflare Pages with Direct Uploads is available. So, it is now possible to build multiple versions of a website and make multiple uploads for each project.

Here I am using it for one project having multiple Cloudflare Pages projects. This solution can be used the same way when you have multiple packages on monorepo and you want to publish the different websites on Cloudflare Pages.

Getting started with Direct Uploads

The publishing can be done with the Wrangler CLI developed by Cloudflare with the command npx wrangler pages publish <directory>. That is pretty simple, isn't it?

The build and publish should be delegated to a software responsible for CI/CD like Github Actions or Travis CI. Cloudflare provided some support for some of them. Check out the Cloudflare Documentation for more informations. If you use software not mentioned in this documentation like Jenkins, you still can use the wrangler command directly which will make the same action at the end as using existing tooling.

Here you can find one Github Actions workflow example deploying one project on different Cloudflare Pages projects and using the cloudflare/pages-action action.

name: Publish

      - main

    runs-on: ubuntu-latest

      contents: read
      deployments: write

          - projectName: 'project-en'
            googleAnalyticsId: 'G-XXXXXXXXXX'
          - projectName: 'project-fr'
            googleAnalyticsId: 'G-XXXXXXXXXX'

      - name: Checkout 🛎
        uses: actions/checkout@v3

      - name: Setup node env 🏗
        uses: actions/setup-node@v3
          node-version: lts/gallium
          cache: 'yarn'

      - name: Install dependencies 👨🏻‍💻
        run: yarn --frozen-lockfile --silent

      - name: Run build
        run: yarn build
          NEXT_PUBLIC_GA_ID: ${{ matrix.googleAnalyticsId }}

      - name: Export
        run: yarn export
          NEXT_PUBLIC_GA_ID: ${{ matrix.googleAnalyticsId }}

      - name: Publish
        uses: cloudflare/pages-action@1
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          projectName: ${{ matrix.projectName }}
          directory: ./out
          gitHubToken: ${{ secrets.GITHUB_TOKEN }}

Mirroring GIT Repository

Another solution that can be used as a workaround to the limitation of having only one project per GIT repository is to create multiple GIT repositories. It can be quite painful to maintain multiple repositories so it is possible to configure automatic synchronization. You can find one example with Github Actions on the Github Action for mirroring repositories snippet.

This solution can be used not only for Cloudflare but also with Vercel.


If you're seeking solutions to a problem or need expert advice, I'm here to help! Don't hesitate to book a call with me for a consulting session. Let's discuss your situation and find the best solution together.

Share this post
Follow the RSS feed

Subscribe to the newsletter

Get the latest news about tech new articles and projects.