How to Serve HTML in FastAPI: Simple Guide with Examples
To serve HTML in
FastAPI, use HTMLResponse from fastapi.responses or render templates with Jinja2Templates. Return the HTML content or template response from your path operation function to display HTML in the browser.Syntax
Use HTMLResponse to send raw HTML strings or use Jinja2Templates to render HTML templates from files. Import HTMLResponse from fastapi.responses and Jinja2Templates from fastapi.templating. Return the response or template in your route function.
HTMLResponse(content=html_string): Sends raw HTML string as response.templates.TemplateResponse(template_name, context): Renders HTML template with context variables.
python
from fastapi import FastAPI from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from fastapi.requests import Request app = FastAPI() templates = Jinja2Templates(directory="templates") @app.get("/raw-html", response_class=HTMLResponse) async def raw_html(): html_content = "<html><body><h1>Hello from raw HTML!</h1></body></html>" return HTMLResponse(content=html_content) @app.get("/template") async def template(request: Request): return templates.TemplateResponse("index.html", {"request": request, "message": "Hello from template!"})
Example
This example shows how to serve a simple HTML page using both raw HTML string and a Jinja2 template file. The /raw-html route returns HTML directly, while /template renders an HTML file with a message.
python
from fastapi import FastAPI from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from fastapi.requests import Request app = FastAPI() templates = Jinja2Templates(directory="templates") @app.get("/raw-html", response_class=HTMLResponse) async def raw_html(): html_content = "<html><body><h1>Hello from raw HTML!</h1></body></html>" return HTMLResponse(content=html_content) @app.get("/template") async def template(request: Request): return templates.TemplateResponse("index.html", {"request": request, "message": "Hello from template!"})
Output
When visiting /raw-html, the browser shows a page with heading: Hello from raw HTML!
When visiting /template, the browser shows the rendered template with message: Hello from template!
Common Pitfalls
- Not setting
response_class=HTMLResponsewhen returning raw HTML causes FastAPI to treat it as plain text. - For templates, forgetting to pass
requestin the context dictionary causes errors. - Incorrect template directory path or missing template files will cause 500 errors.
- Returning raw HTML without proper escaping can cause security issues.
python
from fastapi import FastAPI from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from fastapi.requests import Request app = FastAPI() templates = Jinja2Templates(directory="templates") # Wrong: missing response_class for raw HTML @app.get("/wrong-raw-html") async def wrong_raw_html(): return "<h1>Missing HTMLResponse</h1>" # Correct: specify response_class @app.get("/correct-raw-html", response_class=HTMLResponse) async def correct_raw_html(): return "<h1>Correct HTMLResponse</h1>" # Wrong: missing request in template context @app.get("/wrong-template") async def wrong_template(): return templates.TemplateResponse("index.html", {"message": "Missing request"}) # Correct: include request @app.get("/correct-template") async def correct_template(request: Request): return templates.TemplateResponse("index.html", {"request": request, "message": "With request"})
Quick Reference
Summary tips for serving HTML in FastAPI:
- Use
HTMLResponsefor raw HTML strings. - Use
Jinja2Templatesfor rendering HTML files. - Always pass
requestto templates. - Set
response_class=HTMLResponsewhen returning raw HTML. - Keep templates in a dedicated directory like
templates/.
Key Takeaways
Use HTMLResponse to send raw HTML strings with proper response class.
Render HTML templates with Jinja2Templates and always pass the request object.
Set response_class=HTMLResponse when returning raw HTML to avoid plain text display.
Keep your HTML templates in a dedicated folder and configure Jinja2Templates accordingly.
Avoid common mistakes like missing request in template context or wrong response class.