Proxying Flowsery Analytics with FastAPI

Route Flowsery Analytics through your FastAPI server to prevent adblocker interference and capture more accurate visitor data.

1. Install Dependencies

pip install fastapi uvicorn httpx

2. Set Up the Proxy

Add the following to your FastAPI application:

from fastapi import FastAPI, Request
from fastapi.responses import Response
import httpx

app = FastAPI()

def get_client_ip(request: Request) -> str:
    """Resolve the actual visitor IP address"""
    # Prefer X-Real-IP if available
    if x_real_ip := request.headers.get("x-real-ip"):
        return x_real_ip

    # Fall back to X-Forwarded-For
    if x_forwarded_for := request.headers.get("x-forwarded-for"):
        return x_forwarded_for.split(",")[0].strip()

    # Last resort: direct connection host
    return request.client.host if request.client else ""

@app.get("/js/script.js")
async def proxy_script():
    async with httpx.AsyncClient() as client:
        response = await client.get('https://analytics.flowsery.com/js/script.js')
        return Response(
            content=response.content,
            media_type='application/javascript',
            headers={
                'Cache-Control': 'public, max-age=31536000'
            }
        )

@app.post("/api/events")
async def proxy_events(request: Request):
    body = await request.json()

    # Determine the origin from the request or construct it from the base URL
    origin = request.headers.get('origin') or str(request.base_url).rstrip('/')

    # Resolve visitor IP for accurate geolocation
    client_ip = get_client_ip(request)

    async with httpx.AsyncClient() as client:
        response = await client.post(
            'https://analytics.flowsery.com/events',
            json=body,
            headers={
                'Content-Type': 'application/json',
                'User-Agent': request.headers.get('user-agent'),
                'Origin': origin,
                'x-flowsery-ip': client_ip
            }
        )
        return Response(
            content=response.content,
            media_type='application/json',
            status_code=response.status_code
        )

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

Note: If your application already has an /api/events endpoint, use the data-api attribute on the Flowsery Analytics script tag to direct events to a different path. For example, data-api="/flowsery-events" sends data to /flowsery-events instead.

Important: If every visitor appears to be in the same location in your dashboard, confirm that the x-flowsery-ip header is being set to the real visitor IP (not the proxy server IP) when forwarding requests to the Flowsery Analytics /events endpoint.

3. Modify the Script Tag

Replace the original Flowsery Analytics snippet with the proxied version:

<script defer data-fl-website-id="flid_******" data-domain="your_domain.com" src="/js/script.js"></script>

4. Deploy

After deploying your server, the proxy configuration activates automatically.

Confirming It Works

To validate that the proxy is functioning correctly:

  1. Navigate to your website
  2. Open your browser's developer tools and switch to the Network tab
  3. Verify that analytics requests are served from your domain rather than analytics.flowsery.com