Uploaded: Dec. 5 2025 | Modified: Dec. 5 2025
3 Ways to Render Jinja Templates in Flask (Beginner-Friendly Guide)
Flask makes it extremely easy to render Jinja templates—whether they are stored inside your templates folder, built directly as inline HTML strings, or extracted from macros inside template files.
In this guide, you’ll learn the three most common ways to render Jinja templates in Flask, complete with examples and explanations for beginners.
1. render_template() — Render Template Files
render_template() is the most common and recommended way to render templates stored inside your /templates directory.
Example directory structure:
home.html
<h1>Home Page</h1>
<p>A paragraph...</p>
run.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('home.html')
When Should You Use render_template()?
- When rendering external HTML/Jinja template files
- When building real Flask web pages
- When you want cleaner and reusable code
2. render_template_string() — Render Inline Template Strings
render_template_string() allows you to write HTML templates directly in Python instead of a separate file.
This is useful for testing, quick demos, or simple responses.
from flask import Flask, render_template_string
app = Flask(__name__)
@app.route('/')
def home():
return render_template_string("""
<h1>Home Page</h1>
<p>A paragraph...</p>
""")
When Should You Use This?
- Small HTML outputs
- Temporary debugging
- Dynamic email/template rendering in backend logic
Avoid Using It For:
- Full web pages
- Large HTML templates (use real template files instead)
3. get_template_attribute() — Render Specific Template Parts (Macros)
This function is used to load and execute a specific macro from a Jinja template file.
Example: You have multiple forms inside a template file, and you want to reuse them across routes.
/templates/forms.html
{% macro login_form() %}
<form action="/login" method="post">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<button type="submit">Log In</button>
</form>
{% endmacro %}
{% macro signup_form() %}
<form action="/signup" method="post">
<input type="email" name="email" placeholder="Email">
<input type="password" name="password" placeholder="Password">
<button type="submit">Sign Up</button>
</form>
{% endmacro %}
app.py
from flask import Flask, get_template_attribute
app = Flask(__name__)
@app.route('/login')
def login():
macro = get_template_attribute('forms.html', 'login_form')
return macro() # call the macro
@app.route('/signup')
def signup():
macro = get_template_attribute('forms.html', 'signup_form')
return macro()
When Should You Use This?
- When reusing Jinja macros
- When generating reusable HTML components
- When you need to call template functions directly from Python code
Summary Table
| Method | Best Use Case | Example |
|---|---|---|
render_template() |
Rendering template files | render_template('home.html') |
render_template_string() |
Inline HTML, small content | render_template_string("<h1>Hello</h1>") |
get_template_attribute() |
Calling Jinja macros | get_template_attribute('forms.html', 'login_form')() |
FAQs About Rendering Templates in Flask
1. Where should I store my Flask Jinja templates?
Flask automatically looks for templates inside the /templates folder.
Make sure all your .html or Jinja template files are inside that directory.
2. Can I pass variables to templates?
Yes! You can pass data using keyword arguments.
return render_template('home.html', name="John")
Inside template:
<p>Hello, {{ name }}!</p>
3. Which method is best for real applications?
Always use render_template() for actual projects.
It keeps your code clean, organized, and scalable.
4. When should I avoid render_template_string()?
Avoid it for full page layouts—it becomes messy, hard to read, and difficult to maintain.
5. What is a Jinja macro?
A macro is a reusable HTML block (like a component).
You can reuse it across templates or call it using get_template_attribute().