Vite
React, Vue, Svelte
Defaults work. Add "spa": true for a client-side router.
Showcase
Showcase hosts public, customer-facing content: demos, guides and prototypes. Each top-level directory in the repo is one site. A merge request gets a preview. Merging to main publishes the site.
showcase/├── about/ # about.showcase.orbitalhq.io├── hello-world/ # hello-world.showcase.orbitalhq.io├── your-site/ # your-site.showcase.orbitalhq.io├── scripts/ # pipeline scripts├── AGENTS.md└── README.md
Previews, from merge requests
*.audition.orbitalhq.io
acme-demo--mr12.audition.orbitalhq.io
One per site in each open merge request. Deleted when the MR is merged or closed.
Live sites, from main
*.showcase.orbitalhq.io
acme-demo.showcase.orbitalhq.io
Updated each time a change to the site merges to main.
How it works
GitLab CI builds and deploys only the directories you changed. DNS and HTTPS are set up on the first deploy.
Its name becomes the subdomain. Put a built app or plain HTML inside it.
The pipeline builds the site and deploys a preview to name--mr12.audition.orbitalhq.io. The link appears on the MR.
The site goes live at name.showcase.orbitalhq.io. The preview is deleted.
Uses the same rules as the pipeline.
Create a site
A site is either a built app with a package.json, or a folder of plain HTML. Add a .showcase.json only if the defaults don't fit.
a-z, 0-9 and single dashes.scripts, schema or node_modules, and not starting with a dot.package.json with a build script, and a committed package-lock.json. The build should write to dist/.index.html and your assets. Nothing is built.From the repo root, build the site, then run the deploy script with --dry-run. It checks that the build output exists and that the generated config is valid. Nothing is uploaded.
{ "$schema": "../schema/showcase.schema.json", "build": { "image": "node:22", "command": "npm ci && npm run build", "output": "dist" }, "spa": true}
(cd acme-demo && npm ci && npm run build)node scripts/deploy-site.mjs acme-demo --dry-run
| Field | Default | What it does |
|---|---|---|
build.image | node:22 | The Docker image the build runs in. Use it to pick a Node version. |
build.command | npm ci && npm run build with a package.json, otherwise none | Shell command run inside your directory. null serves the files as they are. |
build.output | dist with a package.json, otherwise . | The folder, relative to your directory, that gets published. |
spa | false | true serves index.html for unknown paths, for client-side routers. Otherwise unknown paths get the nearest 404.html. |
For headers and redirects, add Cloudflare _headers and _redirects files to your build output. With Vite, put them in public/.
Previews
Push a branch and open a merge request against main. The MR shows a link to the preview.
git checkout main && git pullgit checkout -b add-acme-demo# add acme-demo/, then:git add acme-demogit commit -m "Add acme-demo showcase site"git push -u origin HEADglab mr create --fill --target-branch main
What you can deploy
Each site is served from the root of its own subdomain, so leave the framework's base path as /.
Vite
React, Vue, Svelte
Defaults work. Add "spa": true for a client-side router.
Next.js
Static export
Set output: 'export', then "output": "out".
Astro
Static output
Defaults work.
SvelteKit
adapter-static
"output": "build"
Angular
Browser build
Output is dist/<project>/browser. Add "spa": true.
Create React App
Build folder
Output is build. Add "spa": true.
Docs sites
VitePress, Docusaurus
Point build.output at the generated folder.
Plain HTML
No build
Leave out package.json. The folder is served as it is.
Works
HTML, CSS, JavaScript, images and fonts. Client-side routing with "spa": true. Custom headers and redirects.
Doesn't work
Server-side rendering, API routes, serverless functions, runtime secrets and databases. If a site needs these, it doesn't belong here.
Coding agents
The repo has instructions for coding agents. They cover naming, the config file, the local check and opening the merge request.
CLAUDE.md.Clone git@gitlab.com:vyne/showcase.git, read AGENTS.md and follow it.Create a showcase site called acme-demo from the app in ./my-app.Build it and run the dry-run deploy locally, then open a merge request and give me the preview URL from the pipeline.
The code
GitLab CI works out what changed, builds it and deploys it to Cloudflare Workers.
Repository
vyne/showcase
Every site, plus the pipeline that deploys them.
Pipeline
.gitlab-ci.yml
Runs the planning job, then a child pipeline that builds and deploys the changed sites.
Planning
scripts/plan.mjs
Finds the changed sites and writes their build and deploy jobs.
Deploying
scripts/deploy-site.mjs
Writes the Worker config and runs wrangler deploy.
Status
Pipelines
Build logs and site URLs for every run.
This page
about/
A Showcase site, built with Vite and TypeScript.
The README has the full checklist, the config reference and fixes for common pipeline failures.