# Web Analytics

# About

import { LinkButton, Render } from "~/components";

<Render file="web-analytics-definition" product="web-analytics" />

Web Analytics supports Adaptive Bit Rate (ABR). Cloudflare's servers will select the best resolution for each chart or table depending on the size of the data, the date range, your network connection, and other factors. For more information, refer to [Explaining Cloudflare's ABR Analytics](https://blog.cloudflare.com/explaining-cloudflares-abr-analytics/).

The data displayed in Web Analytics is real user monitoring (RUM). For more information, refer to [Real User Monitoring](https://en.wikipedia.org/wiki/Real_user_monitoring).

Cloudflare Web Analytics does not collect or use your visitors’ personal data.

<LinkButton
	variant="primary"
	href="http://dash.cloudflare.com/sign-up/web-analytics"
>
	Get started
</LinkButton>
<LinkButton variant="secondary" href="/web-analytics/data-metrics/">
	Learn more
</LinkButton>

# Changelog

import { ProductReleaseNotes } from "~/components";

Cloudflare occasionally updates the `beacon.min.js` file to improve Web Analytics functionality. The table below includes a log of what changed in the `beacon.min.js` file and when.

{/* <!-- Actual content lives in /src/content/release-notes/web-analytics.yaml. Update the file there for new entries to appear here. For more details, refer to https://developers.cloudflare.com/style-guide/documentation-content-strategy/content-types/changelog/#yaml-file --> */}

<ProductReleaseNotes />

# FAQs

import { Render } from "~/components";

Below you will find answers to our most commonly asked questions. If you cannot find the answer you are looking for, refer to the [community page](https://community.cloudflare.com/) to explore more resources.

- [Errors](#errors)
- [Setup](#setup)
- [Functionality](#functionality)

## Errors

### When I add the beacon to my website and load the webpage, I see an error that includes `is not allowed by Access-Control-Allow-Origin` (CORS). What is happening?

This error usually occurs when the hostname of the site loading the analytics does not match the name of the analytics site configured in the dashboard. Double-check that they are identical.

Cloudflare matches hostnames based on a postfix. For example, if you set up analytics for `example.com`, we will allow analytics from `www.example.com`, `blog.staging.example.com`, and `fooexample.com`. However, we will not allow analytics from `example.com.br`.

You may also see this error if the site does not send a `Referer` or `Origin` header. The `Referer` header is required (do not try to use the `Referrer-policy` header instead). We have a change in-flight now that only the `Origin` header will be required – we believe there is no way to disable that in the browser.

### The analytics beacon is blocked by ad-blockers (including adblockplus, Brave, DuckDuckGo extension, etc). Why is that?

Cloudflare is aware that the analytics beacon is blocked by these services.

While Cloudflare Web Analytics uses a JavaScript beacon, Cloudflare’s edge analytics cannot be blocked because we can measure every request that is received. Edge analytics are available to any customer who proxies traffic through Cloudflare. Currently, users on Pro, Business, and Enterprise plans get advanced web analytics powered by our edge logs.

### Why am I not seeing all the metrics for single-page application (SPA) or multiple-page application (MPA)?

Every route change that occurs in the single-page app will send the measurement of the route before the route is changed to the beacon endpoint. The measurement for the last route change will be sent whenever the user leaves the tab or closes the browser window. That will trigger `visibilityState` to a hidden state. Whenever that happens, Beacon JS sends the payload using the [Navigator.sendBeacon method](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon) that should not be cancelled even when the browser window is closed. However, due to compatibility, old browsers would fallback to using AJAX (`XmlHttpRequest`), which can be cancelled when the browser window is closed, so the last payload that gets sent to the beacon endpoint can be lost. Also, due to various network conditions, there can be data loss when the payload is sent to the beacon endpoint.

### For the same site, why would I see more data reported with an automatic setup?

Unless you are using Rules to control which pages to be measured, using [automatic setup](/web-analytics/get-started/#sites-proxied-through-cloudflare) will inject the JS snippet on all pages (sub-domains) under the zone.

If you used a [manual setup](/web-analytics/get-started/#sites-not-proxied-through-cloudflare) instead, only those pages that render the JS snippet will be reported.

:::note

Since only one JS snippet can be rendered and used per page, you cannot have multiple snippets on the same page.

:::

### My website is proxied through Cloudflare, but Web Analytic's automatic setup is not working.

If you have a `Cache-Control` header set to `public, no-transform`, Cloudflare proxy will not be able to modify the original payload of the website. Therefore, the Beacon script will not be automatically injected to your site, and Web Analytics will not work. Refer to [Origin cache control](/cache/concepts/cache-control/) for more information.

### Why am I getting a `405 Method Not Allowed` error from `/cdn-cgi/rum`?

The `/cdn-cgi/rum` endpoint only accepts `POST` requests for data ingestion. If you send a request using any other HTTP method (for example, `GET`, `PUT`, or `DELETE`), the endpoint returns a `405 Method Not Allowed` response with an `Allow: POST, OPTIONS` header (`OPTIONS` is allowed for [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) support).

The Web Analytics beacon (`beacon.min.js`) always uses `POST` when reporting metrics. If you see `405` errors in your logs, the requests are not coming from the beacon itself.

They are most likely coming from an automated testing tool making erroneous requests, in which case you should correct it to use `POST` or ignore the errors.

We do not support custom integrations directly with the endpoint: all requests should originate from our beacon JavaScript.

### Why am I seeing syntax errors from the beacon script in Internet Explorer?

Internet Explorer 11 was the final version of Internet Explorer and it was [declared completely end-of-life (EOL) in 2022](https://techcommunity.microsoft.com/blog/windows-itpro-blog/internet-explorer-11-desktop-app-retirement-faq/2366549).

Our beacon script targets modern syntax which Internet Explorer does not support. This will cause a non-user-visible error when the script attempts to execute. The only functional impact is that beacons are not collected from these old browsers.

For customers using automatic-injection, Cloudflare adds `type="module"` to the `<script>` tag to prevent loading in Internet Explorer and similarly old, deprecated browsers.

For customers using the manual embed approach, you will need to add `type="module"` to the `<script>` tag manually. Our dashboard has been updated to include this attribute in the installation instructions.

---

## Setup

### I am proxying my site through Cloudflare. Should I manually add the JS beacon?

You can, but you do not have to. Cloudflare Web Analytics is designed primarily for customers who do not use Cloudflare's proxy to measure their web traffic.

Existing Cloudflare customers can access analytics collected from our edge on the **Analytics** tab of the dashboard. You can also enable Web Analytics to measure performance using JavaScript.

Using a domain proxied through Cloudflare with [automatic setup](/web-analytics/get-started/#sites-proxied-through-cloudflare) will report stats back to your own domain's `/cdn-cgi/rum` endpoint. If you have installed JS snippet yourself (a [manual setup](/web-analytics/get-started/#sites-not-proxied-through-cloudflare)), it will report back to `cloudflareinsights.com/cdn-cgi/rum` endpoint.

### Can I add Web Analytics to my site using a tag manager like Google Tag Manager (GTM)?

Yes. Instead of embedding the script using a tag manager as shown here:

```html
<script
	type="module"
	src="https://static.cloudflareinsights.com/beacon.min.js"
	data-cf-beacon='{"token": "$SITE_TOKEN"}'
></script>
```

Add the following script:

```html
<script
	type="module"
	src="https://static.cloudflareinsights.com/beacon.min.js?token=$SITE_TOKEN"
></script>
```

### What do I need to add to my Content Security Policy (CSP)?

If your site implements a Content Security Policy (CSP), you'll need to add some entries to this HTTP header to allow browsers to download the beacon script and transmit beacons to Cloudflare.

**Warning:** be sure to validate any CSP changes on a test environment before releasing an update to your production environment. You may wish to use [Content Security Rules](https://developers.cloudflare.com/client-side-security/rules/) or trial with `Content-Security-Policy-Report-Only` first.

You'll first need to permit our script to execute by adding it to your `script-src` directive:

```
script-src [...existing values...] https://static.cloudflareinsights.com/beacon.min.js
```

_Note: if you have a query string in the script as per the example above for Google Tag Manager, then you'll need to include this in the URL too, e.g. `script-src [...existing values...] https://static.cloudflareinsights.com/beacon.min.js?token=$SITE_TOKEN`_

Secondly, you'll need to permit the endpoint we transmit the beacon data to.

For automatic injection, this will be the same domain, so ensure your `connect-src` includes `'self'`:

```
connect-src [...existing values...] 'self'
```

For manual embedding, this script instead connects to `cloudflareinsights.com`, so ensure that's included instead:

```
connect-src [...existing values...] cloudflareinsights.com
```

### How can I enforce Subresource Integrity (SRI) with the JS beacon? 

If you're using the automated injection (i.e. not the manually-embedded script approach mentioned above), Cloudflare automatically includes an `integrity` attribute in the `<script>`. This ensures the script will only execute if a local hash of its downloaded contents match the integrity hash supplied in the HTML.

Unfortunately, if you're using the manually-embedded script approach, there is no current way to safely apply an `integrity` attribute because we do not support version-pinning our beacon script. We do this because it ensures we can release periodic updates to maintain security, address bugs and ensure 

### Can I use the same JS Snippet for a different domain?

No. However, if the apex domain (also known as "root domain" or "naked domain") is the same, you can use the same site tag. For example, if you have provided us a hostname `example.com` when registering a site, you can use the JS snippet from that site for `abc.example.com` and `def.example.com` since they use the same apex domain. When payload gets sent to the beacon endpoint, we validate the hostname with postfix matching, so if your domain shares the same apex domain, that would work.

### Can I use automatic setup with a DNS-only domain (CNAME setup)?

No, you can only use the [automatic setup](/web-analytics/get-started/#sites-proxied-through-cloudflare) with JS snippet injection if traffic to your domain is proxied through Cloudflare (orange-clouded).

If you have a DNS-only domain, you will have to do a [manual setup](/web-analytics/get-started/#sites-not-proxied-through-cloudflare) instead.

### What prevents the JS Snippet from being added to a page?

<Render file="web-analytics-troubleshooting" product="web-analytics" />

### Can I use Real User Monitoring (RUM) with Cloudflare Workers?

Cloudflare's Real User Monitoring (RUM) operates exclusively on the initial client request and cannot collect metrics from Worker subrequests. This is a fundamental architectural limitation designed to ensure accurate performance measurements and prevent duplicate or misleading analytics data.

---

## Functionality

### Is the data sampled?

We retain unsampled beacon data for the past 7 days, after this point data is aggregated down to around 10%.

When aggregating metrics in the Cloudflare Dashboard or querying the GraphQL API, a level of sampling (between 0.0001% and 100%) will be dynamically selected based on the filters applied and the volume of matching rows. This ensures a high confidence in the accuracy of figures while maintaining a reasonable response time. You can [read more about this approach on the Cloudflare blog](https://blog.cloudflare.com/explaining-cloudflares-abr-analytics/).

Note: the GraphQL API exposes a `sampleInterval` field to indicate which level of sampling has been applied to the query.

* The beacon script will fire on every pageview.
* The data ingestion pipeline does not apply sampling—every received beacon will be recorded.
* We store the unsampled data for 7 days.
* We also aggregate it down so it's around 10% of the original volume for long-term storage.
* Sites with very low traffic volumes are sampled to greater percentages to maintain high confidence in aggregate figures.

### Can I see server-side analytics by URL?

Web Analytics only displays client-side analytics. All Cloudflare customers who proxy their traffic also get analytics based on traffic at their edge.

Currently, users on Pro, Business, and Enterprise plans get advanced HTTP traffic analytics, which is the only way to see features like a breakdown of traffic by URL based on server-side analytics.

### What is the period of time I can access data in Web Analytics?

Currently, you can access data for the previous six months.

### Does Cloudflare Web Analytics support UTM parameters?

Not yet. UTM parameters are special query string parameters that can help track where traffic is coming from.
Currently, Cloudflare Web Analytics do not log query strings to avoid collecting potentially sensitive data, but we may add support for this in the future.

### Does Web Analytics support custom events?

Not yet, but we may add support for this in the future.

### Can I track more than one website with Web Analytics?

Yes. Right now there is a soft limit of ten sites per account, but that can be adjusted by contacting Cloudflare support.

### When does the beacon send metrics to the `/cdn-cgi/rum/` endpoint?

For traditional websites, not Single Page Applications (SPAs), the Web Analytics beacon reports to the `/cdn-cgi/rum/` endpoint when the page has finished loading (load event) and when the user leaves the page. For Single Page Applications, additional metrics are sent for every route change to capture the page load event.

# Cloudflare Web Analytics

import { CardGrid, Description, Feature, LinkTitleCard, Plan, RelatedProduct } from "~/components"

<Description>

Get vital web analytics for your website without compromising user privacy.
</Description>

<Plan type="all" />

Cloudflare Web Analytics helps you understand the performance of your web pages as experienced by your site visitors.

***

## Features

<Feature header="Filters" href="/web-analytics/configuration-options/filters/">

Use filters to refine the data displayed in Web Analytics.


</Feature>

<Feature header="Rules" href="/web-analytics/configuration-options/rules">

Use rules to configure tracking of Web Analytics for specific websites or paths.


</Feature>

<Feature header="Dimensions" href="/web-analytics/data-metrics/dimensions">

Use dimensions to categorize and organize various metrics or data types effectively.


</Feature>

***

## Related products

<RelatedProduct header="Analytics" href="/analytics/" product="analytics">
Cloudflare visualizes the metadata collected by our products in the Cloudflare dashboard.
</RelatedProduct>

<RelatedProduct header="Speed" href="/speed/" product="speed">
Speed allows you to assess the performance of your website and get recommendations of Cloudflare products to enhance the website performance.


</RelatedProduct>

***

## More resources

<CardGrid>

<LinkTitleCard title="Resource hub" href="https://www.cloudflare.com/application-services/products/analytics/" icon="document">
Refer to our latest resources to learn more about security, performance and reliability.
</LinkTitleCard>

<LinkTitleCard title="Cloudflare blog" href="https://blog.cloudflare.com/privacy-first-web-analytics/" icon="open-book">
Read articles about the latest updates about Web Analytics.
</LinkTitleCard>

</CardGrid>

# Limits

Cloudflare limits the number of sites for which you can track web analytics, as well as the number of rules allowed for each plan type. Refer to the following tables for more information.

## Site limits

Cloudflare limits the number of sites for which you can track web analytics when they are not proxied by Cloudflare.

| Site type                      | Limit    |
| ------------------------------ | -------- |
| Not proxied through Cloudflare | 10       |
| Proxied through Cloudflare     | No limit |

:::note
To provide a reliable and fast experience, viewing aggregate data is limited to 1,000 websites in parallel in the dashboard. Customers with large volumes of tracked websites can workaround this restriction by selecting specific websites or using the GraphQL API to extract data.
:::

## Rules limits

Cloudflare limits the number of Web Analytics rules you can have by plan type. For plans with a limit of zero, Web Analytics injects the JS snippet on all subdomains.

Rules are only available for sites proxied through Cloudflare.

| Plan type  | Rules limit |
| ---------- | ----------- |
| Free       | 0           |
| Pro        | 5           |
| Business   | 20          |
| Enterprise | 100         |

# Filters

import { DashButton } from "~/components";

To filter the data shown on Web Analytics:

1. In the Cloudflare dashboard, go to the **Web Analytics** page.

   <DashButton url="/?to=/:account/web-analytics" />

2. Select the website you want to check.
3. Select **Add filter**.
4. In the **New filter** box, choose your criteria from the dropdown. Refer to the [Dimensions](/web-analytics/data-metrics/dimensions/) page for a list of available filters and their descriptions.
5. Select **Apply**.

### Additional tips

- By default, Web Analytics shows data for the previous 24 hours. Adjust the time range using the dropdown menu above the graph.
- Select and drag the cursor on the graph to choose a custom time period.
- Scroll below the graph to view detailed breakdowns, for instance of top visits by country or by device type.

# Configuration options

import { DirectoryListing } from "~/components"

Customize your Web Analytics views by using filters and rules.

<DirectoryListing />

# Rules

import { Render, DashButton } from "~/components";

Use **Rules** to configure whether to track Web Analytics for specific websites or paths. By default, Web Analytics automatically creates a single rule for the zone that injects the JavaScript (JS) snippet for all pages.

Rules are only available for sites proxied through Cloudflare. For more information, refer to [Limits](/web-analytics/limits/).

1. In the Cloudflare dashboard, go to the **Web Analytics** page.

   <DashButton url="/?to=/:account/web-analytics" />

2. Find the site you want to configure and select **Manage site**.
3. Select **Advanced options** > **Add rule**.
4. Select the **Action** and fill in the hostname and path(s) you want to add a rule for.
5. If you want to add additional rules, select **Add rule**. Otherwise select **Update** to save the rule.

<Render file="configuration-rule-wins-over-rum-rule" product="rules" />

# Core Web Vitals

import { DashButton } from "~/components";

[Core Web Vitals](https://www.cloudflare.com/learning/performance/what-are-core-web-vitals/) are high-level metrics designed to measure the perceived performance of websites and web applications.

Three core Web Vitals metrics are measured: Largest Contentful Paint, Interaction to Next Paint, and Cumulative Layout Shift. Each of these metrics is automatically assigned a rating of Good, Needs Improvement, or Poor based on the thresholds defined by Google.

## Access Core Web Vitals

Core Web Vitals enables you to easily pinpoint which elements in a web page are affecting the user's experience while browsing your website, in a visual form. To access Core Web Vitals:

1. In the Cloudflare dashboard, go to the **Web Analytics** page.

   <DashButton url="/?to=/:account/web-analytics" />

2. Select your website and select **Core Web Vitals**.

###  Core Web Vitals metrics

Core Web Vitals is divided into three main sections, each one with information about a specific feature that affects user experience:

- [Largest Contentful Paint (LCP)](https://web.dev/optimize-lcp/): Measures perceived load speed by the user — how long the main content of the page takes to be loaded.
- [Interaction to Next Paint (INP)](https://web.dev/inp/): Measures user interface responsiveness – how quickly a website responds to user interactions like clicks, taps or key presses.
- [Cumulative Layout Shift (CLS)](https://web.dev/optimize-cls/): Measures visual stability — to what extent there are unexpected shifts in the page layout during and after page load.

:::note

Currently, Cumulative Layout Shift is only supported in Chromium browsers, Firefox and Safari have not implemented [support for the Layout Instability API](https://caniuse.com/wf-layout-instability).

:::

Each of these metrics represents an impact to the user experience, which is quantified and graded by Web Analytics.

Cloudflare Web Analytics offers interactive exploration in Core Web Vitals by allowing you to filter data by URL, Browser, Operating System, Country, Element and more.

### Sub-parts

To support deeper investigation, the LCP and INP metrics are broken down into their respective sub-parts.

LCP is broken into four phases, so you can see which one is impacting your perceived load time:

1. **Time to First Byte:** how long the browser waits for the HTML document.
2. **Resource load delay:** how long the browser takes to discover the LCP resource after the document starts arriving.
3. **Resource load duration:** how long it takes to download that resource.
4. **Element render delay:** the gap between the resource arriving and the element appearing on screen.

![LCP sub-parts visual in the dashboard](~/assets/images/web-analytics/dash-web_analytics-lcp-sub-parts.png)

INP is broken into three phases, guiding you to the area slowing down responsiveness:

1. **Input delay:** how long an interaction (click, tap or key press) is blocked before it can be processed.
2. **Processing duration:** how long your event handlers take to run.
3. **Presentation delay:** how long the browser takes to render the next frame after the handlers finish.

![INP sub-parts visual in the dashboard](~/assets/images/web-analytics/dash-web_analytics-inp-sub-parts.png)

### Debug view

The 'Debug View' section has the top five elements with a negative impact on each metric. Selecting the elements shown in the data table gives you more details about them.

Each table — LCP, INP, and CLS — also shows you the performance of these elements in the 75th percentile (P75) at a glance. Selecting in each row of the table lets you expand the element and have access to more information, including P50, P90 and P99 metrics.

These numbers refer to how an element performs relatively to others in your page. For example, if an element takes 3,900 ms to load and is in the 75 percentile, this means that it is slower to load than 75% of the elements in your page.

![Debug View page](~/assets/images/web-analytics/core-web-vitals-debug-view.png)

## Information collected

Web Analytics uses its lightweight JavaScript beacon to collect the information Vitals Explorer uses. It does not use any client-side state, such as cookies or `localStorage`, to collect usage metrics. Vitals Explorer also does not fingerprint individuals via their IP address, User Agent string, or any other data.

### Common data collected for all Core Web Vitals metrics

#### Element

A CSS selector representing the DOM node. With this string, you can use `document.querySelector(<element_name>)` in the dev console of your browser to find out which DOM node has a negative impact on your scores/values.

#### Path

The URL path at the time the Core Web Vitals are captured.

#### Value

[The metric value](https://web.dev/cls/#layout-shift-score) for each Core Web Vitals. This value is in milliseconds for LCP or INP and a score for CLS.

### Additional data collected for Largest Contentful Paint

#### URL

The source URL (such as image, text, web fonts).

#### Size

The source object's size in bytes.

### Additional data collected for Cumulative Layout Shift

Layout information is a JSON value that includes width, height, x axis position, y axis position, left, right, top, and bottom. These values represent the layout shifts that happen on the page.

#### CurrentRect

Captures the layout information of the DOM element with the largest area, after the shift in the page has occurred. This JSON value is shown as **Current** in the **Debug View** section. To access it, scroll to the **Cumulative Layout Shifts (CLS)** graphic > **Debug View**. Select any element from that table to access the **Layout Shifts** section, where **Current** is presented.

#### PreviousRect

Captures the layout information of the DOM element with the largest area, before the shift in the page has occurred. This JSON value is shown as **Previous** in the **Debug View** section. To access it, scroll to the **Cumulative Layout Shifts (CLS)** graphic > **Debug View**. Select any element from that table to access the **Layout Shifts** section, where **Previous** is presented.

# Data origin and collection

import { GlossaryTooltip } from "~/components"

Web Analytics relies on the `performance.getEntriesByType('navigation')` object to collect metrics about page load performance. If Navigation Timing Level 2 is not supported, then [`performance.timing` (Level 1)](https://developer.mozilla.org/en-US/docs/Web/API/Performance/timing) is used.

Refer to the [W3C Processing Model](https://www.w3.org/TR/navigation-timing-2/#processing-model) for a visual depiction of the sequence of timing events for web page loads.

## Data collection and reporting

Web Analytics collects the minimum amount of information - timing metrics - to show customers how their websites perform. Cloudflare does not track individual end users across our customers’ Internet properties.

The Web Analytics performance beacon loads from `https://static.cloudflareinsights.com/beacon.min.js`. You may need to update your <GlossaryTooltip term="content security policy (CSP)" link="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP">Content Security Policy (CSP)</GlossaryTooltip> settings to load this script.

Beacon data is sent to `https://<yourdomainname>/cdn-cgi/rum` for sites proxied through Cloudflare or `https://cloudflareinsights.com/cdn-cgi/rum` for sites not proxied through Cloudflare. Core Web Vital metrics are reported when the `visibilityState` is hidden for the first time after the page load event is triggered.

# Dimensions

Dimensions are the labels used to describe different types of metrics or data. For example, **Referer** is the data collected from external links referring visits to a page, while **Browser** shows which browsers accessed your website.

Below you can find a list of the different dimensions you can use to filter Web Analytics:

- **Country**: The visitor's country.
- **Host**: The domain of the site's URL.
- **Path**: The links within your site referring visits to a page.
- **Referer**: The external links referring visits to a page. You can access `referer host` data on the dashboard. Additionally, you can access data for the `referer path` from the GraphQL API.
- **Device type**: The device visitors use to access a page (for example, desktop, mobile, or tablet).
- **Browser**: The web browser (for example, Chrome, Safari) visitors use to access your website.
- **Operating system**: The operating system visitors use to access a page.
- **Site**: The website's domain name. Used for high-level segmentation of data. For example, you can use it for a particular zone or gray-clouded website.
- **Exclude Bots**: Exclude bot traffic from the dataset. With this dimension set to `Yes`, the resulting dataset will be a closer representation of real user traffic.
- **Navigation type**: Which method was used to load the HTML document. Refer to [Navigation types](#navigation-types) for a breakdown.

![Web Analytics dimensions page](~/assets/images/web-analytics/dash-web_analytics-dimensions.png)

## Navigation types

| Type                    | Cache hit? | Explanation |
| ----------------------- | ---------- | ----------- |
| Navigate                | ❌         | The visitor clicked a link or submitted a form but the document was either not found or stale in the browsers HTTP cache, so a network request was made to load the document. |
| Navigate Cache          | ✅         | The visitor clicked a link or submitted a form and the document was found and fresh within the browsers HTTP cache, so no network request was necessary for the document. |
| Navigate Prefetch Cache | ✅         | The visitor clicked a link or submitted a form and the document has been prefetched into the browsers HTTP cache, so no network request was necessary for the document. |
| Prerender               | ✅         | The visitor clicked a link or submitted a form but the browser had already prerendered the page, so no network request was necessary for the document. |
| Reload                  | ❌         | The visitor reloaded the page but the document was either not found or stale in the browsers HTTP cache, so a network request was made to load the document. |
| Reload Cache            | ✅         | The visitor reloaded the page and the document was found and fresh within the browsers HTTP cache, so no network request was necessary for the document. |
| Back-forward            | ❌         | The visitor used the back/forward buttons/gestures in their browser but the previously-loaded document either not found or stale in the browsers HTTP cache OR a feature was used which prevents using the cache (refer to the explanation in [Back/forward cache](https://web.dev/articles/bfcache)), so a network request was made to load the document. |
| Back-forward Cache      | ✅         | The visitor used the back/forward buttons/gestures in their browser and the document was found and fresh within the browsers HTTP cache, so no network request was necessary for the document. |
| Restore                 | ✅         | The browser was able to restore this page, for example when a tab has been paused due to inactivity. |
| Soft Navigation         | N/A        | The visitor clicked a link or submitted a form but JavaScript intercepted the navigation and made a client-side update instead. Measured via [the native Soft Navigation API](https://developer.chrome.com/docs/web-platform/soft-navigations). |
| Routing APIs            | N/A        | The visitor clicked a link or submitted a form but JavaScript intercepted the navigation and made a client-side update instead. Measured via [the Navigation API](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API) or [the History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) when the Soft Navigation API is not supported. |

# High-level metrics

Understanding the key metrics in web analytics is essential for optimizing your website’s performance and user experience. Here are the high-level metrics tracked by Cloudflare Web Analytics:

* **Visits** - A page view that originated from a different website or direct link. Cloudflare checks where the HTTP referer does not match the hostname. One visit can consist of multiple page views.
* **Page views** - A successful HTTP response with a content-type of HTML.
* **Page load time** - The total amount of time required to load the page.
* **[Core Web Vitals](https://www.cloudflare.com/learning/performance/what-are-core-web-vitals/)** - Higher-level metrics designed by Google to capture the user experience more completely.

![Web Analytics overview page](~/assets/images/web-analytics/dash-web_analytics-overview.png)

# Data and metrics

import { DirectoryListing } from "~/components"

In this section, you can find information about the data and metrics available in Web Analytics.

<DirectoryListing />

# Page load time

Page load time summary gives you an overview of how long your web page takes to load, broken down by area. To access Page load time:

1. Go to [Web Analytics](https://dash.cloudflare.com/?to=/:account/web-analytics) from your account home page, and choose a website.
2. Select **Page load time**.

## Components

Below is a list of all the components you can inspect:

### Page load

The total amount of time required to load the page. Note that page load time does not correspond to the sum of the other timings available in Web Analytics. This happens because the page load time also includes timings that are not displayed, such as pre-DNS lookup timings and unattributed gaps between timing metrics.

### DNS (`domainLookupEnd` - `domainLookupStart`)

How long a DNS query takes. This could appear as zero for reused connections or content stored in the local cache (memory or disk).

### TCP (`connectEnd` - `connectStart`)

How long it takes to establish a TCP connection with the server. If using HTTPS, this process includes TLS negotiation time.

### Request (`responseStart` - `requestStart`)

The time elapsed between making an HTTP request and receiving the first byte of the response.

### Response (`responseEnd` - `responseStart`)

The time elapsed between the first byte and the last byte of the received response. Think of this as a resource download time.

### Processing (`domComplete` - `domInteractive`)

How long it took to render the page. This includes loading any resources that block page rendering, including images, scripts, and style sheets. If this number is big, optimize your document architecture, resource size, or configure settings in the Cloudflare Speed app. This document process can be drilled down more with `domInteractive`, `domContentLoadedEventStart`, `domContentLoadedEventEnd`, and `domComplete`.

### Load Event (`loadEventEnd` - `loadEventStart`)

An event triggered by the browser when a document and its resources finish loading. The Load Event duration may be a useful metric if you have additional functions or any logic for the load event.

![Web Analytics load time summary page](~/assets/images/web-analytics/dash-web_analytics-page_load_time.png)

## Data collected for Paint Timings

To make Web Analytics work, Cloudflare collects several types of data points. These are the additional data points collected for Paint Timings:

### First Paint

The time between navigation and when the browser renders the first pixels to the screen.

### First Contentful Paint

Time when the browser renders the first bit of content from the DOM.

# Get started

import { Render, DashButton } from "~/components";

## Sites not proxied through Cloudflare

1. In the Cloudflare dashboard, go to the **Web Analytics** page.

   <DashButton url="/?to=/:account/web-analytics" />

2. Select **Add a site**.
3. In **Set up hostname**, write your website's hostname.
4. Select the message box that appears to choose the hostname you have input and select **Done**.
5. Copy the JS snippet from **Manage site**. This is also where you can later edit the hostname you have just added.
6. (Optional) Select **View Analytics sites** to go back on the Web Analytics interface. If you prefer to continue setting up Web Analytics website, continue reading.
7. Add the JS snippet to any of your website’s HTML pages before the ending body tag.

Web analytics is now set up on your website, but it may take a few minutes for Web Analytics data to appear.

Repeat steps 3-7 for all the websites you want to track with Web Analytics by selecting **Add a site** from Web Analytics. In **Web Analytics Sites**, select **Manage site** inside each website's card to adjust Web Analytics for your site at any time.

For more information on how many sites you can track, refer to [Limits](/web-analytics/limits/).

---

## Sites proxied through Cloudflare

<Render file="web-analytics-proxied-setup" product="web-analytics" />

Your website is now using Web Analytics through the automatic setup, which is enabled by default.

You always have the option to go to **Manage Site** and change the automatic setup to one of the following:

- **Enable, excluding visitor data in the EU** - The JS Snippet will not be injected for visitors from the EU.
- **Enable with JS Snippet installation** - The JS Snippet needs to be installed manually.
- **Disable** - The JS Snippet will not be injected and has been disabled.

Repeat these steps for all of the websites you want to track with Web Analytics. Web Analytics is enabled by default for sites proxied through Cloudflare that previously used Browser Insights. Adjust Web Analytics for your site at any time by selecting **Manage site** from Web Analytics.

For more information on how many sites you can track, refer to [Limits](/web-analytics/limits/).

For more information on how to configure which sites or pages you track with Web Analytics, refer to [Rules](/web-analytics/configuration-options/rules/).

:::caution[Important]

If you have a `Cache-Control` header set to `public, no-transform`, Cloudflare proxy will not be able to modify the original payload of the website. Therefore, the Beacon script will not be automatically injected to your site, and Web Analytics will not work. Refer to [Origin cache control](/cache/concepts/cache-control/) for more information.

:::

---

## Pages projects

Cloudflare Pages offers a one-click setup for Web Analytics:

<Render file="web-analytics-setup" product="pages" />

# Notifications

import { AvailableNotifications, Render } from "~/components";

<Render file="web-analytics-notifications" product="web-analytics" /> <br />
<Render file="get-started" product="notifications" />

<AvailableNotifications product="Web Analytics" />

# Web Analytics for SPAs

Cloudflare Web Analytics automatically tracks user interactions on Single Page Applications (SPAs) via one of the following three methods, depending on which is supported:

1. Using the [Soft Navigations API](https://developer.chrome.com/docs/web-platform/soft-navigations)
2. Listening on `navigate` events via the [Navigation API](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API)
3. By patching the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API)'s `pushState` function and listening to the `onpopstate` event

## Disable SPA measurement

If you want to disable the automatic tracking for SPAs, you can do so by adding the `spa` option with a value of `false` in the data attribute of the script tag, as shown below:

```html
<script
  type="module"
  src="https://static.cloudflareinsights.com/beacon.min.js"
  data-cf-beacon='{"token": "...", "spa": false}'
></script>
```

Note: this requires using [the manual embedding approach](/web-analytics/get-started/#sites-not-proxied-through-cloudflare).

### Google Tag Manager (GTM)

If you are using Google Tag Manager (GTM), you can disable SPA tracking by passing the `spa=false` option via the query string in the script URL:

```html
<script
  type="module"
  src="https://static.cloudflareinsights.com/beacon.min.js?token=...&spa=false"
></script>
```