Personal site: a landing page with a three.js hero and a projects page.
npm install
npm run dev # http://localhost:5173
npm run build # static site in dist/
index.html/src/landing/— landing page (glass knot hero, scroll sections)projects/index.html/src/projects/— projects page; featured projects come fromsrc/data/projects.js, the rest is fetched live from the GitHub APIde/index.html,de/projects/index.html— German versions of both pages. All copy lives insrc/i18n/strings.js(UI) andsrc/data/projects.js(projects, as{ en, de }). English pages send German-language browsers to/de/unless the visitor picked a language with the EN/DE switch.src/components/reactbits/— text and card effects adapted from React Bitsold/— hand-written static pages, copied intodist/unchanged. The games are their own repo: malte9799/games, served at/games/(and games.maltee.dev).
Pushing to main builds and deploys via .github/workflows/deploy.yml
(Settings → Pages → Source must be set to GitHub Actions).
maltee.dev. The same main build is also served at https://maltee.dev/ by a Cloudflare
assets-only Worker (maltee-site, wrangler.jsonc, route maltee.dev/*), deployed by the
"Cloudflare (maltee.dev)" step of the workflow (main only; previews/ is left out). Orbis keeps its own
more specific route maltee.dev/orbis*, so /orbis/ is unaffected. GitHub Pages stays live in parallel.
One-time setup: repo secrets CLOUDFLARE_API_TOKEN (Workers Scripts: Edit + Zone → Workers Routes: Edit for
maltee.dev, same as in the orbis repo) and CLOUDFLARE_ACCOUNT_ID; and the Cloudflare redirect rule that sends
maltee.dev/ to /orbis/ must be removed (Dashboard → maltee.dev → Rules), otherwise it fires before the Worker.
Without the secrets the step is skipped with a warning.
Branch previews. The same workflow also builds every other branch (newest 12) into
/previews/<branch>/, e.g. https://malte9799.github.io/previews/my-branch/; the list is at
/previews/. scripts/build-pages.mjs does the work (node scripts/build-pages.mjs locally,
after fetching the branches → site/). Each run replaces the whole deployment, so production
(main) is never touched by a branch push and a deleted branch loses its preview. One-time
setting: Settings → Environments → github-pages → Deployment branches → No restriction.
In code, link with withBase() / import.meta.env.BASE_URL rather than a bare /path.