Plain is headed towards 1.0! Subscribe for development updates →

plain-pageviews

Track pageviews from the client-side.

FAQs

Why not use server-side middleware?

Originally this was the idea. It turns out that tracking from the backend, while powerful, also means you have to identify all kinds of requests not to track (assets, files, API calls, etc.). In the end, a simple client-side tracking script naturally accomplishes what we're looking for in a more straightforward way.

 1import json
 2
 3from plain.views import View
 4from plain.views.csrf import CsrfExemptViewMixin
 5
 6from .models import Pageview
 7
 8
 9class TrackView(CsrfExemptViewMixin, View):
10    def post(self):
11        if getattr(self.request, "impersonator", None):
12            # Don't track page views if we're impersonating a user
13            return 200
14
15        data = json.loads(self.request.body)
16
17        url = data["url"]
18        title = data["title"]
19        referrer = data["referrer"]
20        timestamp = data["timestamp"]
21
22        if user := getattr(self.request, "user", None):
23            user_id = user.pk
24        else:
25            user_id = ""
26
27        if session := getattr(self.request, "session", None):
28            session_key = session.session_key or ""
29        else:
30            session_key = ""
31
32        Pageview.objects.create(
33            user_id=user_id,
34            session_key=session_key,
35            url=url,
36            title=title,
37            referrer=referrer,
38            timestamp=timestamp,
39        )
40
41        return 201