Skip to main content
RapidDev - Software Development Agency
lovable-integrationsEdge Function Integration

How to Integrate Lovable with Google Analytics 4

Add Google Analytics 4 to a Lovable app by loading the gtag.js snippet in your HTML head and creating a Supabase Edge Function that calls the GA4 Measurement Protocol for server-side event tracking. Store your GA4 Measurement ID in Cloud → Secrets as VITE_GA4_MEASUREMENT_ID (public, safe for frontend), and store the GA4 API Secret in Cloud → Secrets for Edge Function use only.

What you'll learn

  • How to inject the GA4 gtag.js snippet into a Lovable Vite+React project for automatic pageview tracking
  • How to send custom events to GA4 using the gtag() function from React components
  • How to create a Supabase Edge Function that calls the GA4 Measurement Protocol for server-side events
  • How to configure GA4 conversion events and build acquisition funnel reports
  • How to use the GA4 Data API via Edge Function to display analytics data inside your Lovable app
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate20 min read30 minutesAnalyticsMarch 2026RapidDev Engineering Team
TL;DR

Add Google Analytics 4 to a Lovable app by loading the gtag.js snippet in your HTML head and creating a Supabase Edge Function that calls the GA4 Measurement Protocol for server-side event tracking. Store your GA4 Measurement ID in Cloud → Secrets as VITE_GA4_MEASUREMENT_ID (public, safe for frontend), and store the GA4 API Secret in Cloud → Secrets for Edge Function use only.

Adding Google Analytics 4 to Your Lovable App

Google Analytics 4 is the most widely used web analytics platform in the world, and for good reason — it provides free, comprehensive data about where your users come from, what they do in your app, and where they leave. For Lovable app builders, GA4 answers acquisition questions that product-focused tools like Mixpanel are not designed for: which marketing channels drive the most signups, which landing pages convert best, and how organic search traffic compares to paid campaigns. GA4's integration with Google Search Console, Google Ads, and Looker Studio makes it the analytical backbone of any app that depends on organic or paid growth.

GA4 uses a dual-layer tracking architecture that maps neatly onto Lovable's security model. The client-side gtag.js snippet loads from Google's CDN and handles all browser-visible events automatically — pageviews, scroll depth, outbound link clicks, and session data. This snippet uses your Measurement ID (a public identifier formatted like G-XXXXXXXXXX) that is safe to embed in frontend code. For backend events — payment completions, API-triggered conversions, and server-side form submissions — GA4's Measurement Protocol allows your Supabase Edge Function to send events directly to Google's collection servers using a secret API key that must stay in Cloud → Secrets.

Lovable's security infrastructure blocks approximately 1,200 hardcoded API keys daily, and GA4's Measurement Protocol API Secret falls squarely in the category of credentials that must never appear in client-side code. The SOC 2 Type II certified Cloud → Secrets panel is the only correct location for this key. Your public Measurement ID, however, can be configured as a VITE_-prefixed build environment variable since it is intentionally public — similar to how the Google Analytics tracking ID has always been embedded in HTML.

Integration method

Edge Function Integration

Google Analytics 4 integrates with Lovable through two complementary layers. The client-side gtag.js snippet loads from Google's CDN and tracks pageviews, scroll depth, and outbound clicks automatically. A Supabase Edge Function uses GA4's Measurement Protocol to send server-side events — purchase confirmations, form submissions, and backend conversions — that must not rely on the browser being open. Your GA4 Measurement ID is a public identifier safe for the frontend, while the Measurement Protocol API Secret stays encrypted in Cloud → Secrets.

Prerequisites

  • A Lovable account with an existing project that has Supabase configured
  • A Google Analytics 4 account — free at analytics.google.com — with a web data stream created for your app
  • Your GA4 Measurement ID (formatted as G-XXXXXXXXXX) from Admin → Data Streams → your stream → Measurement ID
  • A GA4 Measurement Protocol API Secret from Admin → Data Streams → your stream → Measurement Protocol → Create, for server-side event tracking
  • Basic familiarity with browser developer tools to verify that GA4 events are firing correctly

Step-by-step guide

1

Create a GA4 property and get your Measurement ID and API Secret

Before adding tracking to your Lovable app, you need a GA4 property configured for your application. Log in to Google Analytics at analytics.google.com. If you do not already have a GA4 property for your app, click Admin in the bottom-left corner, then click Create Property in the top-left of the Admin panel. Enter your property name (your app name works well), select your reporting time zone and currency, and click Next. On the Business Details page, select your industry category and business size, then click Next. On the Business Objectives page, select what you want to measure — for a SaaS app, 'Examine user behavior' and 'Generate leads' are usually the most relevant. Click Create. Accept the Terms of Service. Next, create a web data stream. Under Data collection and modification in the Admin panel, click Data Streams, then click Add stream and choose Web. Enter your app's URL — if you are still in development, use your Lovable preview URL. Enter a stream name and click Create stream. On the stream details page, you will see your Measurement ID formatted as G-XXXXXXXXXX. Copy this value — you will add it to Lovable as an environment variable. For server-side event tracking via the Measurement Protocol, you need an API Secret. Still on the web data stream details page, scroll down to find Measurement Protocol API secrets and click the arrow to expand it. Click Create. Give the secret a nickname like 'lovable-backend' and click Create. Copy the secret value shown — you will only see it once. Store it immediately. Now go to your Lovable project, click the + icon next to Preview to open the Cloud tab, click Secrets, and add two entries: VITE_GA4_MEASUREMENT_ID with your G-XXXXXXXXXX value, and GA4_API_SECRET with your Measurement Protocol API secret.

Pro tip: The Measurement ID (G-XXXXXXXXXX) is a public identifier — it is safe to use with the VITE_ prefix so it is accessible in your React components. The Measurement Protocol API Secret is sensitive and must only be used in Edge Functions via Deno.env.get().

Expected result: Your GA4 property has a web data stream configured. VITE_GA4_MEASUREMENT_ID and GA4_API_SECRET are stored in Lovable Cloud Secrets. The GA4 property shows a green 'Receiving data' indicator in the Admin panel (this may take a few minutes after adding the snippet).

2

Add the gtag.js snippet to your Lovable app for client-side tracking

The GA4 gtag.js snippet needs to load in the HTML head of your Lovable application. In a Vite + React project, the right place is the index.html file in your project root — this is the HTML shell that wraps your entire React app, and scripts placed here load on every page. Ask Lovable to add the snippet via the chat interface, specifying your Measurement ID. The snippet consists of two parts: a script tag that loads the gtag.js library asynchronously from Google's CDN, and an inline script that initializes the gtag function with your Measurement ID and calls config to begin tracking. Once loaded, gtag automatically tracks pageviews for each initial page load. However, since Lovable apps use React Router for client-side navigation, route changes do not trigger full page reloads — you need to manually call gtag('event', 'page_view') on route changes to track SPA navigation. Create a useGoogleAnalytics hook that listens to React Router's location changes and sends a page_view event to GA4 on each navigation. Import this hook in your root App component so it runs throughout the entire session. The hook reads the Measurement ID from the VITE_GA4_MEASUREMENT_ID environment variable using import.meta.env.VITE_GA4_MEASUREMENT_ID. This approach handles both the initial pageview and all subsequent client-side navigations correctly, giving you accurate session and pageview data in GA4's reports. For sending custom events from components, use the global gtag function directly: window.gtag('event', 'event_name', { parameter: value }). GA4's enhanced measurement automatically tracks scroll depth, outbound clicks, file downloads, and site search — check Admin → Data Streams → your stream → Enhanced measurement to see which ones are enabled and configure them as needed.

Lovable Prompt

Add the Google Analytics 4 gtag.js snippet to index.html using the Measurement ID from import.meta.env.VITE_GA4_MEASUREMENT_ID. Create a src/hooks/useGoogleAnalytics.ts hook that uses React Router's useLocation to send a 'page_view' event to GA4 on every route change. Add the hook to App.tsx so pageviews are tracked throughout the app.

Paste this in Lovable chat

src/hooks/useGoogleAnalytics.ts
1// src/hooks/useGoogleAnalytics.ts
2import { useEffect } from 'react';
3import { useLocation } from 'react-router-dom';
4
5declare global {
6 interface Window {
7 gtag: (...args: unknown[]) => void;
8 }
9}
10
11export function useGoogleAnalytics() {
12 const location = useLocation();
13 const measurementId = import.meta.env.VITE_GA4_MEASUREMENT_ID;
14
15 useEffect(() => {
16 if (!measurementId || typeof window.gtag !== 'function') return;
17
18 window.gtag('event', 'page_view', {
19 page_path: location.pathname + location.search,
20 page_title: document.title,
21 });
22 }, [location, measurementId]);
23}
24
25// Usage in App.tsx:
26// import { useGoogleAnalytics } from '@/hooks/useGoogleAnalytics';
27// function App() { useGoogleAnalytics(); return <Router>...</Router>; }

Pro tip: GA4's enhanced measurement settings automatically track scroll depth (90% scroll events), outbound link clicks, and site search. Check your data stream settings to enable these — they add valuable behavioral data without any additional code.

Expected result: Your Lovable app loads the GA4 gtag.js snippet. Navigating between pages triggers page_view events. Opening GA4's Realtime report shows active users and page_view events appearing within seconds of browsing your app.

3

Send custom conversion events from React components

Beyond automatic pageviews, GA4's value comes from tracking meaningful user actions as custom events. GA4's event model uses a flat structure: an event name string and up to 25 key-value parameter pairs per event. Some event names are reserved by Google for enhanced e-commerce (purchase, add_to_cart, begin_checkout) and should only be used with their expected parameter schemas. For custom app-specific actions, use descriptive snake_case names like 'sign_up', 'feature_used', 'report_exported', or 'subscription_started'. Create a centralized analytics utility in your project so all GA4 tracking calls go through a single typed interface. This approach makes it easy to add additional analytics services later and ensures consistent event naming across the codebase. The utility should check that the gtag function exists before calling it (to handle the case where the script has not loaded yet or is blocked by an ad blocker) and should read the Measurement ID from the environment variable to ensure correct configuration. For conversion tracking, mark specific events as conversions in your GA4 Admin panel: go to Admin → Events → click the toggle next to any event to mark it as a conversion. Common conversions for Lovable apps include sign_up, purchase, lead (for lead generation apps), and tutorial_complete. GA4 will then track these events in the Conversions report and allow you to optimize Google Ads campaigns toward these goals. Add GA4 tracking calls at the most important user actions in your app: form submission success, button clicks that initiate key workflows, and feature activations. Each event should include relevant parameters — for example, a 'file_exported' event might include the file format and number of items exported.

Lovable Prompt

Create a src/lib/ga4.ts utility that exports a trackEvent function. The function should call window.gtag('event', eventName, parameters) if gtag is available and VITE_GA4_MEASUREMENT_ID is set. Add trackEvent calls for: 'sign_up' on account creation, 'login' on authentication, 'feature_used' with a feature_name parameter when key features are activated. Export a trackConversion function for purchase and lead events.

Paste this in Lovable chat

src/lib/ga4.ts
1// src/lib/ga4.ts
2declare global {
3 interface Window {
4 gtag: (...args: unknown[]) => void;
5 dataLayer: unknown[];
6 }
7}
8
9const GA_ID = import.meta.env.VITE_GA4_MEASUREMENT_ID;
10
11function isGtagAvailable(): boolean {
12 return !!GA_ID && typeof window !== 'undefined' && typeof window.gtag === 'function';
13}
14
15export function trackEvent(
16 eventName: string,
17 parameters?: Record<string, string | number | boolean>
18) {
19 if (!isGtagAvailable()) return;
20 window.gtag('event', eventName, parameters);
21}
22
23export function trackConversion(
24 transactionId: string,
25 value: number,
26 currency = 'USD',
27 items?: Array<{ id: string; name: string; price: number; quantity: number }>
28) {
29 if (!isGtagAvailable()) return;
30 window.gtag('event', 'purchase', {
31 transaction_id: transactionId,
32 value,
33 currency,
34 items: items ?? [],
35 });
36}
37
38export function setUserProperties(properties: Record<string, string | number>) {
39 if (!isGtagAvailable()) return;
40 window.gtag('set', 'user_properties', properties);
41}

Pro tip: GA4 has a limit of 500 distinct event names per property. Use generic event names with descriptive parameters rather than creating a unique event name for every user action — for example, use 'feature_used' with a 'feature_name' parameter rather than 'used_export_feature', 'used_import_feature', etc.

Expected result: Custom events appear in GA4's Realtime report as you perform tracked actions in the app. The Events report (under Reports → Engagement) shows event counts accumulating. Events marked as conversions appear in the Conversions report.

4

Create a Supabase Edge Function for GA4 Measurement Protocol

The GA4 Measurement Protocol allows server-side event tracking — events sent directly from your Edge Functions to GA4's collection servers without any browser involvement. This is essential for tracking events that occur on the backend: successful Stripe payment confirmations, email delivery events, scheduled job completions, and any conversion that should be recorded even if the user has navigated away or closed their browser. The Measurement Protocol endpoint is https://www.google-analytics.com/mp/collect and accepts POST requests with your Measurement ID and API Secret as query parameters. The request body is a JSON object containing a client_id (an anonymous identifier for the user), optionally a user_id (the authenticated user's ID), and an array of events with their parameters. The client_id is critical — it must be consistent across sessions for the same user so GA4 can correctly attribute events to user sessions. For server-side events triggered by authenticated users, use a combination of a UUID stored in your Supabase database for the user. For events with no user context (like unauthenticated webhooks), generate a stable client_id from the transaction ID or order ID. Create the Edge Function in Lovable using the chat interface. The function accepts a POST request from your frontend or other Edge Functions with the event name and parameters, reads the GA4_API_SECRET and VITE_GA4_MEASUREMENT_ID from Deno.env.get(), and forwards the event to Google's Measurement Protocol endpoint. Handle CORS headers so the function can be called from the browser if needed. Always return HTTP 200 from this function regardless of whether the GA4 API call succeeded — analytics failures should never block user workflows.

Lovable Prompt

Create a Supabase Edge Function called 'ga4-track' that accepts a POST request with event_name, client_id, optional user_id, and optional parameters. Forward the event to the GA4 Measurement Protocol at https://www.google-analytics.com/mp/collect using GA4_MEASUREMENT_ID and GA4_API_SECRET from Deno environment secrets. Return 200 even if the GA4 call fails. Include CORS headers.

Paste this in Lovable chat

supabase/functions/ga4-track/index.ts
1// supabase/functions/ga4-track/index.ts
2import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
3
4const corsHeaders = {
5 'Access-Control-Allow-Origin': '*',
6 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
7};
8
9serve(async (req) => {
10 if (req.method === 'OPTIONS') {
11 return new Response('ok', { headers: corsHeaders });
12 }
13
14 try {
15 const measurementId = Deno.env.get('VITE_GA4_MEASUREMENT_ID');
16 const apiSecret = Deno.env.get('GA4_API_SECRET');
17
18 if (!measurementId || !apiSecret) {
19 console.error('GA4 credentials not configured');
20 return new Response(JSON.stringify({ success: false }), {
21 status: 200,
22 headers: { ...corsHeaders, 'Content-Type': 'application/json' },
23 });
24 }
25
26 const { event_name, client_id, user_id, parameters = {} } = await req.json();
27
28 if (!event_name || !client_id) {
29 return new Response(
30 JSON.stringify({ error: 'event_name and client_id are required' }),
31 { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
32 );
33 }
34
35 const payload: Record<string, unknown> = {
36 client_id,
37 events: [{ name: event_name, params: { engagement_time_msec: 100, ...parameters } }],
38 };
39
40 if (user_id) payload.user_id = user_id;
41
42 const url = `https://www.google-analytics.com/mp/collect?measurement_id=${measurementId}&api_secret=${apiSecret}`;
43
44 const response = await fetch(url, {
45 method: 'POST',
46 headers: { 'Content-Type': 'application/json' },
47 body: JSON.stringify(payload),
48 });
49
50 console.log('GA4 Measurement Protocol response status:', response.status);
51
52 return new Response(JSON.stringify({ success: true }), {
53 headers: { ...corsHeaders, 'Content-Type': 'application/json' },
54 });
55 } catch (error) {
56 console.error('GA4 track error:', error);
57 return new Response(JSON.stringify({ success: false }), {
58 status: 200,
59 headers: { ...corsHeaders, 'Content-Type': 'application/json' },
60 });
61 }
62});

Pro tip: The GA4 Measurement Protocol returns HTTP 204 No Content on success — do not treat a 204 response as an error. Use Google's Measurement Protocol Validation Server (https://www.google-analytics.com/debug/mp/collect) during development to verify your event payloads are correctly formatted before sending to the production endpoint.

Expected result: The ga4-track Edge Function is deployed. Calling it with a valid event_name and client_id results in the event appearing in GA4's Realtime report within seconds. The function returns 200 even when GA4's API is unreachable.

5

Configure GA4 goals and verify end-to-end tracking

With both client-side and server-side tracking implemented, configure GA4 to surface the most important metrics and verify that all tracking is working correctly end-to-end. Start with the GA4 DebugView — it provides a real-time stream of every event your implementation sends, with full parameter details, making it easy to spot missing parameters, misspelled event names, or events firing at the wrong time. To enable DebugView for your browser session, open your Lovable app in Chrome, open Developer Tools, and install the Google Analytics Debugger Chrome extension — it activates GA4's debug mode which sends events to DebugView instead of production data. In GA4, navigate to Admin → DebugView. You will see a timeline of events as you interact with your app, with each event expanded to show all parameters. Verify that page_view events fire on every route change, that your custom events fire at the right times, and that the client_id is consistent across events in the same session. Next, mark your key conversion events. Go to Admin → Events. You will see all events GA4 has received from your app. Find your most important conversion events (sign_up, purchase, lead) and click the toggle in the 'Mark as conversion' column to enable conversion tracking. These events now appear in the Conversions report and can be used as optimization targets for Google Ads campaigns. Finally, set up your first GA4 Exploration report. Go to Explore → Blank Exploration. Add 'Event name' as a dimension and 'Event count' and 'Conversions' as metrics. This gives you a complete picture of all events your app is sending and their conversion rates. For complex GA4 implementations or building internal analytics dashboards using the GA4 Data API, RapidDev's team can help architect the event taxonomy and build the Edge Function infrastructure needed to query and display GA4 data inside your Lovable app.

Pro tip: GA4 data is not available in the standard reports until 24-48 hours after events are sent — but Realtime reports show data within seconds. Use Realtime during development to verify tracking, and use the standard reports for historical analysis once data has had time to process.

Expected result: GA4 DebugView shows all events with correct parameters. Conversion events are marked in the GA4 Admin panel. The Realtime report shows active users and current page paths. The Exploration report shows event counts accumulating across all tracked events.

Common use cases

Track signup and activation funnel for acquisition optimization

Instrument the complete funnel from landing page visit through account creation to first meaningful action. GA4's funnel exploration report shows exactly which step has the highest drop-off, and the acquisition report shows which traffic source drives users who actually complete activation. This data directly informs where to spend marketing budget.

Lovable Prompt

Add Google Analytics 4 event tracking to the signup and onboarding funnel. Track 'sign_up' when a user creates an account with a method property (email or google). Track 'tutorial_complete' when they finish onboarding. Track 'first_value' when they complete the first meaningful action in the app. Use the gtag() function from the GA4 snippet already loaded in index.html.

Copy this prompt to try it in Lovable

Track e-commerce conversions server-side via Measurement Protocol

Send purchase events to GA4 from the Stripe webhook Edge Function so conversions are always captured regardless of browser behavior. Server-side purchase tracking is more accurate than client-side because it is not affected by ad blockers, browser closures, or navigation away from the confirmation page. GA4's revenue reports show true conversion value.

Lovable Prompt

Create a Supabase Edge Function that sends a 'purchase' event to the GA4 Measurement Protocol when a Stripe payment succeeds. Include the transaction_id, value, currency, and items array in the event payload. Use the GA4_MEASUREMENT_ID and GA4_API_SECRET from Cloud Secrets. Call this from the existing Stripe webhook handler after payment confirmation.

Copy this prompt to try it in Lovable

Embed GA4 Data API charts inside the Lovable app

Build an in-app analytics dashboard that shows users their own engagement metrics pulled from GA4 via the Data API. A Supabase Edge Function authenticates with a Google Service Account and calls the GA4 Data API to fetch pageviews, active users, and conversion counts. Display these as summary cards or charts inside your Lovable app.

Lovable Prompt

Create a Supabase Edge Function that calls the GA4 Data API to fetch pageviews and active users for the last 30 days. Authenticate using a Google Service Account JSON key stored as GA4_SERVICE_ACCOUNT_KEY in Cloud Secrets. Return the data as JSON so the frontend can display it in a stats dashboard. Create a React component that calls this Edge Function and displays the metrics.

Copy this prompt to try it in Lovable

Troubleshooting

GA4 Realtime report shows no data after adding the gtag.js snippet

Cause: The snippet was not placed in the correct location in index.html, the VITE_GA4_MEASUREMENT_ID environment variable is not configured as a build variable, or an ad blocker is intercepting requests to googletagmanager.com.

Solution: Open the browser's Network tab and filter for 'google-analytics' or 'googletagmanager'. If no requests appear, the snippet did not load — verify the snippet is in the HTML head before the closing head tag and that the measurement ID is not undefined (check the rendered source for your G-XXXXXXXXXX ID). If requests appear but show blocked status, disable your ad blocker for testing. For production, consider routing GA4 requests through your own domain using the Measurement Protocol Edge Function to bypass blockers.

Page views are only tracked on the initial load, not on navigation between routes

Cause: React Router uses client-side navigation that does not trigger full page reloads, so GA4's automatic pageview tracking only fires once. The useGoogleAnalytics hook is either missing, not added to App.tsx, or the useLocation hook is not updating correctly.

Solution: Verify the useGoogleAnalytics hook is imported and called in the root App component (the component that contains your React Router setup). Check that the hook's useEffect dependency array includes the location object from useLocation. Navigate between pages and watch the GA4 Realtime report — each navigation should trigger a page_view event.

Measurement Protocol Edge Function returns success but events do not appear in GA4

Cause: The client_id format is invalid (must be a non-empty string), the engagement_time_msec parameter is missing (GA4 requires this for session attribution), or the API Secret does not match the property's Measurement ID.

Solution: Use the GA4 Measurement Protocol Validation endpoint (replace /mp/collect with /debug/mp/collect in the URL) and check the validationMessages array in the response. Common issues are: client_id must be a non-empty string, events[0].params.engagement_time_msec must be set to at least 1, and the api_secret must match the data stream that owns the measurement_id. Verify both secrets in Cloud → Secrets are from the same GA4 data stream.

typescript
1// Add to Edge Function payload to debug validation errors:
2const debugUrl = `https://www.google-analytics.com/debug/mp/collect?measurement_id=${measurementId}&api_secret=${apiSecret}`;
3const debugResponse = await fetch(debugUrl, { method: 'POST', body: JSON.stringify(payload) });
4const debugResult = await debugResponse.json();
5console.log('Validation result:', JSON.stringify(debugResult));

GA4 shows duplicate conversions or inflated event counts

Cause: The trackEvent function is being called inside a React component that re-renders on every state change, or the useGoogleAnalytics hook has an incorrect dependency array causing the page_view event to fire multiple times per navigation.

Solution: Move trackEvent calls out of the component render function and into event handlers or useEffect hooks with correct dependency arrays. For the page_view hook, ensure the useEffect only has the location object in its dependency array — not the entire location object's children properties. Use the GA4 DebugView to watch event firing in real time and identify exactly when duplicates occur.

Best practices

  • Use a consistent event naming convention across your entire app — GA4 recommends snake_case event names like 'sign_up', 'feature_used', 'checkout_started'. Avoid spaces, hyphens, or camelCase to prevent fragmented data in reports.
  • Always include the engagement_time_msec parameter in Measurement Protocol events — without it, GA4 may not count the event toward active user sessions, causing discrepancies between client-side and server-side data.
  • Store the Measurement ID as a VITE_-prefixed environment variable for the frontend and as a plain secret for Edge Functions — never hardcode the G-XXXXXXXXXX string in your component code since it becomes difficult to manage across development, staging, and production environments.
  • Configure Google Signals in GA4 (Admin → Data Settings → Data Collection) to enable cross-device tracking and demographic reporting — this requires users to be signed in to Google but significantly improves audience insights at no extra cost.
  • Set up data retention in GA4 at 14 months (Admin → Data Settings → Data Retention) — the default is 2 months, which causes historical data to disappear from Exploration reports after 60 days.
  • Use GA4's custom dimensions to attach user properties (plan, account age, feature flags) to every session — configure these in Admin → Custom Definitions → Custom Dimensions before tracking them, as GA4 does not retroactively process custom dimensions.
  • Create a separate GA4 property or data stream for development to prevent test events from contaminating production analytics data — use VITE_GA4_MEASUREMENT_ID set to the development stream ID in your .env.local file.
  • Enable IP anonymization by default (GA4 does this automatically) and review your privacy policy to disclose GA4 tracking — many jurisdictions require explicit disclosure of analytics cookies and data collection.

Alternatives

Frequently asked questions

Is Google Analytics 4 free to use with a Lovable app?

GA4 is free for standard use — there is no cost to add it to your Lovable app and no charge for the volume of events you send. The GA4 360 paid tier ($150,000+/year) adds higher data freshness, more custom dimensions, and BigQuery export for enterprise-scale data needs, but the free tier is more than sufficient for most Lovable apps.

Why does GA4 show fewer conversions than I tracked in my app?

GA4 uses statistical modeling to fill in gaps where data is incomplete due to ad blockers, cookie consent rejections, or browser restrictions. This means GA4's reported conversion numbers may be lower than your actual count from Supabase. Use the Measurement Protocol Edge Function approach for critical conversion events (purchases, signups) so they are tracked server-side and not subject to browser-side blocking. Compare GA4 data against your Supabase transaction table as the source of truth for revenue.

How do I track users across sessions in GA4?

GA4 uses the client_id stored in a first-party cookie (_ga) to identify returning users across sessions. For authenticated users, you can also set a user_id with window.gtag('set', {user_id: userId}) after login — GA4 then links sessions across devices when the same user logs in from different browsers. The user_id must be a non-personally-identifiable string (use your Supabase user UUID, not the user's email address).

What is the difference between GA4 events and conversions?

In GA4, every tracked action is an event, and conversions are simply events you have marked as important business outcomes. You mark events as conversions in Admin → Events by toggling the 'Mark as conversion' switch. Conversion events then appear in the dedicated Conversions report and can be used as optimization targets for Google Ads. There is no difference in how the events are sent from your app — the distinction is purely in how GA4 reports them.

Can I see GA4 data inside my Lovable app without leaving the browser?

Yes, using the GA4 Data API. Create a Supabase Edge Function that authenticates with a Google Service Account and calls the GA4 Data API to fetch metrics like active users, pageviews, and conversion counts. The Edge Function stores the service account credentials in Cloud Secrets and returns the data as JSON for your React components to display. This lets you build an in-app analytics dashboard that shows real GA4 data to your users or your team.

Does GA4 work with Lovable's preview environment?

GA4 will track events from Lovable's preview environment, but the preview runs in an iframe which some browsers restrict for cookie-based tracking. For reliable testing, use GA4's DebugView (which works without cookies) and the Measurement Protocol Edge Function. It is best practice to use a separate GA4 property or data stream for development so test events do not appear in your production analytics.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.