File size: 1,232 Bytes
6a6737e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
"""
SPA Static Files Handler for FastAPI
Serves Vue.js SPA while preserving API routes
"""
from fastapi.staticfiles import StaticFiles
from starlette.responses import FileResponse
from starlette.types import Scope
import os


class SPAStaticFiles(StaticFiles):
    """
    Custom StaticFiles that serves index.html for non-API routes (SPA fallback)
    while allowing API routes to pass through
    """
    
    async def get_response(self, path: str, scope: Scope):
        """
        Handle requests:
        - API routes (/api/*) β†’ 404 (let FastAPI handle)
        - Static files (exist) β†’ serve file  
        - Everything else β†’ index.html (SPA routing)
        """
        # Let API routes pass through to FastAPI
        if path.startswith("api/") or path.startswith("docs") or path.startswith("redoc") or path.startswith("openapi.json"):
            # Return 404 to let FastAPI handle it
            raise RuntimeError("Not found")
        
        try:
            # Try to serve the file
            return await super().get_response(path, scope)
        except Exception:
            # File not found β†’ serve index.html for SPA routing
            return FileResponse(os.path.join(self.directory, "index.html"))