# Deployment guide Mechanica is a static Vite application with client-side routing and WebGL assets. The production deployment target is Vercel, but the generated `dist/` folder can also be served from any static host that supports SPA rewrites and long-lived immutable asset caching. ## Build contract - Install command: `npm install` - Build command: `npm run build` - Output directory: `dist` - Preview command: `npm run preview` - Node version: `>=20` The build command runs TypeScript project validation before bundling with Vite. Production source maps are disabled by default and can be enabled with `VITE_ENABLE_SOURCE_MAPS=true`. ## Vercel setup 1. Import the repository into Vercel. 2. Select framework preset **Vite**. 3. Set: - Install command: `npm install` - Build command: `npm run build` - Output directory: `dist` 4. Add environment variables from `.env.example`. 5. Set `VITE_APP_ORIGIN` to the canonical production origin, for example `https://mechanica.example.com`. 6. Deploy a preview branch and run the QA checklist before promoting to production. `vercel.json` contains the SPA rewrites, security headers, and immutable cache headers for hashed build assets plus decoder folders. ## Environment configuration Only non-secret values belong in `VITE_` variables because Vite embeds them into client bundles. Required public variables for production: ```bash VITE_APP_NAME=Mechanica VITE_APP_ORIGIN=https://your-production-domain.example VITE_DEFAULT_MACHINE=four-stroke-petrol-engine VITE_ASSET_BASE_URL=/assets/machines/ VITE_DRACO_DECODER_PATH=/draco/ VITE_KTX2_TRANSCODER_PATH=/basis/ VITE_ENABLE_PERF_OVERLAY=false VITE_ENABLE_DEBUG_CAMERA=false VITE_ENABLE_SOURCE_MAPS=false VITE_SOCIAL_IMAGE=/social/mechanica-og.svg ``` ## Routing Mechanica is a single-page app. These routes rewrite to `index.html`: - `/` - `/catalogue` - `/machine/:slug` - `/viewer/:slug` - all other client routes Runtime route handling should display an in-app not-found state for unknown machine slugs rather than relying on the hosting platform’s 404 page. ## Headers The Vercel configuration applies: - `X-Content-Type-Options: nosniff` - `X-Frame-Options: DENY` - `Referrer-Policy: strict-origin-when-cross-origin` - restrictive `Permissions-Policy` - a CSP that allows: - same-origin scripts - WebAssembly execution needed by Basis/KTX2 transcoding - same-origin and blob workers used by asset decoders - inline styles for Vite/CSS-in-JS runtime compatibility If third-party analytics or monitoring is added later, update `script-src`, `connect-src`, and `img-src` deliberately instead of weakening the policy globally. ## Cache policy Hashed build assets under `/assets/` are cached for one year with `immutable`. Decoder/transcoder folders are also cached for one year: - `/draco/` - `/basis/` If decoder files are replaced, either keep their filenames versioned or purge the Vercel cache. Social preview and icon assets are cached for one week to allow brand updates without long stale periods. ## Asset decoder deployment For Draco-compressed geometry, copy the decoder files from the resolved `three` package into `public/draco/` during asset pipeline setup. Typical files are: - `draco_decoder.js` - `draco_decoder.wasm` - `draco_wasm_wrapper.js` For KTX2/Basis textures, copy the transcoder files into `public/basis/`. Typical files are: - `basis_transcoder.js` - `basis_transcoder.wasm` The exact file names and source locations should be confirmed against the installed Three.js version. ## Preview deployment QA For every preview deployment: 1. Open the preview URL in a clean browser profile. 2. Load the catalogue. 3. Search and filter machines. 4. Open one machine from each category. 5. Confirm the 3D viewer renders without console errors. 6. Play/pause animation and change RPM. 7. Toggle exploded view, wireframe, annotations, and cross-section. 8. Select a part and confirm the detail drawer updates. 9. Copy a share link and open it in a private window. 10. Test a mobile viewport at 390px width. 11. Test with reduced motion enabled. 12. Run Lighthouse or WebPageTest for a production-like network profile. ## Rollback Vercel retains immutable deployments. To rollback: 1. Open the Vercel project deployments list. 2. Select the last known-good production deployment. 3. Promote it to production. 4. Verify the app loads and share links still resolve. 5. If asset paths changed between deployments, purge caches for decoder folders and any public non-hashed assets. ## Domain and canonical URLs Set `VITE_APP_ORIGIN` to the production origin. The runtime SEO/share layer should derive canonical machine URLs from that origin and the route slug. For static social crawlers, `index.html` provides a robust default preview. Per-machine social cards require either: - pre-rendered static HTML files generated for each machine route, or - a Vercel Edge/SSR metadata endpoint that returns route-specific Open Graph tags before the SPA boots. The current static deployment strategy uses default site-level tags plus client-side metadata updates for browser tabs and copy-link behavior.