What Blueprints Solve
A Blueprint is a way to organize a group of related routes, templates, static files, and error handlers as a self-contained component that gets registered onto the main Flask app later, rather than defining every @app.route() directly on a single monolithic app object. This matters once an application grows past a handful of routes — separating auth, admin, and api concerns into their own Blueprint modules keeps each file focused, makes routes easier to test in isolation, and allows the same Blueprint to be registered under different URL prefixes or even reused across multiple projects.
Cricket analogy: A Blueprint is like a franchise's dedicated batting, bowling, and fielding coaching units — each unit is self-contained and specialized, then all are 'registered' together under the same head coach's overall team structure.
# auth/routes.py
from flask import Blueprint, render_template, request
auth_bp = Blueprint('auth', __name__, url_prefix='/auth', template_folder='templates')
@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# authenticate user
pass
return render_template('auth/login.html')
@auth_bp.route('/logout')
def logout():
# clear session
return 'Logged out'Registering Blueprints
A Blueprint does nothing until it's registered with app.register_blueprint(auth_bp), typically inside the application factory, and url_prefix set either on the Blueprint itself or at registration time is prepended to every route defined within it — so @auth_bp.route('/login') with url_prefix='/auth' becomes reachable at /auth/login. Because each registered Blueprint's routes are namespaced by the Blueprint's name for url_for() calls (e.g., url_for('auth.login')), you can safely define a login view in both an auth Blueprint and an admin Blueprint without any naming collision.
Cricket analogy: Registering a Blueprint with a URL prefix is like assigning a franchise a fixed home-ground identifier — every fixture they host is automatically prefixed with their venue code, so there's no ambiguity across teams.
Blueprints can also register their own static and template folders scoped to the Blueprint, which is useful when packaging a Blueprint as a reusable, self-contained component distributed across multiple projects — for example, an admin dashboard Blueprint shipped as an installable package.
Blueprint-Level Hooks and Error Handlers
Blueprints support their own before_request, after_request, and errorhandler decorators scoped only to routes within that Blueprint — @auth_bp.before_request runs before every view in the auth Blueprint but not in admin or api, which is useful for Blueprint-specific concerns like checking that an admin session cookie is present only on admin routes. This scoping avoids polluting a global @app.before_request with conditional logic that branches on URL path to figure out which section of the app is being accessed.
Cricket analogy: A Blueprint-scoped before_request is like a fielding restriction that only applies during the powerplay overs, not the entire innings — the rule is scoped to a specific phase, not applied globally with conditional exceptions.
errorhandler registered directly on a Blueprint only catches exceptions raised within that Blueprint's own view functions by default — it will not catch a 404 for a URL that doesn't match any route at all, since Flask can't know which Blueprint 'should' have handled an unmatched path. Application-wide error pages (like a global 404) still belong on app.errorhandler.
- Blueprints group related routes, templates, static files, and handlers into self-contained, registerable components.
- A Blueprint does nothing until registered via
app.register_blueprint(), typically in the application factory. url_prefixis prepended to every route inside the Blueprint.- Routes are namespaced for
url_for()asblueprint_name.view_name, preventing naming collisions across Blueprints. - Blueprints support their own scoped
before_request,after_request, anderrorhandlerdecorators. - Blueprint-level
errorhandlerdoesn't catch unmatched-route 404s; those remain on the app-level handler. - Blueprints can ship their own
static/templatefolders, useful for reusable, packaged components.
Practice what you learned
1. What must happen before a Blueprint's routes become reachable in a Flask app?
2. If a Blueprint is created with url_prefix='/auth' and defines @auth_bp.route('/login'), what URL serves that view?
3. How does url_for() disambiguate a 'login' view defined in both an 'auth' Blueprint and an 'admin' Blueprint?
4. Does a Blueprint-scoped errorhandler catch a 404 for a URL that matches no route in the entire application?
5. What is a key benefit of scoping before_request to a Blueprint instead of the whole app?
Was this page helpful?
You May Also Like
Flask-SQLAlchemy Basics
Learn how Flask-SQLAlchemy wires the SQLAlchemy ORM into a Flask app, from configuration to sessions.
Querying with Flask-SQLAlchemy
Master filtering, joining, and optimizing database queries using Flask-SQLAlchemy's query interface.
Defining Models in Flask
Learn how to declare Flask-SQLAlchemy models with columns, types, constraints, and relationships.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentgRPC Study Notes
Protocol Buffers · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics
Web DevelopmentNext.js Study Notes
JavaScript · 30 topics