# Vite build — from CDN script tags to a real frontend **Status: tracked, not started.** A direction to refactor toward, not a project with a date. Each phase below is worth shipping on its own; none of it is speculative scaffolding for a component rewrite. Today `static/index.html` loads Vue 3, Lightweight Charts 5.2.0 and Font Awesome 7.3.1 from unpkg, then two plain scripts. FastAPI serves those files and stamps `?v=` onto every `/static/` URL. Production is Coolify + nixpacks + a Python `Procfile`. That is the setup this document replaces. ## The goal is not "more Vue" The target is **a pinned, hashed, same-origin frontend** that we can grow without unpkg and without a Python hasher. It is not a component split, not TypeScript, not a router, and not leaving Coolify. - `chart.js` stays a plain class. Vue still must not wrap chart or series objects in `ref()` / `reactive()`. - `window.__chart` stays. E2E and diagnostic work depend on it. - One `App.vue` holding today's template and `setup()`. Do not extract the color picker or the tool panels in the same change. - Stay on Coolify. The friction is nixpacks autodetection, not the platform. ## What is already right - Vue 3 Composition API in `static/app.js` (`createApp`, `ref`, `computed`, `watch`, `onMounted`). That maps 1:1 onto `vue` from npm. - `ConfluenceChart` is already framework-free. It only needs `export` instead of `window.ConfluenceChart`, and ESM named imports instead of the `LightweightCharts` global. - FastAPI already owns `/`, `/api`, `/ws`. The built SPA still comes from that origin. Do not put a Vite server in production. - Asset hashing exists because a tab left open kept running yesterday's JS (`main.asset_version`, `tests/test_asset_versioning.py`). Vite's content hashes replace that rewriter; the *reason* does not go away. ## Constraints this repo will punish you for forgetting - **The agent is on a different machine from the user's browser.** Local Vite on `localhost:5173` is invisible to them. Whatever serves the UI in dev must still be reachable as `hera.local:8010` (or whatever host port compose publishes). HMR has to work across that hop, or we do not use HMR. - **`--reload` plus an 82-second seed.** Never put a scratch `.py` in the repo root. Frontend files are safe; uvicorn watches Python. Do not "help" by adding a Python build helper at the root. - **Every push to `main` is a production deploy**, and a deploy restarts the market stream. The Vite cutover is one of those deploys. Land the production Dockerfile *before* a root `package.json` exists, or nixpacks may decide this is a Node app and the site goes dark. - **E2E hits `http://api:8000`**, waits on `window.__chart.bars`, and uses `--lang=en-US`. None of that changes. A blank canvas after the move is still the locale bug until proven otherwise. - **Pin what unpkg currently pins.** Lightweight Charts **5.2.0** and Font Awesome **7.3.1**. Vue's CDN tag is `vue@3` (floating). Pin a current Vue 3.x on the way in; do not upgrade LWC in this work. v5 series creation is `chart.addSeries(CandlestickSeries, opts)` — the v4 helpers do not exist. - **One uvicorn worker, forever**, until the streamer is a separate process. The Dockerfile `CMD` is the `Procfile` line. Do not add `--workers`. ## Target layout ``` frontend/ package.json package-lock.json committed vite.config.js index.html Vite entry; empty #app src/ main.js createApp(App).mount('#app') App.vue today's markup + today's setup() chart.js export class ConfluenceChart style.css moved from static/ dist/ gitignored; Vite outDir, served by FastAPI Dockerfile production; Coolify prefers this over nixpacks ``` `static/` goes away when FastAPI is serving `dist/` and the e2e suite is green. Do not keep both as a fallback — a missed build would silently serve the CDN app. Suggested `frontend/src/main.js`: ```js import { createApp } from 'vue'; import '@fortawesome/fontawesome-free/css/all.min.css'; import './style.css'; import App from './App.vue'; createApp(App).mount('#app'); ``` Suggested chart import (names used today): ```js import { createChart, CandlestickSeries, HistogramSeries, LineSeries, LineStyle, LineType, CrosshairMode, TickMarkType, } from 'lightweight-charts'; ``` Keep `export default { setup() { ... return { ... }; } }` in `App.vue`. `