Skip to content

Add static site generation for GitHub Pages deployment - #1

Merged
michielbdejong merged 1 commit into
mainfrom
claude/github-pages-action-wqjpiv
Jul 24, 2026
Merged

Add static site generation for GitHub Pages deployment#1
michielbdejong merged 1 commit into
mainfrom
claude/github-pages-action-wqjpiv

Conversation

@michielbdejong

Copy link
Copy Markdown
Member

Summary

This PR adds static site generation capabilities to enable deploying the application as a static site to GitHub Pages. A new Node.js script crawls all public routes and renders them to static HTML files, which are then deployed instead of the raw repository.

Key Changes

  • New static-export.js script: Implements a complete static site generation pipeline that:

    • Discovers all public routes by scanning controller files in the os-app directory
    • Generates URLs for each route, including language-specific variants
    • Starts the Express server and fetches each route's rendered HTML
    • Writes responses to .static/ directory with proper directory structure
    • Copies built assets alongside rendered pages for a self-contained static site
  • Updated GitHub Actions workflow (static.yml):

    • Changed target branch from master to main
    • Added Node.js setup and dependency installation steps
    • Added build and static export steps before deployment
    • Changed artifact upload path from entire repository ('.') to only the generated .static directory
    • Improved workflow documentation
  • Updated package.json:

    • Added static-export npm script that runs the new static generation script
    • Added magic-string version override to resolve dependency conflicts

Implementation Details

  • The static exporter intelligently handles different URL types (root paths, language-prefixed routes, and file extensions) and generates appropriate file structures (e.g., /about.static/about/index.html)
  • Routes are filtered to exclude redirects, hidden routes, stub routes, and non-GET methods
  • The script waits up to 60 seconds for the server to become ready before crawling
  • Redirect responses (3xx status codes) are skipped during crawling
  • The server process is properly terminated after static generation completes

https://claude.ai/code/session_01AcjKc8vk2fb84yYZsE8k5d

The app renders pages server-side (Express + EJS) purely as a function
of (route, language), with no per-request dynamic data, so each page
can be pre-rendered once at build time. static-export.js boots the
real server, crawls every route the controllers declare (in all their
supported languages), and writes the responses alongside a full copy
of the built os-app asset tree, producing a self-contained static site
for GitHub Pages.

Also:
- fix static.yml's push trigger, which targeted "master" while the
  repo's default branch is "main", so it never actually ran
- build the app and run the export before uploading the Pages artifact,
  instead of uploading raw repo source
- pin magic-string to a CommonJS-compatible version via "overrides";
  the unpinned latest is ESM-only and breaks OLSKRollupPluginLocalize,
  which "require()"s it directly
@michielbdejong
michielbdejong merged commit d8b022f into main Jul 24, 2026
0 of 2 checks passed
michielbdejong pushed a commit that referenced this pull request Jul 24, 2026
…c export

- set NODE_ENV=production when booting the server for crawling, so the
  dev-only livereload script (injected by OLSKExpress whenever
  NODE_ENV !== production) doesn't get baked into the static pages and
  trip mixed-content blocking once served over HTTPS
- write an empty .nojekyll to the export root; GitHub Pages otherwise
  treats underscore-prefixed folders (_shared, __compiled) as
  Jekyll-reserved and silently excludes them, 404ing every asset under
  them despite the generated HTML referencing the correct paths

Found by testing the live deploy from #1 at hyperdraft.pondersource.com.
michielbdejong added a commit that referenced this pull request Jul 24, 2026
…c export (#6)

- set NODE_ENV=production when booting the server for crawling, so the
  dev-only livereload script (injected by OLSKExpress whenever
  NODE_ENV !== production) doesn't get baked into the static pages and
  trip mixed-content blocking once served over HTTPS
- write an empty .nojekyll to the export root; GitHub Pages otherwise
  treats underscore-prefixed folders (_shared, __compiled) as
  Jekyll-reserved and silently excludes them, 404ing every asset under
  them despite the generated HTML referencing the correct paths

Found by testing the live deploy from #1 at hyperdraft.pondersource.com.

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants