Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS not recognized when served with FastAPI

I have a FastAPI app built and an index, css and js file that work when opened directly, but I can't get the css file to show up when being served with FastAPI. I've tried troubleshooting in case the problem is a CORS issue, I've tried re-arranging the files so as to be in the same or different directories (and re-specifying the href path accordingly) but nothing has worked. This is my directory at this point:

working_directory
└── app
|__ index.html
    ├── style.css
    └── main.js

With the app home route set up like so:

file_path = "index.html"

@app.get("/")
async def home():
    return FileResponse(file_path)

Would I need to also provide the path to the css file within the file_path variable? The formats I've tried haven't worked thus far and errors with FastAPI aren't as well documented as with Flask or Django, for example.

My error looks like this: GET http://localhost:8000/style.css net::ERR_ABORTED 404 (Not Found)

How would I get the web app to recognize my style.css file?

like image 328
Erin Avatar asked May 06 '20 17:05

Erin


People also ask

Can FastAPI serve HTML?

FastAPI is really designed for building APIs and microservices. It can be used for building web applications that serve HTML using Jinja, but that's not what it is really optimized for.

How do I fix external CSS not working?

Make sure the link tag is at the right place If you put the <link> tag inside another valid header tag like <title> or <script> tag, then the CSS won't work. The external style CAN be put inside the <body> tag, although it's recommended to put it in the <head> tag to load the style before the page content.


1 Answers

You need to actually serve the static files. Below's an example doing so with FastAPI. In a 'real world' scenario you would probably leave serving these files to a reverse proxy, like nginx.

Consider the following structure;

src
  app/main.py
  static/css/main.css
  templates/index.html

main.py

from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from pathlib import Path


app = FastAPI()

app.mount(
    "/static",
    StaticFiles(directory=Path(__file__).parent.parent.absolute() / "static"),
    name="static",
)

templates = Jinja2Templates(directory="templates")


@app.get("/")
async def root(request: Request):
    return templates.TemplateResponse(
        "index.html", {"request": request}
    )

index.html

...
<link href="{{ url_for('static', path='/css/main.css') }}" rel="stylesheet">
...
like image 98
Hedde van der Heide Avatar answered Oct 12 '22 14:10

Hedde van der Heide