Skip to content

Usage

Two steps, whatever the framework: wire the request-lifecycle half, then call pagebar_html() in your template.

Wiring

from pagebar import PagebarMiddleware
from starlette.applications import Starlette
from starlette.middleware import Middleware

app = Starlette(
    middleware=[Middleware(PagebarMiddleware, package="my-app")],
    routes=[...],
)

Litestar instantiates middleware as cls(app) with no further kwargs, so config has to be baked in. Use PagebarMiddleware.bound(...):

from litestar import Litestar
from pagebar import PagebarMiddleware

app = Litestar(
    middleware=[
        PagebarMiddleware.bound(package="my-app", unsafe=False),
    ],
    route_handlers=[...],
)

.bound(**kwargs) returns a thin subclass with the kwargs baked into __init__. Same fields as the regular constructor. This works for any framework that instantiates middleware as mw_cls(app).

Flask isn't ASGI, so there's no middleware — the pagebar[flask] extra ships a small extension that wires the same data collection into Flask's request lifecycle:

from flask import Flask
from pagebar.flask import Pagebar

app = Flask(__name__)
Pagebar(app, package="my-app", unsafe=app.debug)

Same knobs as PagebarMiddleware. pagebar_html is registered as a Jinja global, so no import is needed in the template. enabled / unsafe callables receive the Flask request here (the ASGI versions get the connection scope).

Template

In your base template, anywhere inside <body>:

{{ pagebar_html() | safe }}
</body>

Under Starlette/FastAPI/Litestar, import pagebar_html and expose it to your template environment (env.globals["pagebar_html"] = pagebar_html); the Flask extension registers it for you.

Content Security Policy

pagebar_html() accepts a nonce keyword that's applied to the inline <style> and <script>:

{{ pagebar_html(nonce=csp_nonce) | safe }}

Otherwise the host needs 'unsafe-inline' for both directives. No external assets, no third-party requests.

Hiding the bar

enabled lets you hide the bar from JSON endpoints, healthchecks, or admin routes:

def show(scope):
    return not scope["path"].startswith(("/api/", "/health"))

Middleware(PagebarMiddleware, package="my-app", enabled=show)

Bots are skipped automatically (User-Agent matching bot|crawler|spider|googlebot|bingbot).