# Social metadata and sharing strategy Mechanica supports shareable links to specific machines and viewer states. Browser-visible metadata can be updated client-side, while social crawler previews need static or server-generated HTML. ## Share URL goals A copied link should reconstruct: - active machine - camera preset or camera position/target - exploded view amount - display mode - cross-section axis and offset - annotation label state - selected part - hidden parts - part opacity overrides - animation RPM and time scale The link should not include: - hover state - FPS - temporary drag state - open tooltip coordinates - raw Three.js object UUIDs - local favourites - user preferences unrelated to the shared view ## Canonical route format Preferred route: ```text /machine/ ``` Example: ```text /machine/planetary-gearbox?preset=iso&explode=0.55&mode=solid&labels=1&part=sun-gear ``` If a router variation cannot encode the slug in the path, use: ```text /viewer?machine=planetary-gearbox&preset=iso ``` ## Query schema | Param | Type | Clamp/validation | | --- | --- | --- | | `preset` | enum | `front`, `back`, `left`, `right`, `top`, `iso` | | `cam` | six comma-separated numbers | camera xyz + target xyz, finite values only | | `explode` | number | clamp `0` to `1` | | `mode` | enum | `solid`, `wireframe`, `xray` | | `clip` | axis + offset | axis `x/y/z`, offset clamp `-1` to `1` | | `labels` | boolean | `1` or `0` | | `part` | string | valid part ID for active machine | | `hidden` | CSV | valid part IDs only | | `opacity` | CSV pairs | `partId:value`, opacity clamp `0` to `1` | | `rpm` | number | clamp to active machine animation range | | `speed` | number | clamp `0.1` to `3` | Unknown params should be preserved only if the router owns them. Viewer-state parsing should ignore unknown fields. ## Copy-link behavior The copy-link control should: 1. Build the current route with serialized state. 2. Resolve it against `VITE_APP_ORIGIN` or `window.location.origin`. 3. Prefer `navigator.clipboard.writeText`. 4. Use a text-area fallback if Clipboard API is unavailable. 5. Show a success message in a visible toast and an ARIA live region. 6. Show a recoverable error state if copying fails. The generated URL should be deterministic so copying twice without state changes produces the same string. ## Client-side metadata On route changes, update: - `document.title` - `` - Open Graph title/description/url/image tags - Twitter title/description/image tags - `` For machine pages: ```text <Machine Title> — Mechanica description= og:title= — Mechanica og:description= og:url= og:image= ``` ## Social crawler limitation Most social crawlers do not execute the client application fully. A static SPA can provide a strong default site preview in `index.html`, but route-specific social cards require one of these strategies: ### Strategy A: pre-render machine HTML Generate one static HTML file per machine route at build time with machine-specific meta tags and the same SPA root. This is simple and CDN-friendly. Pros: - fast - no server runtime - deterministic - works on static hosting Cons: - requires a small build-time metadata generation script - deploy must include all machine route HTML files ### Strategy B: Vercel Edge metadata response Use an edge function or serverless route to return route-specific HTML metadata for crawlers and the SPA shell for browsers. Pros: - supports dynamic social images - can handle future user-generated collections Cons: - more moving pieces - CSP and cache policy must be maintained carefully - higher operational complexity ### Current milestone strategy The delivered static app uses a robust default preview in `index.html` and documents the per-machine options above. Runtime metadata updates should still be implemented because they improve browser tabs, bookmarks, accessibility tooling, and copied-link clarity even when social crawlers use default tags. ## Social image policy Default image: ```text /social/mechanica-og.svg ``` Per-machine images should use: ```text /social/machines/.png ``` Recommended dimensions: - `1200x630` - PNG or JPG for maximum platform compatibility - less than `500 KB` - dark background with clear machine silhouette and title SVG is included as the lightweight default asset in this repository. For a public marketing launch, export a PNG equivalent for broader social-platform compatibility.