app.frontend() method for serving static frontend
Use app.frontend() or router.frontend() to serve static frontend applications. This is useful for frontend tools that generate static files, such as React with Vite, TanStack Router, Astro, Vue, Svelte, Angular, and Solid. FastAPI checks path operations first; frontend files are only checked if no normal route matched, so the API won't be affected.
Frontend directory structure for app.frontend()
Create a directory structure with your built frontend files. For example, after running npm run build, place generated files in a dist directory. The structure would be: project root with pyproject.toml, an app folder with __init__.py and main.py, and a dist folder containing index.html and an assets subfolder with generated files like app.js.
Using fallback with app.frontend() for client-side routing
For single-page apps (SPAs) with client-side routing, use fallback='index.html' in app.frontend(). FastAPI uses this fallback only for GET and HEAD requests that explicitly accept HTML with Accept: text/html or Accept: application/xhtml+xml headers, as browser navigation requests normally do. Missing files like JavaScript, CSS, and images still return 404. Requests with other methods like POST or PUT to paths that only match the frontend fallback also return 404.
Custom 404.html page with app.frontend()
Serve a custom 404.html page for missing frontend paths by using app.frontend() with the directory containing 404.html. That response keeps a status code of 404. FastAPI won't serve index.html for missing frontend paths; it will return the 404.html file instead. This is useful with frontend tools that generate static HTML files for each page, like Astro.
Fallback auto mode in app.frontend()
By default, app.frontend() uses fallback='auto'. If a 404.html file exists in the frontend directory, missing frontend paths serve that file with status code 404. Otherwise, if an index.html file exists, missing browser navigation paths serve index.html, which is what many frontend apps with client-side routing expect. In most cases, you can use app.frontend('/', directory='dist') without specifying the fallback argument.
Disable fallback in app.frontend()
To prevent serving a fallback file for missing frontend paths, use fallback=None in app.frontend(). Then missing frontend paths return the normal 404.
check_dir parameter behavior in app.frontend()
By default, app.frontend() uses check_dir='auto'. When FASTAPI_ENV environment variable is set to development, FastAPI only shows a warning if the frontend build output directory is missing; the fastapi dev command sets this environment variable automatically. In any other environment, FastAPI raises an error when the app is created. Set check_dir=True to always check the directory when the app is created. Set check_dir=False if frontend files are created later by a separate build step after the app object is created; FastAPI will then check the directory when a request is handled instead.
Dependencies and middleware apply to frontend responses
Frontend responses run inside the normal FastAPI application, so HTTP middleware applies to them. Dependencies from the app, from an APIRouter, and from include_router() also apply to frontend responses. This can be useful for protecting a frontend with cookie authentication or similar. Dependencies can also modify response headers and add background tasks, as with normal path operations.
app.frontend() serves static files only
app.frontend() serves files already generated by your frontend build. It does not run server-side rendering. It is for frontend frameworks that generate static files, not for frameworks that need dynamic rendering on the server for each request.
StaticFiles import and basic mounting
Import StaticFiles from fastapi.staticfiles (or alternatively from starlette.staticfiles). Mount a StaticFiles() instance in a specific path using app.mount(). FastAPI provides StaticFiles as a convenience, but it comes directly from Starlette.
Mounting vs APIRouter
Mounting means adding a complete independent application in a specific path that handles all sub-paths. This is different from using an APIRouter because a mounted application is completely independent. The OpenAPI and docs from the main application will not include anything from the mounted application.
StaticFiles mount parameters
When mounting StaticFiles, use three parameters: the first parameter is the sub-path where the StaticFiles will be mounted (e.g., '/static'), directory= is the name of the directory containing your static files, and name= gives it an internal name that FastAPI can use. All parameters can be customized according to application needs.
StaticFiles path handling
Any path that starts with the mounted sub-path (e.g., '/static') will be handled by the mounted StaticFiles application.
app.frontend() alternative for frontend hosting
For hosting a frontend, use app.frontend() instead of manually mounting StaticFiles. app.frontend() uses StaticFiles underneath but provides several additional advantages for frontends, such as handling client-side routing.