Docs · Web tracking

Your landing page, in the same dashboard

Page views, App Store clicks, campaign attribution, and time on page — one script tag, no cookie banner, no build step.

Setup: one line

Register the landing page as its own app in the dashboard (+ New app, a slug like myappweb), then add one line before </body>:

<script src="https://foliokit.io/appcore-web.js"
        data-app-id="YOUR_SLUG" data-api-key="YOUR_API_KEY" defer></script>

That's everything. The landing page gets linked to its iOS app so the app's Overview shows a Landing card — the web→store funnel, per-page views and time, visitor countries, referrers, and campaigns. During early access, the linking is done for you: mention which app the page belongs to when you register it, or email contact@foliokit.io.

What gets tracked automatically

EventWhen
page_viewpage load — with the page path, campaign/source from the URL (see below), and the referrer's hostname
store_clicka click on any link to apps.apple.com — your web→store conversion
page_leaveleaving the page, carrying the visitor's visible time on it — background tabs don't count, so "average time on page" means time actually looking at it

Campaign links: ?ac=

When you post a link on Reddit, a newsletter, or anywhere else, append ?ac=campaign-name:

https://yourapp.com/?ac=reddit-launch

Every page_view (and the store_click that may follow) carries that campaign, and the Landing card breaks visitors down by it. The snippet also reads standard ?utm_campaign= / ?utm_source= / ?ref= parameters, so existing tagged links keep working.

Custom events: one attribute

Put data-appcore-event="name" on any element to count its clicks:

<button data-appcore-event="pricing_expanded">See pricing</button>

The waitlist-form pattern

For a simple "how many people clicked join" count, the attribute above is enough. If you want the signup itself — including the email — as an event, post it directly from your form's submit handler. This is exactly how foliokit.io's own waitlist works:

await fetch("https://foliokit.io/api/track", {
  method: "POST",
  headers: { "content-type": "text/plain" },
  body: JSON.stringify({
    app_id: "YOUR_SLUG",
    api_key: "YOUR_API_KEY",
    user: { id: uid },   // reuse localStorage "appcore_uid" if present
    events: [{ name: "waitlist_signup",
               screen: location.pathname,
               props: { email: cleanedEmail } }],
  }),
})

Signups then show up highlighted in the Live tab, email included, seconds after they happen. Putting an email in props is your call — it's your event data, on your app; the SDK-side rule of "no PII in props" exists because app events don't need it, but a waitlist signup is the email. The text/plain content type is deliberate: it keeps the request a CORS "simple request" so browsers deliver it reliably, even during page unload.

How geography works (the relay)

The snippet sends events to foliokit.io/api/track, a tiny edge relay whose only jobs are to stamp the visitor's country (from the network edge — no IP is stored, no geolocation API runs in the browser) and forward the event to ingestion. That's why the Landing card can show a country breakdown without any fingerprinting.

Honesty section: adblockers

Brave, uBlock Origin, and most content blockers block requests like this one — those visitors are invisible to the snippet, full stop. If your audience is developers, the undercount can be significant. FolioKit will not play the cat-and-mouse games (disguised endpoints, fingerprinting) that "fix" this; treat web numbers as a directional floor, not a census. Your App Store click counts are affected the same way, so the web→store ratio stays roughly honest.

Privacy & safety

The full collected/never-collected list is on the data & privacy page.

FolioKit — your landing page and your app, finally in one funnel.

Get early access