Showcase

Static sites on orbitalhq.io, published from a merge request.

Showcase hosts the customer-facing pages that don't belong on the main site: demos, guides and prototypes. Each top-level directory in the repo is its own site. A merge request gets a preview, and merging to main publishes it.

vyne/showcase
showcase/├── about/         # about.showcase.orbitalhq.io├── hello-world/   # hello-world.showcase.orbitalhq.io├── your-site/     # your-site.showcase.orbitalhq.io├── scripts/       # the pipeline├── AGENTS.md└── README.md
One directory per site. The directory name is the subdomain.

How it works

Add a directory, open a merge request, merge.

Everything runs in GitLab CI. Only the directories you change get rebuilt, and DNS and HTTPS are set up for you on the first deploy.

  1. Step 1

    Add a directory

    Its name becomes the subdomain. Put a built app or plain HTML inside it.

  2. Step 2

    Open a merge request

    The pipeline builds the site and deploys a preview to name--mr12.audition.orbitalhq.io. The link appears on the MR.

  3. Step 3

    Merge

    The site goes live at name.showcase.orbitalhq.io, and the preview is deleted.

Check a site name

Uses the same rules as the pipeline.

    Preview
    Production

    Create a site

    Pick a name, then add your files.

    A site is a built app with a package.json, or a folder of plain HTML. The config file is optional, and most sites don't need one.

    Naming rules

    • 3 to 50 characters: lowercase a-z, 0-9 and single dashes.
    • No double dashes, and no dash at the start or end.
    • Not scripts, schema or node_modules, and not starting with a dot.

    What goes inside

    • Built app: a package.json with a build script, and a committed package-lock.json. Output is read from dist/.
    • Plain static files: an index.html and your assets. Nothing is built.

    Check it locally

    From the repo root, build the site and run the deploy script in dry-run mode. It checks the config and the build output, and uploads nothing.

    acme-demo/.showcase.json
    {  "$schema": "../schema/showcase.schema.json",  "build": {    "image": "node:22",    "command": "npm ci && npm run build",    "output": "dist"  },  "spa": true}
    Terminal
    (cd acme-demo && npm ci && npm run build)node scripts/deploy-site.mjs acme-demo --dry-run
    Fields in .showcase.json
    FieldDefaultWhat it does
    build.imagenode:22The Docker image the build runs in. Use it to pick a Node version.
    build.commandnpm ci && npm run build with a package.json, otherwise noneShell command run inside your directory. null serves the files as they are.
    build.outputdist with a package.json, otherwise .The folder, relative to your directory, that gets published.
    spafalsetrue 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

    Every merge request gets its own URL.

    Push a branch and open a merge request against main. The preview link shows on the MR as "View app", and in the deploy job's log.

    Terminal
    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
    Preview URL<dir>--mr<number>.audition.orbitalhq.io
    First deployAbout 2 minutes before HTTPS works, while the certificate is issued
    Later pushesLive as soon as the deploy job finishes
    Search enginesPreviews send X-Robots-Tag: noindex
    Clean-upDeleted when the MR is merged or closed, or after 2 weeks

    What you can deploy

    Anything that builds to static files

    Sites are served from the root of their own subdomain, so leave the framework's base path at /.

    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: output is dist.

    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

    Point your agent at AGENTS.md.

    The repo has instructions written for coding agents. They cover naming, the config file, the local check and opening the merge request.

    • AGENTS.md: the checklist and the rules. Claude Code reads it through CLAUDE.md.
    • README.md: the full reference, including troubleshooting.
    • showcase.schema.json: every valid config field, so the agent doesn't invent new ones.
    Prompt
    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.

    Start with a branch and a directory.

    The README has the full checklist, the config reference and fixes for common pipeline failures.