Template in FastAPI

In FastAPI, templates are commonly used to render HTML pages dynamically. FastAPI supports templates through libraries like Jinja2, which allows you to inject dynamic content into HTML files.

Installing Jinja2

pip install jinja2
Python

Setting Up Templates in FastAPI

You need to use Jinja2Templates from fastapi.templating and set up a templates directory.

Project Structure

/my_project
-- main.py
-- templates/
│   ├── index.html
│   ├── about.html
Python

Example

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from starlette.responses import HTMLResponse

app = FastAPI()

# Initialize Jinja2 templates
templates = Jinja2Templates(directory="templates")

@app.get("/", response_class=HTMLResponse)
async def home(request: Request):
    return templates.TemplateResponse("index.html", {"request": request, "title": "Home Page", "message": "Welcome to FastAPI!"})

@app.get("/about", response_class=HTMLResponse)
async def about(request: Request):
    return templates.TemplateResponse("about.html", {"request": request, "title": "About Us", "message": "This is the about page."})
Python

Creating Template Files

Inside the templates/ folder, create index.html and about.html.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ title }}</title>
</head>
<body>
    <h1>{{ message }}</h1>
</body>
</html>
Python

about.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ title }}</title>
</head>
<body>
    <h1>{{ message }}</h1>
</body>
</html>
Python

Passing Dynamic Data

You can pass data dynamically using Jinja2 syntax:

<h1>Hello, {{ username }}!</h1>
Python

Modify the route to include the username:

@app.get("/user/{username}", response_class=HTMLResponse)
async def user_profile(request: Request, username: str):
    return templates.TemplateResponse("index.html", {"request": request, "title": "User Profile", "message": f"Hello, {username}!"})
Python

Now, visiting /user/John will render:

Hello, John!
Python

Using Template Inheritance

Instead of repeating HTML structures, use Jinja2 template inheritance.

base.html (Parent Template)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
    <header>
        <h1>My Website</h1>
        <nav>
            <a href="/">Home</a> | <a href="/about">About</a>
        </nav>
    </header>

    <main>
        {% block content %}{% endblock %}
    </main>
</body>
</html>
Python

index.html (Child Template)

{% extends "base.html" %}

{% block title %}Home{% endblock %}

{% block content %}
    <h2>Welcome to FastAPI with Jinja2 Templates</h2>
{% endblock %}
Python

Now, index.html inherits the structure from base.html and overrides only the necessary blocks.

Serving Static Files (CSS, JS, Images)

If you want to serve CSS, JavaScript, or images, create a static/ folder.

Project Structure

/my_project
-- main.py
-- templates/
│   ├── base.html
│   ├── index.html
-- static/
│   ├── styles.css
│   ├── script.js
Python

Register Static Files

Modify main.py:

from fastapi.staticfiles import StaticFiles

app.mount("/static", StaticFiles(directory="static"), name="static")
Python

Link Static Files in Templates

Modify base.html:

<link rel="stylesheet" href="{{ url_for('static', path='styles.css') }}">
Python

Conclusion

  • Jinja2 Templates allow the rendering dynamic HTML pages.
  • Template Inheritance helps avoid redundancy.
  • Static Files can be served easily.

Resource

Leave a Comment