Skip to main content

Registering Blueprints and URL Prefixes

To organize your application into modules, you can use the Blueprint class to define routes and then register them on a Flask application. This allows you to group related views and apply common URL prefixes or subdomains.

Basic Blueprint Registration

To register a blueprint, create an instance of Blueprint and use the register_blueprint method of your Flask application.

from flask import Flask, Blueprint

app = Flask(__name__)
auth_bp = Blueprint("auth", __name__)

@auth_bp.route("/login")
def login():
return "Login Page"

# Register the blueprint on the app
app.register_blueprint(auth_bp)

Configuring URL Prefixes

You can define a url_prefix when creating the blueprint or when registering it. Registration-time options will override or extend the blueprint's defaults.

# Defined at creation
api_bp = Blueprint("api", __name__, url_prefix="/api/v1")

@api_bp.route("/users")
def get_users():
return "User List"

# Registering with the default prefix: /api/v1/users
app.register_blueprint(api_bp)

# Overriding the prefix at registration: /v2/users
app.register_blueprint(api_bp, url_prefix="/v2", name="api_v2")

Using Subdomains

To use subdomains with blueprints, you must first enable subdomain_matching on the application and set a SERVER_NAME.

app = Flask(__name__)
app.config["SERVER_NAME"] = "example.test"
app.subdomain_matching = True

# Define a blueprint for a specific subdomain
admin_bp = Blueprint("admin", __name__, subdomain="admin")

@admin_bp.route("/")
def admin_index():
return "Admin Panel"

app.register_blueprint(admin_bp)
# This route matches: http://admin.example.test/

Nesting Blueprints

Blueprints can be registered on other blueprints using the register_blueprint method. This creates a hierarchy where URL prefixes and subdomains are concatenated.

parent = Blueprint("parent", __name__, url_prefix="/parent")
child = Blueprint("child", __name__, url_prefix="/child")

@child.route("/")
def index():
return "Nested Index"

# Nest the child blueprint inside the parent
parent.register_blueprint(child)

# Register the parent on the app
app.register_blueprint(parent)
# The resulting URL is: /parent/child/

When nesting subdomains, the child subdomain is prepended to the parent subdomain (e.g., child.parent.example.test).

Registering the Same Blueprint Multiple Times

You can register the same Blueprint object multiple times with different configurations by providing a unique name during registration. This is useful for versioning or reusing logic under different paths.

bp = Blueprint("bp", __name__)

@bp.route("/")
def index():
return "Index"

# Register twice with different names and prefixes
app.register_blueprint(bp, url_prefix="/a", name="instance_a")
app.register_blueprint(bp, url_prefix="/b", name="instance_b")

# Endpoints will be 'instance_a.index' and 'instance_b.index'

Troubleshooting and Constraints

  • No Dots in Names: Blueprint names (the name parameter in the constructor) cannot contain a dot (.) character.
  • No Self-Registration: A blueprint cannot be registered on itself. This will raise a ValueError.
  • Duplicate Names: Registering two different blueprints with the same name, or the same blueprint twice without providing a unique name override, will raise a ValueError.
  • Post-Registration Setup: You cannot call setup methods (like @route, @errorhandler, or record) on a blueprint after it has been registered on an application. Doing so will raise an AssertionError. Ensure all routes and handlers are defined before calling app.register_blueprint().
  • Static Files: If a blueprint does not have a url_prefix, the application's static route will take precedence, potentially making the blueprint's static files inaccessible. Provide a url_prefix or a unique static_url_path to avoid this.