Add the tracker
The tracker is a small script served by LogSure at /_care/script.js. It sets no cookies and stores nothing on the visitor's device. It counts pageviews, single-page navigations included, and gives the page window.logsure for events, errors, A/B variants, feature flags, feedback, bug reports, messages and signups.
Each app's page in Settings › Apps has a Setup section with all of the snippets below filled in for that app and your server.
1. Route your app's host to LogSure
On each host the app is served on, send /_care/ to the LogSure server; the rest of the host keeps its own routes. The app stays first-party: its pages talk to their own host. With Caddy:
app.example.com {
handle /_care/* {
reverse_proxy https://logsure.example.com {
header_up Host logsure.example.com
}
}
# … the app's own routes
}
Or with nginx:
location /_care/ {
proxy_pass https://logsure.example.com;
proxy_set_header Host logsure.example.com;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Check the route; expect 200:
curl -sI https://app.example.com/_care/health
2. Add the script to every page
<script defer data-app="acme-notes" data-cfasync="false" src="/_care/script.js"></script>
Without a route, the script also works straight from the LogSure server, cross-origin, for the domains listed on the app:
<script defer data-app="acme-notes" data-cfasync="false" src="https://logsure.example.com/_care/script.js"></script>
| Attribute | |
|---|---|
data-app | The app's id. Needed when several apps share an origin; otherwise the app is found from the page's origin. |
data-hash="true" | Count #hash changes as pages, for hash-routed apps. |
data-manual="true" | Turn automatic pageviews off and send them with logsure.pageview(). |
data-release, data-environment | The release and environment every error report carries; see Tracking errors. |
data-flags="true" | Load the app's feature flags with the page; see Feature flags. |
data-local="true" | Count on localhost, 127.0.0.1 and file: pages too. Without it the script stays quiet there, and in automated browsers. |
The script loads once per page, however often it is included. It sends with sendBeacon where it can and fetch otherwise, never with credentials.
In development
Proxy /_care to LogSure from your dev server, add the dev host (for example localhost:5173) to the app's domains, and add data-local="true" to the script tag. Vite:
// vite.config.js
export default {
server: {
proxy: { '/_care': { target: 'https://logsure.example.com', changeOrigin: true } },
},
};
Next.js:
// next.config.js
module.exports = {
async rewrites() {
return [{ source: '/_care/:path*', destination: 'https://logsure.example.com/_care/:path*' }];
},
};
Pageviews by hand
With data-manual="true", send pageviews yourself, for example with a template URL so that every document counts as one page:
logsure.pageview({ url: '/doc/:id' });
The same page twice in a row counts once. Only the host, the path and the utm_* parameters of a URL are kept; any other query parameter is dropped, and a path segment holding an email address is replaced.
window.logsure
| Function | |
|---|---|
logsure.track(name, props?, value?) | A custom event; see Events and goals |
logsure.pageview({ url?, props? }) | A pageview |
logsure.error(err, props?) | An error your code caught; see Tracking errors |
logsure.variant(key, { id? }) | A promise of an experiment's variant, or null; see A/B tests and feature flags |
logsure.flag(key, { id?, score?, attrs?, fallback }) | A feature flag's value, worked out in the page; also flags(), flagDetail() and flagsReady(). See Feature flags |
logsure.feedback(…), logsure.bug(…), logsure.message(…) | Requests for the inbox; see Feedback, bug reports and waitlists |
logsure.waitlist(…) | A waitlist signup |
logsure.form(kind) | The app's own fields for a kind of request, to render a form from |
The earlier names still work: window.care and window.customerCare are the same object, and data-care-event and data-care-prop-* are read as before. If the page already has a plain object under one of these names, the script adds its functions to it without replacing the page's own.