Integrating Client-Side Applications (Frontend) in FastAPI

- Andrés Cruz - ES En español

Video thumbnail

FastAPI provides efficient mechanisms to manage client applications (Frontend) built with modern frameworks like Vue, React, or Svelte. This functionality simplifies the deployment of single-page user interfaces (SPAs) alongside the backend, optimizing communication and eliminating the need to configure independent web servers.

1. Using the Native Frontend Method

The most straightforward way to serve a client-side built interface is by using the native method provided by the framework. After compiling the frontend project (generating distribution files in a folder like dist using packaging commands), it is enough to link the output directory directly to the main application:

$ app.frontend("/ui", directory="frontend/dist")

This method automatically handles resolving routes, integrating client-side routers (such as Vue Router), and serving the main index.html file without requiring additional routing configurations or manual 404 error management.

2. Project Structure and Hybrid Deployment

In a hybrid architecture combining a FastAPI backend with a modern client interface, the typical project structure separates endpoint logic from compiled static resources:

  • Backend Module: Contains Python scripts, database configuration, and API routers integrated via include_router.
  • Frontend Directory: Houses the interface source code and generates the distribution folder with files packaged in HTML, CSS, and JavaScript.

Thus, high-performance backend services coexist harmoniously with the user's visual experience in a single integrated application.

3. Advanced Implementation with Custom Classes (StaticFiles)

In scenarios requiring exhaustive control over caching and response handling for SPAs (such as redirecting not-found requests to the index.html file so the client router manages navigation), it is possible to implement a custom class inherited from StaticFiles.

class SpaStaticFiles(StaticFiles):
    """StaticFiles that redirects to index.html on route 404 errors."""

    def lookup_path(self, path: str) -> tuple[str, os.stat_result | None]:
        self.all_directories = [os.fspath(CARPETA_UI)]
        return super().lookup_path(path)

    async def get_response(self, path: str, scope: Scope) -> Response:
        if not dist_esta_construido():
            return HTMLResponse(PAGINA_SIN_BUILD, status_code=status.HTTP_503_SERVICE_UNAVAILABLE)

        servido = path
        try:
            respuesta = await super().get_response(path, scope)
        except StarletteHTTPException as exc:
            if exc.status_code != 404 or "." in Path(path).name:
                raise
            respuesta = await super().get_response("index.html", scope)
            servido = "index.html"

        return self._con_cache_adequate(servido, respuesta)

app.mount(
    "/",
    SpaStaticFiles(directory=str(CARPETA_UI), html=True, check_dir=False),
    name="ui",
)

This advanced approach allows managing cache HTTP headers differently, applying immutability policies to hashed assets and ensuring that the main file maintains constant validation.

Let’s learn how to use the `.frontend` method in FastAPI to load JavaScript projects directly into FastAPI and route them accordingly.


Únete a la comunidad de desarrolladores que han decidido dejar de picar código y empezar a construir productos reales. Recibe mis mejores trucos de arquitectura cada semana:

I agree to receive announcements of interest about this Blog.