---
title: "How to add product analytics to a Framer site"
description: "Install Amplitude and track pricing CTA clicks on a Framer site."
canonical: "https://amplitude.com/en-us/build/framer-product-analytics"
---

# How to add product analytics to a Framer site

Install Amplitude and track pricing CTA clicks on a Framer site.

Source: https://amplitude.com/en-us/build/framer-product-analytics

---

# How to add product analytics to a Framer site

Install Amplitude and track pricing CTA clicks on a Framer site. Follow the published-site checks in about 20 minutes.

- Framer
- Published site
- Browser SDK 2
- 20 min

Chris Tam · Last updated 19 October 2026

Framer lets you publish a product website from a visual canvas. Amplitude [product analytics](https://amplitude.com/amplitude-analytics) helps you follow a visitor from reading about the product to choosing a plan.

In this tutorial, you'll instrument a small example site with home, pricing, and thank-you pages. You'll record page views and a plan-selection click, then check that the events reach Amplitude.

A published Framer site that sends page views and `Pricing CTA Clicked` with `plan` and `page_path`. You'll inspect the same visitor's navigation and CTA event in Amplitude.

The example site follows a visitor evaluating a product: the home page introduces it, `/pricing` describes one plan, and a `Start test` button represents the decision to try that plan. For this demo, the button opens `/thank-you` so you can follow the navigation without creating an account or taking a payment.

## Prerequisites

- A Framer site where you can add custom code and publish changes.
- A published home page, `/pricing`, and `/thank-you`. On `/pricing`, add a `Start test` link to `/thank-you`.
- An Amplitude test project and its project API key from [your project settings](https://amplitude.com/docs/apis/authentication). Use the project's US data region for the code below.

[Sign up for free](https://app.amplitude.com/signup) to create a project. Check your project's product access and quotas before moving beyond the test.

## 1. Add the browser snippet

In Framer, open **Settings > Code > Add**. Name the snippet `Amplitude`, set **Placement** to **Start of \<head>**, choose **All pages**, and set **Run** to **Once**. Use the [Amplitude Quickstart's script installation](https://amplitude.com/docs/get-started/amplitude-quickstart) for this site without a build step.

Replace every `AMPLITUDE_API_KEY` with the same project API key. The key is public and has the scope needed for ingestion. Framer injects this value into the published page; keep secret and management keys out of it.

If Amplitude is already installed, merge the additions into that snippet. Keep one SDK loader and one `amplitude.init()` call, including lines added by other Framer tutorials. Use the browser snippet in Framer's site settings, outside an Embed component or canvas preview.

```html
<!-- Framer Settings > Code: Start of <head>, All pages, Once -->
<!-- Keep lines other Framer pages added here: Pricing CTA Clicked listener
(/build/framer-product-analytics), attribution.trackingMethod
(/build/framer-web-analytics), sessionReplay privacyConfig
(/build/framer-session-replay), replay sampling used by heatmaps
(/build/framer-heatmaps), experiment.js (/build/framer-web-experiment),
engagement.js and engagement.plugin() (/build/framer-guides-surveys). -->
<script src="https://cdn.amplitude.com/script/AMPLITUDE_API_KEY.js"></script>
<script>
if (!window.__amplitudeFramerInitialized) {
  window.__amplitudeFramerInitialized = true;
  window.amplitude.add(window.sessionReplay.plugin({ sampleRate: 1 }));
  window.amplitude.init("AMPLITUDE_API_KEY", {
    remoteConfig: { fetchRemoteConfig: true },
    autocapture: {
      attribution: { trackingMethod: ["userProperty", "eventProperty"] },
      fileDownloads: true,
      formInteractions: true,
      pageViews: true,
      sessions: true,
      elementInteractions: true,
      networkTracking: true,
      webVitals: true,
      frustrationInteractions: true
    }
  });
}
</script>
```

This test configuration also starts session replay with `sampleRate: 1`. That requests capture of every eligible session; project settings and quotas still apply. For an analytics-only installation, remove the `sessionReplay.plugin(...)` registration. Before a production rollout, choose the replay sampling and privacy settings you want.

Remote autocapture settings can override individual local options. If the expected page, click, or form events are missing, check **Data > Settings > Autocapture** in the project.

**Why.** Framer can navigate between pages without reloading the document. Running initialization once lets the SDK handle page views across those transitions without adding another listener on every route.

## 2. Publish the three-page flow

Set up the example journey in Framer: give the home page a `View pricing` link to `/pricing`, describe one plan on the pricing page, and add a `Start test` link to `/thank-you`. Publish the site and open its public URL.

The question you'll answer is whether visitors who review the plan click through to try it. That is why the next step records `Pricing CTA Clicked`. For your own site, choose an action such as `Book a demo` or `Contact us`, and update the event name, matching routes, and properties to describe that action.

Keep the three paths consistent with the listener in the next step. This example uses a link as the pricing CTA, so it works across Framer's generated responsive markup.

```text
Framer links
Home CTA: /pricing
Pricing CTA: /thank-you
Thank-you navigation: /
```

## 3. Name the pricing CTA event

Add a second snippet in **Settings > Code**. Set it to **End of \<body>**, **All pages**, and **Once**. Keep the analytics installation from step one.

The delegated listener reads the link destination rather than a generated Framer class or button text. It survives client navigation and copy changes. Capture the click on `window` so the source route is read before Framer handles navigation. Change the route and `plan` value together if your pricing page uses a different plan.

```html
<!-- Framer Settings > Code: End of <body>, All pages, Once -->
<script>
if (!window.__amplitudeFramerCtaListener) {
  window.__amplitudeFramerCtaListener = true;
  window.addEventListener("click", function (event) {
    var link = event.target instanceof Element
      ? event.target.closest("a[href]") : null;
    if (!link) return;
    var destination = new URL(link.href, location.href);
    if (destination.origin === location.origin &&
        destination.pathname === "/thank-you" &&
        location.pathname === "/pricing") {
      window.amplitude.track("Pricing CTA Clicked", {
        plan: "test",
        page_path: location.pathname
      });
    }
  }, { capture: true });
}
</script>
```

`Pricing CTA Clicked` means the visitor clicked the pricing link. It does not mean a payment, account creation, or form submission succeeded.

## 4. Publish and inspect one click

Publish the custom code update, open `/pricing`, and click `Start test` once. Open the same flow again through the home CTA and repeat.

Inspect `Pricing CTA Clicked` in Instrumentation Explorer. Expect one named event with `plan: "test"` and `page_path: "/pricing"` for each click. Repeat after browser Back. Use the explicit `page_path` for the source route; automatic page enrichment can already reflect the thank-you destination. Autocaptured click events can coexist with this named event; use one event definition consistently in your conversion metric.

## Verify it worked

1. **Published site:** use the public Framer URL. Open developer tools and confirm the Amplitude scripts load. Canvas preview isn't the published installation.
2. **Network:** confirm an event ingestion POST succeeds with HTTP 200. For the US endpoint, filter on `api2.amplitude.com`. Requests can be compressed, so use Instrumentation Explorer for event contents.
3. **Instrumentation Explorer:** inspect the event names, properties, and device ID. In Amplitude, find that device in **User Profiles** and check its activity. Use your test project, not another project in the organization.
4. **Custom event:** one pricing CTA click produces one `Pricing CTA Clicked` event with `plan: "test"` and `page_path: "/pricing"`. Check both a direct pricing visit and navigation from home.
5. **Visitor continuity:** the same anonymous device ID follows the visit across the three pages. If you later add sign-in, connect identity at the real authentication boundary.

## Troubleshooting

### The published page has no events

Confirm the snippet is saved, published, assigned to All pages, and uses the intended project key. Check browser console errors and whether an extension blocks the script or ingestion request.

### One navigation produces two page views

Remove duplicate installations from site and page code, tag managers, and components. Keep one init call and let `autocapture.pageViews` track navigation. Inspect a fresh page load after publishing.

### A form event arrives, but no submission arrives at its destination

Form autocapture records an interaction. Configure the native Framer form's destination and its **Redirect** field separately, then verify delivery at that destination. A link on the form layer doesn't configure the success redirect.

### The named event disappears after a redesign

Check the CTA's published `href`. The listener matches a same-origin link to `/thank-you` while the current path is `/pricing`. Update those paths if your routes changed.

### The event fires twice

Keep this listener in one site-wide snippet. Its guard prevents registering it twice in a document, but duplicate installations with different guards still duplicate events.

## Full code reference

For a fresh site, use the initialization snippet from step one followed by this separate end-of-body snippet. If either already exists, merge the changes into it and retain sibling additions.

Full code reference

```html
<!-- Keep lines other Framer pages added here: Pricing CTA Clicked listener
(/build/framer-product-analytics), attribution.trackingMethod
(/build/framer-web-analytics), sessionReplay privacyConfig
(/build/framer-session-replay), replay sampling used by heatmaps
(/build/framer-heatmaps), experiment.js (/build/framer-web-experiment),
engagement.js and engagement.plugin() (/build/framer-guides-surveys). -->
<script src="https://cdn.amplitude.com/script/AMPLITUDE_API_KEY.js"></script>
<script>
if (!window.__amplitudeFramerInitialized) {
  window.__amplitudeFramerInitialized = true;
  window.amplitude.add(window.sessionReplay.plugin({ sampleRate: 1 }));
  window.amplitude.init("AMPLITUDE_API_KEY", {
    remoteConfig: { fetchRemoteConfig: true },
    autocapture: {
      attribution: { trackingMethod: ["userProperty", "eventProperty"] },
      fileDownloads: true,
      formInteractions: true,
      pageViews: true,
      sessions: true,
      elementInteractions: true,
      networkTracking: true,
      webVitals: true,
      frustrationInteractions: true
    }
  });
}
</script>
```

Full code reference

```html
<!-- Framer Settings > Code: End of <body>, All pages, Once -->
<script>
if (!window.__amplitudeFramerCtaListener) {
  window.__amplitudeFramerCtaListener = true;
  window.addEventListener("click", function (event) {
    var link = event.target instanceof Element
      ? event.target.closest("a[href]") : null;
    if (!link) return;
    var destination = new URL(link.href, location.href);
    if (destination.origin === location.origin &&
        destination.pathname === "/thank-you" &&
        location.pathname === "/pricing") {
      window.amplitude.track("Pricing CTA Clicked", {
        plan: "test",
        page_path: location.pathname
      });
    }
  }, { capture: true });
}
</script>
```

## Hand it to your agent

Use this prompt with an agent that can inspect your Framer settings and the published page.

Using Cursor or Claude Code? Paste this prompt

```text
Follow https://amplitude.com/build/framer-product-analytics on my Framer test site.
Merge changes into existing custom code. Preserve the additions listed in its
keep-lines comment, and never delete lines another Amplitude Build page added.
Use one analytics loader and one init call. Create /pricing and /thank-you if
missing, and add a pricing CTA pointing to /thank-you. Ask for the project API
key if it isn't available; never insert a secret or management key. Don't reset
anonymous visitors or double-track autocaptured page views. Check the published
site after saving and publishing custom code. Report events and properties you
observed, separate docs checks from runtime tests, and list unresolved checks.
Track Pricing CTA Clicked only for the same-origin /thank-you link on /pricing.
Treat the event as a click, not a completed signup or successful submission.
```

## What this unlocks

[Session replay](https://amplitude.com/session-replay) lets you inspect a recorded visit around `Pricing CTA Clicked` after replay capture is configured.

[Heatmaps](https://amplitude.com/heatmaps) show aggregate pricing-page interactions after heatmap capture and sufficient traffic are available.

[Experimentation](https://amplitude.com/amplitude-experiment) lets you compare variants using a defined conversion metric, alongside the experiment's exposure event.

[Guides and surveys](https://amplitude.com/guides-and-surveys) let you ask a targeted question on the pricing page after you install the engagement SDK and configure the experience.

## Next steps

[BehaviorFramer session replayReview a visit while keeping form fields masked.](https://amplitude.com/build/framer-session-replay)[FeedbackFramer guides and surveysAsk a question on a specific published page.](https://amplitude.com/build/framer-guides-surveys)

Reference docs

[Amplitude Quickstart →](https://amplitude.com/docs/get-started/amplitude-quickstart)[Browser SDK 2 →](https://amplitude.com/docs/sdks/analytics/browser/browser-sdk-2)[Debug analytics →](https://amplitude.com/docs/analytics/debug-analytics)[API keys and tokens →](https://amplitude.com/docs/apis/keys-and-tokens)[Framer custom code →](https://www.framer.com/help/articles/how-to-add-custom-code/)

Use [Amplitude MCP](https://amplitude.com/mcp) to inspect your project's existing event taxonomy before naming custom events.

Amplitude is the leading [all-in-one analytics platform](https://amplitude.com/) for building better products. Product and engineering teams use Amplitude to connect [product analytics](https://amplitude.com/amplitude-analytics) and [web analytics](https://amplitude.com/web-analytics) with [session replay](https://amplitude.com/session-replay), [heatmaps](https://amplitude.com/heatmaps), [experimentation](https://amplitude.com/amplitude-experiment), [feature flags](https://amplitude.com/feature-management), and [guides and surveys](https://amplitude.com/guides-and-surveys) in one unified workflow, with [AI agents](https://amplitude.com/ai-agents) working across all of it. Learn how Amplitude is building [self-improving products](https://amplitude.com/self-improving-products) with [Wave](https://amplitude.com/wave), helping teams turn product data into PRs.

For agents

[View raw .md](/build/framer-product-analytics.md)[llms.txt](/llms.txt)

## Ship the instrumentation, then read the data

Once events are flowing, build a funnel for your pricing flow and use the checks above to verify the additional products you enable.

[Create a free account](https://app.amplitude.com/signup)[Browse all Build tutorials](https://amplitude.com/build)
