from django.conf import settings from django.http import FileResponse, Http404 from django.urls import include, path, re_path def spa_index(_request): """Serve the SPA shell for any non-API path. WhiteNoise serves real files from ``SPA_DIST_DIR`` (assets, favicon, …) before URL routing, so this view only fires for client-side routes such as ``/cv``, ``/demos/coins`` or unknown paths — Vue Router picks them up on the client (the wildcard route renders the Lara Croft 404). """ index = settings.SPA_DIST_DIR / "index.html" if not index.exists(): raise Http404("SPA build is missing — run `npm run build` in src/frontend first") return FileResponse(open(index, "rb"), content_type="text/html") urlpatterns = [ path("api/v1/", include("api.urls")), re_path(r"^(?!api/).*$", spa_index, name="spa-index"), ]