fix(web-ui): bust JS cache so api.js fix actually reaches the browser

The api.js library-list fix from the previous commit never reached the browser because nginx served all .js with `Cache-Control: public, immutable; max-age=31536000`. The HTML referenced api.js with no version query, so the browser kept its year-cached buggy copy.

* nginx.conf: drop .js from the immutable long-cache block, add a no-cache must-revalidate block so future redeploys are picked up immediately.
* All HTML files: tag api.js refs with ?v=4 so already-running browsers fetch the new version on next page load.
This commit is contained in:
Zac Gaetano 2026-05-17 08:30:49 -04:00
parent ac1878452f
commit 3ea896c368
6 changed files with 14 additions and 6 deletions

View file

@ -19,11 +19,19 @@ server {
root /usr/share/nginx/html; root /usr/share/nginx/html;
# Cache static assets aggressively # Cache static assets aggressively
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { location ~* \.(css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y; expires 1y;
add_header Cache-Control "public, immutable"; add_header Cache-Control "public, immutable";
} }
# JS files must revalidate so a redeploy is picked up immediately.
# The static index.html links api.js with a ?v=N query string anyway,
# but defence-in-depth: never let a stale .js sit in a browser cache.
location ~* \.js$ {
expires -1;
add_header Cache-Control "no-cache, must-revalidate";
}
# HTML files - no cache # HTML files - no cache
location ~* \.html?$ { location ~* \.html?$ {
expires -1; expires -1;

View file

@ -312,7 +312,7 @@
<div class="toast-container" id="toastContainer" aria-live="polite"></div> <div class="toast-container" id="toastContainer" aria-live="polite"></div>
<script src="js/api.js"></script> <script src="js/api.js?v=4"></script>
<script> <script>
const cState = { const cState = {
devices: [], devices: [],

View file

@ -457,7 +457,7 @@
</div> </div>
</div> </div>
<script src="js/api.js"></script> <script src="js/api.js?v=4"></script>
<script> <script>
const state = { const state = {
projects: [], projects: [],

View file

@ -304,7 +304,7 @@
</footer> </footer>
</div> </div>
<script src="/js/api.js"></script> <script src="/js/api.js?v=4"></script>
<script> <script>
// ============================================================ // ============================================================
// STATE MANAGEMENT // STATE MANAGEMENT

View file

@ -357,7 +357,7 @@
<div class="toast-container" id="toastContainer" aria-live="polite"></div> <div class="toast-container" id="toastContainer" aria-live="polite"></div>
<script src="js/api.js"></script> <script src="js/api.js?v=4"></script>
<script> <script>
const pState = { recorders: [], timers: {}, sourceType: 'srt', mode: 'caller', projects: [], signals: {} }; const pState = { recorders: [], timers: {}, sourceType: 'srt', mode: 'caller', projects: [], signals: {} };

View file

@ -249,7 +249,7 @@
<div class="toast-container" id="toastContainer" aria-live="polite"></div> <div class="toast-container" id="toastContainer" aria-live="polite"></div>
<script src="js/api.js"></script> <script src="js/api.js?v=4"></script>
<script> <script>
const CHUNK = 10 * 1024 * 1024; // 10 MB chunks const CHUNK = 10 * 1024 * 1024; // 10 MB chunks
const state = { projects: [], bins: [], queue: [], uploading: false }; const state = { projects: [], bins: [], queue: [], uploading: false };