Important
This release requires database migrations for existing self-hosted installations. Please read the upgrade instructions below. If you're upgrading from v5.3.x or earlier, complete the v5.4.0 upgrade instructions first.
🔥 Major updates
Session replays for Community Edition
Session replays are now available in the self-hosted version of Swetrix. Record visitor sessions, watch how people use your website, and export recordings as MP4 videos.
Recordings are stored in your own private S3-compatible bucket, with support for providers such as AWS S3, Cloudflare R2, Hetzner Object Storage and MinIO. There is no subscription or monthly replay quota in Community Edition. You can choose a retention period of 30 days, 90 days, 1 year or 5 years for each project.
Recording is opt-in, with privacy modes and masking options. Configure storage on your server, then call startSessionReplay() in your tracking setup. Learn more.
Page-title analytics
You can now see which pages people visit by their titles, alongside their URLs. The new Titles view in the Traffic dashboard groups pageviews by page title. Click a title to filter your traffic, combine it with page-path filters, or export the breakdown.
The browser tracker captures document.title automatically. You can override titles or disable their collection through the tracking callback. Older pageviews without a recorded title remain untitled.
Page-title tracking is supported in swetrix-js v4.7.0 and later, and @swetrix/node v3.5.0 and later. Learn more.
Scoped API keys
You can now create separate API keys for your integrations, choose which projects each key can access, and grant permissions for individual resources. For example, give a reporting script read-only access to analytics for one project without allowing it to change project settings.
Manage keys in Account Settings, change their permissions, rotate their secrets, or revoke them. Project owners can also see which keys have access to a project from its settings.
Existing API keys continue to work with their original unrestricted access. Learn more.
Outbound-link tracking
See which external links visitors click on your website. Enable automatic outbound-link tracking and open Traffic → Pages → Outbound links to see destination URLs and click counts. The expanded view also shows visitors and supports search. You can also export outbound-link breakdowns as CSV.
Outbound-link tracking is disabled by default. Enable it with events: { outboundLinks: true } in your tracker's init() options, alongside your existing self-hosted apiURL. Destination query strings and fragments are excluded by default, and you can exclude particular domains or links.
New Plausible imports also preserve outbound-link destinations when they're present in the export. Available with swetrix-js v4.8.0 and later. Learn more.
🙂 Minor changes
- Removed the 50-goal limit in Community Edition. You can now create as many goals per project as you need.
- Redesigned dashboard panel tabs and metadata selectors, making it easier to switch between breakdowns.
- Improved the custom-event details inspector with collapsible metadata groups, sortable values and better handling of long text.
- Chart tooltips now include relative dates, making comparisons easier to read.
- IP whitelist and blacklist inputs now use editable tags.
- Added VR device labels and filtering in the dashboard.
- Error tracking now accepts stack traces up to 64,000 characters.
- Added selective query-parameter and URL-hash tracking: choose which parameters or hash values should be included in page URLs.
- Improved data-import processing, including lower memory use for Plausible archives, clearer errors for oversized exports, and more reliable CSV handling.
- Updated translations and dependencies, including the browser tracking library to v4.8.0.
🔧 Fixes
- Fixed the last-hour traffic summary showing totals since midnight, and corrected rolling date-range and timezone boundaries so summary cards and charts use consistent periods. Thanks to @vlvovch for the contribution!
- Fixed referrer-name filters returning no results in Docker installations because the backend image was missing the referrer map. Thanks to @GOAT0P for the contribution!
- Fixed funnel queries failing on rows with missing page values.
- Fixed analytics ingestion errors when a page value was not a string.
- Fixed chart comparisons failing to load.
- Fixed the error chart not updating when toggling Show resolved.
- Fixed experiments failing to load in password-protected embedded dashboards.
- Fixed signed-in authentication not being preserved when opening project links.
- Fixed IPv6 and CIDR validation in project IP exclusion settings.
- Fixed the goal editor closing unexpectedly when dashboard statistics refresh.
- Fixed metadata dropdowns causing the page to jump when opened.
- Fixed dark-themed websites rendering with an incorrect white background in session playback and MP4 exports.
- Fixed OIDC compatibility with Rauthy, including EdDSA-signed tokens and PKCE.
- Fixed custom events using the original page path instead of the path modified by a pageview callback.
- Fixed API-key management requests being routed incorrectly by the frontend.
Upgrading to the next Swetrix CE release from v5.4.x
Important
Back up your ClickHouse data and configuration before upgrading. Keep your existing SECRET_KEY_BASE; it is also used to encrypt the new API keys. If you already store recordings, back up their storage bucket too.
1. Update your images and configuration
Update both image tags in compose.yaml to the published release version:
- frontend:
swetrix/swetrix-fe:<VERSION> - backend:
swetrix/swetrix-api:<VERSION>
Replace <VERSION> with the release tag, including its v prefix. Use the same version for both services.
Session-replay storage is optional. To enable it, create a private S3-compatible bucket and add these settings to your self-hosting .env file, using values for your provider:
SESSION_REPLAY_S3_ENDPOINT=https://s3.eu-west-1.amazonaws.com
SESSION_REPLAY_S3_BUCKET=swetrix-replays
SESSION_REPLAY_S3_REGION=eu-west-1
SESSION_REPLAY_S3_ACCESS_KEY_ID=your-access-key
SESSION_REPLAY_S3_SECRET_ACCESS_KEY=your-secret-key
SESSION_REPLAY_S3_FORCE_PATH_STYLE=falseThe bucket must already exist, and the credentials must allow reading, writing and deleting its objects. Keep it private; browsers access recordings through Swetrix.
Also add these entries to the existing swetrix-api.environment list in compose.yaml. Adding values to .env alone does not pass them into the API container:
- SESSION_REPLAY_S3_ENDPOINT=${SESSION_REPLAY_S3_ENDPOINT:-}
- SESSION_REPLAY_S3_BUCKET=${SESSION_REPLAY_S3_BUCKET:-}
- SESSION_REPLAY_S3_REGION=${SESSION_REPLAY_S3_REGION:-}
- SESSION_REPLAY_S3_ACCESS_KEY_ID=${SESSION_REPLAY_S3_ACCESS_KEY_ID:-}
- SESSION_REPLAY_S3_SECRET_ACCESS_KEY=${SESSION_REPLAY_S3_SECRET_ACCESS_KEY:-}
- SESSION_REPLAY_S3_FORCE_PATH_STYLE=${SESSION_REPLAY_S3_FORCE_PATH_STYLE:-false}For replay uploads, add the following inside the existing location /backend/ block in nginx/config, and allow the same request size through any additional proxy in front of Swetrix:
client_max_body_size 15m;Ordinary analytics continues to work without replay storage. See the storage setup guide for provider-specific settings and export requirements.
2. Update Redis, ClickHouse and Nginx
This release also updates the infrastructure images. Edit the image entries for these services in your existing compose.yaml:
| Service | Previous image | New image |
|---|---|---|
redis
| redis:8.6-alpine
| redis:8.10.3-alpine
|
clickhouse
| clickhouse/clickhouse-server:25.8-alpine
| clickhouse/clickhouse-server:26.8.36.3-alpine
|
nginx-proxy
| nginx:1.31.1-alpine
| nginx:1.31.8-alpine
|
These updates apply even if you do not enable session replays. ClickHouse moves from 25.8 to the 26.8 LTS release line. Keep your pre-upgrade ClickHouse backup until you have verified the upgraded installation.
The steps below pull all service images, apply the schema migrations while the existing database is running, then recreate the full stack with the updated images. Updating only the Swetrix frontend and API containers will not apply these infrastructure updates.
3. Run the database migrations
From your self-hosting directory, pull the new application images and stop the frontend and API. Keep ClickHouse and Redis running:
docker compose pull swetrix-api swetrix
docker compose stop swetrix-api swetrixRun all four migrations against your existing database using the new API image:
docker compose run --rm --no-deps swetrix-api node migrations/clickhouse/selfhosted_2026_09_12_session_replays.js
docker compose run --rm --no-deps swetrix-api node migrations/clickhouse/2026_09_26_page_titles.js
docker compose run --rm --no-deps swetrix-api node migrations/clickhouse/selfhosted_2026_10_01_api_keys.js
docker compose run --rm --no-deps swetrix-api node migrations/clickhouse/2026_10_13_outbound_links.jsThese create replay metadata storage and its project retention setting, add page-title storage, create the API-key table, and add outbound-link destination storage. Run them even if you do not plan to enable recordings.
Check that each command completes successfully without Query ERROR messages before continuing. The scripts use IF NOT EXISTS, so they can be rerun after a partial upgrade. No MySQL migration is needed for Community Edition.
Fresh installations create the schema automatically. Existing installations still need the replay migration: the startup initialiser does not add sessionReplayRetentionDays to an existing project table.
4. Start Swetrix
docker compose up -d --force-recreate swetrix-api swetrix
docker compose logs --tail=100 swetrix-apiIf you changed the bundled Nginx configuration, validate and reload it:
docker compose exec nginx-proxy nginx -t
docker compose exec nginx-proxy nginx -s reloadCheck that the dashboard loads and accepts a new pageview. If you enabled replay storage, record a short session and check playback and MP4 export. Keep at least one API instance running with IS_PRIMARY_NODE=true for expired-recording cleanup; this is the default in the official API image.
5. Update your tracker and integrations
- Update pinned browser trackers to swetrix-js v4.8.0 or later to use all the new tracking features. For server-side page-title tracking, use @swetrix/node v3.5.0 or later. Updating the dashboard does not update tracker packages installed on your websites.
- Keep your existing self-hosted
apiURL. Enable outbound tracking explicitly and callstartSessionReplay()if you want to record sessions. - Existing UUID-format API keys remain valid and unrestricted. New keys start with
swx_. The oldPOST /user/api-keycreation route now rejects requests; update any key-provisioning scripts to the new/user/api-keysendpoints, which require a signed-in session, or manage keys in Account Settings. A separateAPI_KEY_ENCRYPTION_SECRETis not required. - Previously imported Plausible data is not upgraded automatically. To recover outbound destinations, remove the old import and re-import its original export. Adding another copy without removing the original would duplicate the data.