Integration Guides

Flask

Add Rybbit analytics to your Flask app

Flask renders Jinja templates, and most apps extend a shared base layout, so the snippet goes into that layout's <head>. Flask exposes app.config to every template as config, so store the site ID there and reference it from the template.

Get your tracking snippet

In your Rybbit dashboard, open Site Settings → Tracking Script and copy your snippet. It looks like this:

<script src="https://app.rybbit.io/api/script.js?siteId=YOUR_SITE_ID" defer></script>

YOUR_SITE_ID is the numeric ID of your site. If you self-host Rybbit, app.rybbit.io is the domain of your own instance.

Add the snippet to Flask

Configure the site ID

Flask loads any environment variable prefixed with FLASK_ into app.config when you call from_prefixed_env(). Set the values in your environment (flask run also reads a .env file when python-dotenv is installed):

FLASK_RYBBIT_INSTANCE_URL=https://app.rybbit.io
FLASK_RYBBIT_SITE_ID=YOUR_SITE_ID

Then load them where you create the app:

from flask import Flask, render_template

app = Flask(__name__)
app.config.setdefault("RYBBIT_INSTANCE_URL", "https://app.rybbit.io")
app.config.from_prefixed_env()


@app.route("/")
def index():
    return render_template("index.html")

from_prefixed_env() parses values as JSON where it can, so a numeric site ID arrives as an int. It renders the same in the template.

If you keep configuration in a Python file or class instead, add RYBBIT_INSTANCE_URL and RYBBIT_SITE_ID there and load it with app.config.from_object().

Add the tag to your base layout

Open the template that your pages extend, usually templates/base.html (or templates/layout.html), and add the tag inside <head>:

<head>
    <meta charset="utf-8">
    <title>{% block title %}My App{% endblock %}</title>

    {% if config.RYBBIT_SITE_ID %}
    <script src="{{ config.RYBBIT_INSTANCE_URL }}/api/script.js?siteId={{ config.RYBBIT_SITE_ID }}" defer></script>
    {% endif %}
</head>

config is part of Flask's standard template context, so no context processor is needed. The {% if %} guard skips the tag when RYBBIT_SITE_ID is unset, so local development is not tracked unless you set the variable.

Templates that do not extend the base layout need the same tag in their own <head>.

Verify installation

Open your live site in a new tab and click through a few pages. Within a few seconds the pageviews appear in the Rybbit dashboard.

If nothing shows up:

  • View the page source and search for script.js?siteId= to confirm the snippet is on the page.
  • Open the browser Network tab and check that script.js returns 200 and that POST requests go to /api/track.
  • Disable ad blockers, or set up a proxy so the script loads from your own domain.
  • See the script troubleshooting guide for other common causes.

Troubleshooting

  • Tag missing: from_prefixed_env() reads the environment when the app is created, so restart the server after changing FLASK_RYBBIT_SITE_ID. Check app.config["RYBBIT_SITE_ID"] in flask shell.
  • Macros imported into other templates: config is added to the render context, not to imported templates. A macro that outputs the tag must be imported with context.
  • Content Security Policy: if you set one with Flask-Talisman or similar, add your Rybbit host to script-src and connect-src, or proxy the script through your own domain.
  • Self-hosted instance: set FLASK_RYBBIT_INSTANCE_URL to your own domain without a trailing slash; the template appends the script path to it.

Next steps

On this page