Serve Chart.js and other vendor assets locally
The app uses Chart.js (and may use other JS/CSS libraries) for charts. By default these can be loaded from a CDN; for offline use, air-gapped deployments, or to avoid external requests, serve them from the app’s static folder.
Why serve locally
- Offline / air-gapped: No CDN dependency; app works without internet.
- Stability: Version is fixed in the repo; CDN changes don’t affect you.
- Privacy / compliance: No requests to third-party domains.
- Performance: One less origin; optional caching under your control.
Where assets live
- JS:
app/static/js/(e.g.chart.umd.min.js) - CSS:
app/static/css/for app styles; vendor CSS can go inapp/static/css/vendor/orapp/static/js/alongside the library if it ships as a bundle.
Templates reference them via Flask’s url_for('static', filename='...'), e.g.:
<script src="{{ url_for('static', filename='js/chart.umd.min.js') }}"></script>
How to add or update Chart.js
-
Download the vendor bundle (run from project root):
uv run python scripts/download_vendor_assets.py allThis script downloads the pinned Chart.js UMD build into
app/static/js/chart.umd.min.js. -
Commit the file (so deploys don’t need network):
git add app/static/js/chart.umd.min.js git commit -m "chore: vendor Chart.js for local serving" -
Templates already use the local URL; no CDN link remains once the file is present.
Adding another JS or CSS library
-
Choose a build: Prefer a single minified file (UMD/IIFE for JS) so the app doesn’t depend on a bundler.
-
Put it under
app/static/:- JS →
app/static/js/<library>.min.js - CSS →
app/static/css/vendor/<library>.min.css(or next to the JS if you prefer).
- JS →
-
Optionally extend the download script in
scripts/download_vendor_assets.py(e.g. add a URL and output path for the new library) so one command fetches all vendor assets. -
Reference in templates:
<script src="{{ url_for('static', filename='js/<library>.min.js') }}"></script> <!-- or --> <link rel="stylesheet" href="{{ url_for('static', filename='css/vendor/<library>.min.css') }}">
Version pinning
Chart.js version is pinned in scripts/download_vendor_assets.py (e.g. 4.4.1). To upgrade:
- Change the version in the script (and optionally the CDN URL if the path changed).
- Run
uv run python scripts/download_vendor_assets.py. - Test the app (Graph and Capacity charts).
- Commit the updated
app/static/js/chart.umd.min.js(and script if changed).
Checklist
- [ ] Run
uv run python scripts/download_vendor_assets.py allsoapp/static/js/chart.umd.min.jsexists. - [ ] Templates use
url_for('static', filename='js/chart.umd.min.js')(no CDN). - [ ] Commit the vendor file so CI and production serve it without network.