Skip to content

Commit 3ab67f2

Browse files
committed
feat: add Cloudflare Worker to serve viewer at clean subdomain
Proxy viewer.geolibre.app to the GitHub Pages build at geolibre.app/demo, which avoids Cloudflare's 25 MiB per-asset limit on the 32 MiB DuckDB WASM bundle while exposing a clean subdomain. Includes a workflow to deploy the worker on changes.
1 parent 5563a51 commit 3ab67f2

3 files changed

Lines changed: 57 additions & 0 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Deploy viewer
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "workers/viewer/**"
8+
- ".github/workflows/deploy-viewer.yml"
9+
workflow_dispatch:
10+
11+
jobs:
12+
deploy:
13+
name: Deploy viewer proxy to Cloudflare Workers
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v6
18+
19+
- name: Deploy to Cloudflare Workers
20+
uses: cloudflare/wrangler-action@v3
21+
with:
22+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
23+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
24+
workingDirectory: workers/viewer

workers/viewer/src/index.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// viewer.geolibre.app
2+
//
3+
// Serves the GeoLibre web viewer at a clean subdomain by proxying to the build
4+
// already published at https://geolibre.app/demo (GitHub Pages). We proxy rather
5+
// than re-host the files because the viewer bundles a 32 MiB DuckDB WASM asset,
6+
// which exceeds Cloudflare's 25 MiB per-asset limit for Workers/Pages. GitHub
7+
// Pages has no such limit, so it stays the origin of record.
8+
//
9+
// The viewer build uses relative asset paths, so requests map 1:1:
10+
// viewer.geolibre.app/<path>?<query> -> geolibre.app/demo/<path>?<query>
11+
//
12+
// Origin redirects (e.g. trailing slash) are followed server-side so the public
13+
// viewer.geolibre.app URL is preserved and geolibre.app/demo is never exposed.
14+
15+
const ORIGIN = "https://geolibre.app/demo";
16+
17+
export default {
18+
async fetch(request: Request): Promise<Response> {
19+
const url = new URL(request.url);
20+
const target = `${ORIGIN}${url.pathname}${url.search}`;
21+
return fetch(target, request);
22+
},
23+
};

workers/viewer/wrangler.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name = "geolibre-viewer"
2+
main = "src/index.ts"
3+
compatibility_date = "2025-03-01"
4+
5+
# Binds the custom domain on deploy. Because geolibre.app is managed in this
6+
# Cloudflare account, the DNS record and TLS certificate are provisioned
7+
# automatically on the first deploy.
8+
[[routes]]
9+
pattern = "viewer.geolibre.app"
10+
custom_domain = true

0 commit comments

Comments
 (0)