As per Starlette documentation:
StaticFiles
Signature:
StaticFiles(directory=None, packages=None, check_dir=True)
html
– Run in HTML mode. Automatically loadsindex.html
for directories if such file exists.
In addtion, as shown from the code snippet you provided, you have mounted StaticFiles
to the root directory (i.e., "https://stackoverflow.com/"
), instead of, for example, /static
(or some other path name), as shown below:
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
app = FastAPI()
app.mount('/static', StaticFiles(directory='static'), name="static")
As per FastAPI documentation:
“Mounting” means adding a complete “independent” application in a
specific path, that then takes care of handling all the sub-paths.
Hence, any path that starts with "https://stackoverflow.com/"
will be handled by that StaticFiles
application, and due to specifying html=True
in the arguments, index.html
will be automatically loaded; regardless of creating a separate endpoint pointing to the root path /
and trying to return something else, as demonstrated in the example given in your question.
Important
If, for example, you moved app.mount("/",StaticFiles(...
line after defining your @app.get("/")
endpoint, you would see that order matters and index.html
would not be automatically loaded anymore, as endpoints are evaluated in order. Note that, in your case, you might get an Internal Server Error
, as your @app.get("/")
endpoint would be called and attempt to find custom.html
, but if this file exists under 'static'
directory (as shown from your code) and not under "https://stackoverflow.com/"
, you would then get a File does not exist
error, and you should instead return FileResponse('static/custom.html')
.
Even if you removed html=True
, but keep StaticFiles
mounted to the root directory (and defined before your "https://stackoverflow.com/"
endpoint), you would get a {"detail":"Not Found"}
error response when attempting to access http://localhost:8000/
. This is because that request is still handled by that application (as mentioned earlier) and you should now need to specify the file that you would like to access, e.g., http://localhost:8000/index.html
. Even if you defined other endpoints in your code (e.g., /register
, /login
, /hello
)—as long as StaticFiles
is mounted to the root directory (i.e., "https://stackoverflow.com/"
) and defined in your code before all other endpoints—all requests to those routes would be handled by StaticFiles
application and lead to a {"detail":"Not Found"}
error response.
The html=True
simply provides an easy way to serve a directory of web content with just one line of code. If you only need to serve static files, such as package docs directory, then this is the way to go. If, however, you need to serve different HTML files that will get dynamically updated, as well as you wish to create additional routes/endpoints, you should have a look at Templates (not FileResponse
), as well as mount your StaticFiles
to a different directory (e.g., /static
), rather than root directory (and without using html=True
).