Visit Tracking¶
Short URL tracks every redirect hit via a lightweight HTTP middleware that runs before Drupal's page cache. This ensures visits are recorded even on cached responses without a full Drupal bootstrap.
How it works¶
- A visitor requests a short URL (e.g.
/promo). - The Redirect module matches the slug and returns a redirect response (301/302/307).
- The
hook_redirect_response_alterhook stamps the response with internalX-Shorturl-NidandX-Shorturl-Langcodeheaders. These headers are cached alongside the response. - On the next request, the
ShortUrlVisitMiddleware(priority 210, above PageCache at 200) detects the redirect response, reads the headers, and inserts a row into theshorturl_visitstable. - The internal headers are stripped before the response reaches the client.
Recorded data¶
Each visit record contains:
| Column | Description |
|---|---|
nid |
The short URL node ID |
langcode |
The language of the translation that was hit |
timestamp |
Unix timestamp of the visit |
referrer |
The HTTP Referer header (up to 2048 chars) |
country_code |
Two-letter ISO country code (requires Smart IP) |
ip_hash |
SHA-256 hash of the visitor's IP address |
Privacy
IP addresses are never stored in plain text. Only a one-way SHA-256 hash is recorded, which cannot be reversed to recover the original IP.
Statistics dashboard¶
Each short URL node has a Statistics tab that displays:
Traffic tab¶
- Line chart of visits over time (7 days, 30 days, or all time)
- Visit history table (24h, 7d, 30d, all time with daily averages)
- Best day (date and count of highest traffic)
Referrers tab¶
- Pie chart of referrer distribution
- Pie chart of direct vs. referred visits
- Top referring sites list
Traffic origin tab¶
- Pie chart of top countries
- Country list with flag emojis, names, and visit counts
Info
The Traffic origin tab requires country data. Without the Smart IP module, it displays a message suggesting installation.
Country detection (Smart IP)¶
Country detection is optional and requires the Smart IP module with a configured data source (e.g. MaxMind GeoLite2-Country binary database).
When Smart IP is installed and configured:
- The middleware calls
SmartIp::query()with the visitor's IP to resolve the country code. - The two-letter ISO code is stored in the
country_codecolumn.
When Smart IP is not installed or the lookup fails:
- The
country_codecolumn is left empty. - Visit tracking continues normally — only the geographic data is missing.
Warning
Smart IP's MaxMind GeoIP2 binary database submodule has a known
PHP 8.1+ compatibility issue
with typed properties. Short URL catches \Throwable (not just
\Exception) to handle this gracefully.
Enabling and disabling¶
Visit tracking can be toggled in the module settings at
/admin/config/shorturl/settings. When disabled, the middleware
is not registered at all — there is zero performance overhead.
The no-store setting controls whether a Cache-Control:
no-store header is added to redirect responses. This prevents
browsers from caching the redirect so that every click is recorded.
Data retention¶
The Visit retention period setting controls how long visit records are kept. When set to a positive number of days (e.g. 90), a cron job automatically deletes records older than the configured period. Set to 0 (default) to retain all records indefinitely.
This helps keep the shorturl_visits table manageable on
high-traffic sites. The purge runs on every cron execution and
deletes records whose timestamp is older than the retention
window.