Skip to main content
For the complete documentation index, see llms.txt

Part 4: Production deployment

The DApp has no server code. The browser talks to Lace and the indexer directly, so any static host can serve it. This part deploys it to Vercel.

Vercel build configuration​

vercel.json sits in examples/leaderboard, which is the Vercel project's root directory:

vercel.json
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"framework": null,
"installCommand": "cd ../.. && npm ci",
"buildCommand": "cd ui && npm run build",
"outputDirectory": "ui/dist"
}
  • installCommand installs from the repository root. The example is one workspace of midnight-examples, and its dependencies and their pinned versions come from the root package.json and lockfile.
  • buildCommand builds ui/: a TypeScript check, then vite build.
  • outputDirectory is Vite's output. It holds the app and, through publicDir, the circuit keys, ZKIR, and integrity manifest.

Compiled contract output​

Vercel has no Compact compiler, so the build can't run npm run compile. That is why contract/managed/leaderboard/ is committed: the build serves the keys from there. If you change the contract, run npm run compile (not compile:fast, which leaves out the proving keys) and commit the result before you deploy.

Environment variables​

The DApp reads three variables at build time. Vite builds them into the bundle, so they are public once the site is live:

VariableRequiredValue
VITE_BLOCKFROST_PROJECT_IDYesA Blockfrost Midnight Preprod project ID, for reading the leaderboard.
VITE_DEFAULT_CONTRACTNoThe address of the leaderboard the page opens with. Without it, visitors deploy or join one.
VITE_NETWORK_IDNoThe network Lace must be on. Defaults to preprod.

Deploy a leaderboard from your local DApp first (Part 3) and use its address as VITE_DEFAULT_CONTRACT, so the site opens on a live leaderboard.

Deploy to Vercel​

Fork midnight-examples on GitHub, then import it from the Vercel dashboard:

  1. Go to vercel.com and sign in with GitHub.
  2. Click Add New Project and import your fork of midnight-examples.
  3. Set Root Directory to examples/leaderboard. Vercel reads vercel.json from there.
  4. Under Environment Variables, add VITE_BLOCKFROST_PROJECT_ID, and optionally VITE_DEFAULT_CONTRACT.
  5. Click Deploy.

Vercel redeploys whenever you push to the fork's default branch, and builds a preview deployment for every pull request.

Test the production deployment​

Open your Vercel URL in a browser with Lace installed. The leaderboard loads from the indexer before you connect a wallet. Connect Lace, play a round, and submit a score. When the transaction is confirmed, the new entry appears in the table within a few seconds. Click Prove on it to check the ownership proof end to end.

Summary​

ComponentService
Frontend and circuit keysVercel (static files)
ChainMidnight Preprod
Leaderboard readsBlockfrost's Midnight Preprod indexer
Wallet, fees, and proof generationLace (proving is delegated to the wallet)
Test tokensPreprod faucet

This layout carries over to other Midnight DApps. The contract defines the on-chain logic, an API layer wraps it for TypeScript, and the frontend gets its providers from the wallet, so the site itself stays static.