Web Analytics docs
Quick start
Three steps, no backend changes:
Install the script
Paste this line before </head> on every page. Find your SITE_KEY in Site settings → Tracking code. The script loads with defer and never blocks rendering.
Options
Tune collection with data-* attributes on the script tag:
| Attribute | Default | Description |
|---|---|---|
data-site | Required | Your site key. |
data-endpoint | /collect on the fmeng.js origin | Where events are sent. |
data-auto | "true" | Track the first page load and route changes automatically; set to "false" to call fmeng.pageview() yourself. |
data-perf | "true" | Collect page performance; set to "false" to turn it off. |
data-errors | "true" | Collect unhandled JS errors and promise rejections; set to "false" to turn it off. |
data-links | "true" | Collect outbound clicks and file downloads; set to "false" to turn it off. |
data-clicks | "false" | Collect raw click points for heatmaps; off by default, set to "true" to enable. |
data-click-sample | 0.2 | Sampling rate for heatmap clicks, from 0 to 1. |
data-local | "false" | Allow sending from localhost, 127.0.0.1 and file pages — for local testing. |
data-extra | — | Extra data as a JSON object, e.g. {"channel":"wechat"}: sent with every pageview and custom event (up to 20 keys); see Events → Page extra data. For the async snippet use &extra=<URL-encoded JSON>. |
Async loading & multiple sites
The same async pattern as Baidu Tongji hm.js: declare the command queue _fmq, then insert the script dynamically; put the site key in the site parameter (fmeng.js?SITE_KEY also works). Commands pushed before the script loads run once it has loaded, so there is no need to check window.fmeng:
One page can load several sites (for example a site-wide property plus one per section or author): insert one script per site and each site receives its own data. Calls through _fmq and window.fmeng go to every site on the page; use fmeng.get(SITE_KEY) to target one.
Other options can go in the URL too, matching the data-* attributes, e.g. fmeng.js?site=SITE_KEY&clicks=true&click_sample=0.2.
Single-page apps
Single-page apps built on the History API (Vue Router, React Router, …) need no extra code: fmeng.js listens to pushState, replaceState and popstate and records a pageview after each route change, deferred to the next tick so that most frameworks have already updated document.title.
To control it yourself, add data-auto="false" to the script and call fmeng.pageview() once navigation completes; calling it repeatedly for the same URL counts only once.
Custom events
Call fmeng.track(name, properties) on button clicks, form submissions and so on. Event names are up to 64 characters; up to 20 properties are kept, and non-string values are sent as JSON strings.
Break events down by property under Events, turn them into goals in Site settings → Goals, or use them as funnel steps.
User identity
After sign-in, call fmeng.identify(userId) to link the visitor to your user (cross-device identity). IDs are up to 128 characters and stored in the browser. Call fmeng.identify(null) on sign-out to clear it.
Events already queued keep the previous identity. Don't use phone numbers, emails or other personal data as the ID.
What is collected
After installation the following is collected automatically (except click heatmaps, which you enable explicitly). Time on page and scroll depth ride along with pageviews; everything else can be turned off individually:
| Data | Description | How to turn off |
|---|---|---|
| Pageviews | First page load and SPA route changes, with page title and referrer. | data-auto="false" |
| Time on page | Visible time of the page; the increment is sent when the page is hidden or left. | Tracked with pageviews |
| Scroll depth | Maximum scroll percentage per view (viewport bottom ÷ document height). | Tracked with pageviews |
| Performance | LCP, FCP, INP, CLS, TTFB and Load, once per full page load. | data-perf="false" |
| JS errors | Unhandled errors and promise rejections; the same error is reported once per page, up to 10 per page. | data-errors="false" |
| Outbound & downloads | Clicks on cross-origin links, and downloads (download attribute or common file extensions). | data-links="false" |
| Click heatmap | Click positions and elements at the sampling rate, up to 100 per view. | Off by default; enable with data-clicks="true" |
npm module
To control tracking from your bundled code, use createTracker from the ESM module fmeng-sdk; its options mirror the script attributes.
Verify installation
Click "Verify installation" in Site settings → Tracking code, then open any page of your site. The console checks every 3 seconds and shows "Data received. Installation successful" as soon as the first event arrives.
Testing locally
To keep data clean, fmeng.js doesn't send from localhost, 127.0.0.1 or file pages by default. Add data-local="true" while testing locally:
No data? Check in this order
- data-site matches your site key;
- the page is not a local address (or has data-local="true");
- no ad blocker is blocking fmeng.js or /collect;
- the visiting IP or path is not in your exclusion rules.