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.