Docs · Web tracking

Your landing page, in the same dashboard

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-to-store funnel, per-page views and time, visitor countries, referrers, and campaigns. 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-to-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 spent looking at it

Automated browsers (Playwright, Puppeteer, Selenium and other headless test runs, which set navigator.webdriver) are not tracked, so your own test runs never count as visitors. To track them on purpose, add data-track-automation="true" to the script tag.

Pages opened from a development server are not tracked either: localhost, 127.0.0.1, addresses ending in .local, .localhost or .test, and private network addresses such as 192.168.x.x (when you open your dev server on a phone). Previewing your own site never shows up as traffic. To track a local page on purpose, add data-track-local="true" to the script tag.

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 paid-plan notify form 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-to-store ratio stays roughly honest.

Privacy & safety

  • The visitor ID is a random anonymous string in localStorage — no cookies, no fingerprinting, no personal data collected by the snippet itself.
  • The API key is send-only: it can add events for your page and read nothing.
  • Tracking failures can never break the page — every call is wrapped and fire-and-forget.

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

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

Start free