Skip to main content
FastAPI Docs

Search documentation

Type to search this documentation.

On this pageOverview

Templates

You can use any template engine you want with FastAPI.

A common choice is Jinja2, the same one used by Flask and other tools.

There are utilities to configure it easily that you can use directly in your FastAPI application (provided by Starlette).

Add jinja2 to your project:

console
$ uv add jinja2

---> 100%
  • Import Jinja2Templates.
  • Create a templates object that you can reuse later.
  • Declare a Request parameter in the path operation that will return a template.
  • Use the templates you created to render and return a TemplateResponse, pass the name of the template, the request object, and a "context" dictionary with key-value pairs to be used inside of the Jinja2 template.
Python
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

app = FastAPI()

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


templates = Jinja2Templates(directory="templates")


@app.get("/items/{id}", response_class=HTMLResponse)
async def read_item(request: Request, id: str):
    return templates.TemplateResponse(
        request=request, name="item.html", context={"id": id}
    )

Then you can write a template at templates/item.html with, for example:

jinja
<html><head>    <title>Item Details</title>    <link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet"></head><body>    <h1><a href="{{ url_for('read_item', id=id) }}">Item ID: {{ id }}</a></h1></body></html>

In the HTML that contains:

jinja
Item ID: {{ id }}

...it will show the id taken from the "context" dict you passed:

Python
{"id": id}

For example, with an ID of 42, this would render:

HTML
Item ID: 42

You can also use url_for() inside of the template, it takes as arguments the same arguments that would be used by your path operation function.

So, the section with:

jinja
<a href="{{ url_for('read_item', id=id) }}">

...will generate a link to the same URL that would be handled by the path operation function read_item(id=id).

For example, with an ID of 42, this would render:

HTML
<a href="/items/42">

You can also use url_for() inside of the template, and use it, for example, with the StaticFiles you mounted with the name="static".

jinja
<html><head>    <title>Item Details</title>    <link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet"></head><body>    <h1><a href="{{ url_for('read_item', id=id) }}">Item ID: {{ id }}</a></h1></body></html>

In this example, it would link to a CSS file at static/styles.css with:

CSS
h1 {    color: green;}

And because you are using StaticFiles, that CSS file would be served automatically by your FastAPI application at the URL /static/styles.css.

For more details, including how to test templates, check Starlette's docs on templates.

Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu