Django
Integrate vTilt with Django — render the SDK in your base template, identify on every authenticated request, send server-side events over HTTP.
There's no native Python SDK yet, but vTilt's wire format is a plain JSON POST so any Python code can emit events. The pattern below covers the two pieces that matter: the Browser SDK (rendered into your Django base template) and a thin Python helper for server-side captures.
#1. Configure settings
# settings.py
import os
VTILT_TOKEN = os.environ['VTILT_TOKEN']
VTILT_HOST = os.environ.get('VTILT_HOST', 'https://www.vtilt.com')python
#2. Pass the user into your base template
Use a context processor so vtilt_context is available in every template render.
# myproject/context_processors.py
from django.conf import settings
def vtilt(request):
user = request.user if request.user.is_authenticated else None
return {
'vtilt_context': {
'token': settings.VTILT_TOKEN,
'host': settings.VTILT_HOST,
'user': {
'id': str(user.id),
'email': user.email,
} if user else None,
}
}python
# settings.py (continued)
TEMPLATES = [{
'OPTIONS': {
'context_processors': [
# ...
'myproject.context_processors.vtilt',
],
},
}]python
#3. Render the SDK in your base template
{# templates/base.html #}
<!doctype html>
<html lang="en">
<head>
<script>
window.__vtilt = {{ vtilt_context|safe }};
</script>
<script>
!(function(t,e){/* ...vTilt loader snippet from Quick start... */})(document, window.vt || []);
vt.init(window.__vtilt.token, {
api_host: window.__vtilt.host,
autocapture: true,
capture_pageview: true,
capture_pageleave: true,
});
if (window.__vtilt.user) {
vt.identify(window.__vtilt.user.id, { email: window.__vtilt.user.email });
}
</script>
</head>
<body>{% block content %}{% endblock %}</body>
</html>django
#4. Server-side capture helper
For events that fire outside a browser session (webhooks, scheduled jobs, server-side conversions), POST directly to vTilt.
# myproject/vtilt.py
import json
from urllib.request import Request, urlopen
from django.conf import settings
def vtilt_capture(distinct_id: str, event: str, properties: dict | None = None) -> None:
payload = json.dumps({
'api_key': settings.VTILT_TOKEN,
'event': event,
'distinct_id': distinct_id,
'properties': properties or {},
}).encode('utf-8')
req = Request(
f'{settings.VTILT_HOST}/api/e',
data=payload,
headers={'Content-Type': 'application/json'},
method='POST',
)
try:
urlopen(req, timeout=2).read()
except Exception:
pass # never block the response on analyticspython
# views.py
from .vtilt import vtilt_capture
def checkout_complete(request):
vtilt_capture(
distinct_id=str(request.user.id),
event='purchase_completed',
properties={'amount': 99.99},
)
return JsonResponse({'ok': True})python
#Next steps
- Identify & alias — anonymous → known user merge.
- Flask integration guide — same Python pattern, smaller framework.
- Event forwarding — fan events out to GA4, Meta CAPI, PostHog.