Add analytics to a Lovable app with its AI agent
undefined
To add analytics to a Lovable app, connect AgentFirstStack to Lovable as a custom MCP server, paste one prompt into the project chat, and publish. Lovable's agent then has AgentFirstStack's tools: it creates the site, adds the tracker to the app's document head, and after you publish it verifies the live app and runs the setup check. You never handle an API key in the browser, and the project lands in your own AgentFirstStack dashboard because you signed in to connect it. One limit: Lovable's hosting has no documented way to serve the tracker from your own domain, so it loads from analytics.agentfirststack.com and visitors with an ad blocker aren't counted. For other builders and editors, see add analytics with an AI agent.
1. Connect AgentFirstStack to Lovable
Lovable lets every plan add custom MCP servers: Connectors > Add custom > MCP server. Use this URL:
https://agentfirststack.com/mcp
Then pick one way to authenticate:
- OAuth (easiest). Leave the token empty. AgentFirstStack's MCP server supports OAuth 2.1 with dynamic client registration: you sign in with Google, choose "Create a new project" (name it after your app's domain) and pick full access. The project is yours from the start, so there's no claim link to open later.
- Bearer token. If you already have a key, or get one from any terminal with
curl -X POST https://agentfirststack.com/v1/signup, paste it as the connector's bearer token. Keep a copy in your password manager: the key is the account.
Two Lovable rules to know. Custom MCP servers "only give Lovable context in the project chat": the agent uses them while it builds, and your published app never calls them. And connections are per user, so a teammate who wants the agent to use AgentFirstStack connects it themselves.
2. Paste the prompt
Add analytics to this app with AgentFirstStack, using the AgentFirstStack MCP server I connected. Read https://agentfirststack.com/llms.txt and https://analytics.agentfirststack.com/llms.txt first. 1. Name the project after the app's domain (afs_update_project) if it has no name. 2. Create an analytics site (analytics_create_site) for the domain the app is published on: the custom domain if it has one, otherwise its .lovable.app address. If the app answers on both, set allowed_hostnames to the custom domain (*.example.com) plus the .lovable.app host. 3. Get the install code (analytics_get_install_instructions) and add the tracker script to the document head so every page has it. If the app uses TanStack Start, add <script async src="https://analytics.agentfirststack.com/s.js" data-site="SITE_ID"> inside <head> in the root route's document, next to <HeadContent />. If it's a React + Vite app, add the snippet to <head> in index.html. The site id is public; never put an API key in frontend code or in a VITE_ variable. Lovable's hosting can't proxy the tracker through the app's domain, so note in AGENTFIRSTSTACK.md that ad blockers block analytics here. 4. Create goals for sign-ups, purchases and the main buttons (data-afsa-event attributes on buttons work without code). 5. Add an email destination, a weekly report, and alerts for a traffic drop and for no data. 6. Tell me to publish. After I say it's published, run analytics_verify_install, fix what it reports, then run afs_check_setup with services ["analytics"] and work through its next_steps until it says ready. Write the site id in AGENTFIRSTSTACK.md (never a key), and tell me what you set up and how you verified it.
If you connected with a bearer token instead of OAuth, add a last line asking for a claim link (afs_create_claim_link), so you can see the project in the dashboard.
Where the tracker goes in a Lovable app
It depends on when the project was created. Lovable's docs say apps created from 13 May 2026 (22 June on Enterprise plans) use TanStack Start with server-side rendering. Older apps are React + Vite single-page apps.
TanStack Start apps. TanStack keeps the HTML document in the root route, src/routes/__root.tsx, where <HeadContent /> renders the head tags. Put the tracker next to it:
<head>
<HeadContent />
<script async src="https://analytics.agentfirststack.com/s.js" data-site="site_..." />
</head>
Rendered there, the tag is in the HTML the server sends, so verify can find it and the homepage proves your domain. async rather than defer because React streams the page; React's docs say defer doesn't work with streaming server rendering.
React + Vite apps. index.html is the one HTML file every route uses:
<head>
<script defer src="https://analytics.agentfirststack.com/s.js" data-site="site_..."></script>
</head>
Either way, page changes inside the app are counted: the tracker wraps history.pushState and listens for popstate, which is how both React Router and TanStack Router navigate. Don't add a page-view hook on top; that counts each page twice.
On paid plans you can check or make the edit yourself in Lovable's code editor (it's read-only on the Free plan), or in GitHub through Lovable's two-way sync.
Why the direct snippet
Where the hosting allows it, AgentFirstStack's tracker is served from the site's own domain through a small proxy, because ad blockers block analytics.agentfirststack.com. That needs the host to forward a path such as /_a/* to another server with a secret header. Lovable's docs describe no such setting, so this guide uses the direct snippet and accepts that visitors with ad blockers aren't counted. If you deploy the app's code somewhere else from GitHub (Vercel, Netlify, Cloudflare), add that host's proxy from GET /v1/sites/:id/install and switch the src to /_a/s.js.
The API key and server events
The browser only needs the site id. The API key is only for the agent's tools and for server code, and Lovable keeps those apart for you. Its Secrets are "injected into your project's Edge Functions and server-side integrations at runtime", while anything in .env with a VITE_ prefix is "embedded into the client bundle at build time". Lovable also refuses VITE_ names in Secrets.
So when a conversion happens on the server (a verified sign-up, a paid order through a payment webhook), send it from an Edge Function with the key from Secrets:
// in a Lovable Cloud Edge Function (Deno)
await fetch(`https://analytics.agentfirststack.com/v1/sites/${Deno.env.get("AFS_SITE")}/events`, {
method: "POST",
headers: {
authorization: `Bearer ${Deno.env.get("AGENTFIRSTSTACK_API_KEY")}`,
"content-type": "application/json",
},
body: JSON.stringify({ events: [{ name: "signup", visitor_id: visitorId, user_id: userId }] }),
});
Get visitorId on the page with window.afsa.visitorId() and send it along with the sign-up or checkout request, so the event joins the visit that led to it. If you connected over OAuth, create the key for Secrets in the AgentFirstStack dashboard; OAuth sessions can't create API keys.
Publish, then verify
Nothing reaches your visitors until you publish, and later edits stay in the editor until you click Publish > Publish changes. The published app lives at your-app.lovable.app; on a paid plan you can connect your own domain. Then ask the agent to verify. It runs analytics_verify_install, which fetches the live page and checks the snippet, that the script loads, the Content-Security-Policy and whether events arrived, and afs_check_setup, which lists anything else the setup is missing.
Visit the published URL once yourself before verifying. The editor preview doesn't count: the preview's "open in new tab" link needs a Lovable login, and it isn't on your app's domain, so its events are dropped.
Things that trip people up
- Two addresses. There's no way to remove the
.lovable.appURL, even with a custom domain. A site accepts events only from its domain and subdomains, so if visitors can reach both, setallowed_hostnamesto["*.example.com", "your-app.lovable.app"]. That list replaces the default, so include your own domain.lovable.appon its own is refused as a site domain, because it's a shared suffix;your-app.lovable.appis fine. - Forgetting to publish. The agent's edit is in the editor, not live. Verify reports
snippet_presentfailing until you publish. - Lovable's own analytics. Lovable has built-in analytics with its own script. Both can run; they don't interfere.
- Instructions for later chats. Lovable reads
AGENTS.mdorCLAUDE.mdat the top level of the project with every message, and also has Project settings > Instructions. Add a line there such as "This app uses AgentFirstStack analytics; ids are in AGENTFIRSTSTACK.md; run afs_check_setup before changing tracking."
FAQ
Can Lovable's agent set up analytics without an MCP server?
Lovable's docs don't say its agent can make arbitrary API calls such as POST /v1/signup, so connect the MCP server. Alternatively, run the setup from a coding agent with a terminal (Claude Code, Cursor, Codex) on the GitHub copy of the project.
Does the API key end up in my app's code?
No. The tracker needs only the public site id. The key lives in the MCP connector (or nowhere, with OAuth) and, for server events, in Lovable's Secrets, which only Edge Functions read.
Will it count page changes in a single-page app?
Yes. The tracker records a page view on every History API navigation, which covers React Router and TanStack Router. Hash routes (#/page) need data-hash="true" on the script tag.
Do I need a cookie banner for it?
The tracker sets no cookies and stores nothing in the browser by default. Whether your site needs a banner is a legal question; if a consent manager should decide, add data-require-consent="true" and call afsa('consent', true) after consent.
What does it cost?
The hosted service is free, with fair-use limits such as 10 analytics sites per account. Lovable's custom MCP servers are available on every plan; custom domains need a paid Lovable plan.
Related
- AnalyticsAdd analytics with an AI agentThe prompt, the checks, and every tool and platform.
- AnalyticsAdd analytics to a Bolt appindex.html, .env and publishing.
- AnalyticsAdd analytics to a v0 appapp/layout.tsx, Vercel env vars and previews.
- AnalyticsAdd analytics with Replit AgentSecrets, deployments and the .replit.app domain.
- AnalyticsAdd analytics with Claude CodeOne prompt in the terminal, then questions over MCP.
- All servicesOne MCP server for every serviceAnalytics, tags, mail and replay tools on one key.
- AnalyticsGoogle Analytics MCP comparedRead GA4, or let the agent create the analytics.
- ReplaySession replay for AI agentsFind out why visitors drop off.