feat: serve the built Vue SPA from Quart with history-mode fallback
The frontend blueprint is registered after the api blueprint so /api/* routes are matched first; everything else falls through to the SPA. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ from quart import Quart
|
|||||||
|
|
||||||
from .api import api_bp
|
from .api import api_bp
|
||||||
from .config import get_config
|
from .config import get_config
|
||||||
|
from .frontend import frontend_bp
|
||||||
|
|
||||||
|
|
||||||
def create_app() -> Quart:
|
def create_app() -> Quart:
|
||||||
@@ -15,5 +16,7 @@ def create_app() -> Quart:
|
|||||||
app = Quart(__name__)
|
app = Quart(__name__)
|
||||||
app.secret_key = cfg.secret_key
|
app.secret_key = cfg.secret_key
|
||||||
app.register_blueprint(api_bp)
|
app.register_blueprint(api_bp)
|
||||||
|
# Registered last so /api/* routes win over the SPA catch-all.
|
||||||
|
app.register_blueprint(frontend_bp)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
"""Serves the built Vue SPA from frontend/dist/ with history-mode fallback."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from quart import Blueprint, send_from_directory
|
||||||
|
|
||||||
|
FRONTEND_DIST = Path(__file__).resolve().parent.parent.parent / "frontend" / "dist"
|
||||||
|
|
||||||
|
frontend_bp = Blueprint("frontend", __name__)
|
||||||
|
|
||||||
|
|
||||||
|
@frontend_bp.route("/")
|
||||||
|
@frontend_bp.route("/<path:subpath>")
|
||||||
|
async def serve_spa(subpath: str = ""):
|
||||||
|
if subpath and (FRONTEND_DIST / subpath).is_file():
|
||||||
|
return await send_from_directory(FRONTEND_DIST, subpath)
|
||||||
|
return await send_from_directory(FRONTEND_DIST, "index.html")
|
||||||
Reference in New Issue
Block a user