Mastering Monorepo Deployments to GitHub Pages: Angular & Astro for Enhanced Developer Productivity

Illustration of a monorepo deploying Angular and Astro sites to GitHub Pages at different paths.
Illustration of a monorepo deploying Angular and Astro sites to GitHub Pages at different paths.

The Monorepo Deployment Challenge: Angular & Astro on GitHub Pages

One common challenge that can impact software project metrics and overall team efficiency is the deployment of multiple static sites from a single monorepo to platforms like GitHub Pages. Developers often aim for a streamlined workflow where different applications, perhaps built with varying frameworks, can coexist under a single custom domain, each accessible at a specific path. This insight explores a real-world scenario and its solution, offering valuable lessons for anyone tackling similar deployment complexities.

A developer, binder-badge, faced this exact problem: deploying an Angular site to the root (/) and an Astro Starlight documentation site to a subpath (/wiki) from a .github.io monorepo. Despite configuring a GitHub Actions workflow to build both projects and consolidate their outputs, both domain.com/ and domain.com/wiki were returning 404 errors.

The Root Cause of 404s

The core issue stemmed from how GitHub Pages serves content and the default build outputs of the frameworks:

  • GitHub Pages' Serving Mechanism: GitHub Pages serves content exclusively from the root of the uploaded artifact. If your Angular site's index.html is buried in dist/portfolio/browser/, GitHub Pages won't find it at the root.
  • Angular's Output Structure: Angular's build typically places the main static assets within a browser/ subdirectory inside its dist folder.
  • Astro's Base Path: Astro, by default, generates asset URLs relative to the root (/). Even if its files are placed under /wiki, its internal links and asset references might still point to /, causing broken links and 404s for resources.

The Working Solution: Step-by-Step

Community members quickly identified and helped refine a robust solution. Here’s a breakdown of the steps to achieve successful deployment:

1. Configure Astro's Base Path

The Astro site needs to be explicitly told its base URL. Edit wiki/astro.config.mjs to include the site and base properties:

import { defineConfig } from 'astro/config';

export default defineConfig({
  site: 'https://domain.com', // Replace with your actual domain
  base: '/wiki/',
});

This ensures Astro generates correct asset paths and routing for content served under /wiki/.

2. Build Both Projects

Build both your Angular and Astro projects. For Angular, ensure the base-href is set correctly for the root path:

# Angular
npm run build -- --configuration production --base-href "/"

# Astro
npm run build

3. Consolidate into the Correct Directory Structure

This is the most critical step. The final artifact uploaded to GitHub Pages must have the Angular site's content directly at the root (dist/) and the Astro site's content directly under dist/wiki/. Your CNAME file and 404.html should also reside at the root of the dist folder.

The desired structure:

dist/
├── index.html (Angular)
├── main-XXXX.js (Angular assets)
├── styles-XXXX.css (Angular assets)
├── 404.html
├── CNAME
└── wiki/
    ├── index.html (Astro)
    ├── _astro/ (Astro assets)
    └── sitemap.xml

4. Correct Copy Commands in Workflow

To achieve the above structure, use precise copy commands in your GitHub Actions workflow:

- name: Consolidate compiled files
  run: |
    mkdir -p dist/wiki
    # Copy Angular's browser output to the root of dist/
    cp -r ./portfolio/dist/portfolio/browser/* ./dist/
    # Copy Astro's dist output directly into dist/wiki/
    cp -r ./wiki/dist/* ./dist/wiki/

Note the use of * to copy the *contents* of the directories, not the directories themselves, and mkdir -p for safety.

5. GitHub Actions Deployment

Finally, upload the consolidated dist folder as your artifact and deploy using actions/deploy-pages@v4:

- name: Upload artifacts
  uses: actions/upload-pages-artifact@v4
  with:
    path: ./dist

# ... (later in the deploy job)
- name: Deploy to GitHub Pages
  id: deployment
  uses: actions/deploy-pages@v4

Key Takeaways for Developer Productivity

This discussion highlights several critical points for efficient static site deployment in a monorepo context:

  • GitHub Pages' Root-Serving Nature: Always remember that GitHub Pages serves the root of your uploaded artifact. Plan your final output structure accordingly.
  • Framework-Specific Configurations: Understand how each framework (Angular's base-href, Astro's base and site) needs to be configured for subpath deployments.
  • Precise File Placement: The exact cp commands and the resulting directory structure are paramount for avoiding 404s and ensuring all assets resolve correctly.

Mastering these deployment nuances not only resolves immediate technical hurdles but also significantly contributes to positive software project metrics, reflecting a more efficient and productive development workflow. Seamless deployments mean less time debugging infrastructure and more time building features, directly impacting overall developer performance and project velocity.

Developer reviewing a dashboard showing successful deployments and positive software project metrics.
Developer reviewing a dashboard showing successful deployments and positive software project metrics.