feat(static-assets): cache-bust JS/CSS via ?v=<commit-sha>, immutable in prod
All checks were successful
All checks were successful
Adds a `static_v(request, name, path=...)` Jinja helper that appends
?v=<commit-sha> from app.core.build_info, plus a CachedStaticFiles
subclass that serves Cache-Control: public, max-age=31536000, immutable
in production and no-cache in development. Browsers refetch JS/CSS
automatically on every deploy without the user having to hard-reload.
- New: app/core/static_files.py (CachedStaticFiles)
- Updated: app/templates_config.py (static_v helper)
- Updated: main.py (use CachedStaticFiles for *_static mounts)
- Codemod: 143 url_for('*_static', path='*.js'|'*.css') → static_v(...)
across 123 templates. Images/fonts/JSON locales intentionally
unchanged (out of scope).
- Arch rule: FE-024 (warning) flags raw url_for on JS/CSS to prevent
drift. Note: FE-008 was already taken by the number_stepper rule.
- docs/proposals/static-asset-cache-busting.md marked Done.
Closes plan from docs/proposals/static-asset-cache-busting.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
{% block alpine_data %}backgroundTasks(){% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script defer src="{{ url_for('marketplace_static', path='admin/js/background-tasks.js') }}"></script>
|
||||
<script defer src="{{ static_v(request, 'marketplace_static', path='admin/js/background-tasks.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
{% block alpine_data %}adminImports(){% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script defer src="{{ url_for('marketplace_static', path='admin/js/imports.js') }}"></script>
|
||||
<script defer src="{{ static_v(request, 'marketplace_static', path='admin/js/imports.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
@@ -426,5 +426,5 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script defer src="{{ url_for('marketplace_static', path='admin/js/letzshop-store-directory.js') }}"></script>
|
||||
<script defer src="{{ static_v(request, 'marketplace_static', path='admin/js/letzshop-store-directory.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
{% block alpine_data %}adminLetzshop(){% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script defer src="{{ url_for('marketplace_static', path='admin/js/letzshop.js') }}"></script>
|
||||
<script defer src="{{ static_v(request, 'marketplace_static', path='admin/js/letzshop.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
@@ -570,5 +570,5 @@
|
||||
document.head.appendChild(script);
|
||||
})();
|
||||
</script>
|
||||
<script defer src="{{ url_for('marketplace_static', path='admin/js/marketplace-letzshop.js') }}"></script>
|
||||
<script defer src="{{ static_v(request, 'marketplace_static', path='admin/js/marketplace-letzshop.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -388,5 +388,5 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script defer src="{{ url_for('marketplace_static', path='admin/js/marketplace-product-detail.js') }}"></script>
|
||||
<script defer src="{{ static_v(request, 'marketplace_static', path='admin/js/marketplace-product-detail.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -412,5 +412,5 @@
|
||||
document.head.appendChild(script);
|
||||
})();
|
||||
</script>
|
||||
<script defer src="{{ url_for('marketplace_static', path='admin/js/marketplace-products.js') }}"></script>
|
||||
<script defer src="{{ static_v(request, 'marketplace_static', path='admin/js/marketplace-products.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -347,5 +347,5 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script defer src="{{ url_for('marketplace_static', path='admin/js/marketplace.js') }}?v=2"></script>
|
||||
<script defer src="{{ static_v(request, 'marketplace_static', path='admin/js/marketplace.js') }}?v=2"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -378,6 +378,6 @@
|
||||
<script defer src="{{ url_for('static', path='shared/js/utils.js') }}"></script>
|
||||
<script defer src="{{ url_for('static', path='shared/js/api-client.js') }}"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.14.0/dist/cdn.min.js"></script>
|
||||
<script defer src="{{ url_for('marketplace_static', path='store/js/onboarding.js') }}"></script>
|
||||
<script defer src="{{ static_v(request, 'marketplace_static', path='store/js/onboarding.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user