Install tracking code
Paste this snippet just before the closing </head> tag on every page you want to measure. It's a tiny, cookieless script — no consent banner needed.
Loading your snippet…
Step-by-step for your platform, with your own snippet filled in.
Your snippet
…
Steps
- Open the HTML template all your pages share (often header.php, layout.html or a _head partial).
- Paste the snippet just before the closing </head> tag.
- Upload or deploy the changed file.
One copy per page is enough. If your site sends a Content-Security-Policy, allow https://cdn.ghoststat.me in script-src and https://api.ghoststat.me in connect-src.
Your site key
…
Steps
- Download the GhostStat plugin with the button above.
- In WordPress go to Plugins → Add Plugin (Add New Plugin in older versions) → Upload Plugin. Choose the zip, click Install Now, then Activate Plugin.
- In WordPress open Settings → GhostStat, paste your site key (above) and click Save Changes. Every page is now measured; signed-in administrators are not counted.
- Optional, to see your statistics inside WordPress: create an API key in Site settings → API keys, paste it under API key in the same WordPress settings and save. Your numbers then show under Dashboard → GhostStat and in a dashboard widget.
- Click Check now in the plugin settings to confirm both keys work.
Also in the WordPress plugin directory: in WordPress go to Plugins → Add Plugin, search for “GhostStat Analytics” and click Install Now; updates then arrive automatically. Prefer no extra plugin? Paste the snippet in the Header box of the free WPCode plugin (Code Snippets → Header & Footer).
Your site key
…
Steps
- Download the GhostStat add-on with the button above and unzip it.
- Upload the ghoststat folder to system/user/addons/ on your server.
- In the ExpressionEngine control panel go to Add-ons, find GhostStat and click Install.
- Open Add-ons → GhostStat, paste your site key (above) and click Save.
- Put the tag below in your layout template, just before </head>. Every page that uses the layout is now measured.
- Optional, to see add-on installs and updates next to your traffic in Software Development: make a report key with the button below (a second, secret key that starts with gssw_ and is shown once), paste it under Report key in the same add-on settings and click Save.
- Optional, to see your statistics inside ExpressionEngine (the same as in the WordPress plugin, and a dashboard widget on ExpressionEngine Pro): create an API key with the button below, paste it under API key in the same add-on settings and click Save. Add-ons → GhostStat then opens your statistics.
{exp:ghoststat:tracker}
Already have the GhostStat snippet in your templates? Then leave the tag out, so pages are not counted twice. With several sites in one ExpressionEngine (MSM), switch site and fill in the settings for each.
Your snippet
…
Steps
- Open your container, go to Tags and click New.
- Click Tag Configuration and choose Custom HTML.
- Paste the snippet into the HTML field. Leave “Support document.write” off.
- Under Triggering choose All Pages, then click Save.
- Click Submit, then Publish.
Tag Manager may change quotes in the snippet when it saves; that does no harm.
Your snippet
…
Steps
- In Shopify admin go to Online Store → Themes. To be safe, first make a copy of your theme with … → Duplicate.
- On your current theme click … and choose Edit code.
- Open layout/theme.liquid.
- Paste the snippet just before </head> and click Save.
Shopify's checkout doesn't run theme code, so the checkout steps themselves aren't measured. A theme update can drop code changes, so check again after updating.
Your snippet
…
Steps
- In your site's dashboard open Settings, then Custom Code under Development & integrations.
- Click + Add Custom Code and paste the snippet. Name it, for example “GhostStat”.
- Under Add Code to Pages choose All pages, and load the code once (not on each new page).
- Under Place Code in choose Head, then click Apply.
Wix only runs custom code on a published site with a connected domain. Loading it once is enough: GhostStat counts page changes inside the site by itself.
Your snippet
…
Steps
- Go to Website → Pages → Website Tools → Code Injection.
- Paste the snippet into the Header box and click Save.
Code injection is available on the Core, Plus and Advanced plans and some older plans.
Your snippet
…
Steps
- Open Site settings and go to the Custom code tab.
- Paste the snippet into Head code and click Save changes.
- Publish your site: the code only goes live after publishing.
Custom code needs an active Site plan, or a Core, Growth, Agency or Freelancer Workspace.
Your snippet
…
Steps
- Vite (React, Vue, Svelte): paste the snippet inside <head> in index.html at the project root.
- Create React App: paste it inside <head> in public/index.html.
- Next.js: add this Script to your root layout (app/layout) or to pages/_app:
…
Navigation with the History API (pushState, back and forward) is counted as a pageview automatically. No extra code needed.
Check that it works
Open your site in another tab and load a page, then verify here.
Your app sends screens, events and a "still here" heartbeat to GhostStat. Visitors are counted like on your website — no cookies, no advertising or device IDs, nothing that identifies the phone — so no tracking prompt (ATT) is needed.
1. Add the Swift package
Download GhostStatSDK and unzip it next to your project. In Xcode choose File → Add Package Dependencies… → Add Local…, pick the GhostStatSDK folder and add the GhostStat library to your app. It needs iOS 16 or later and has no dependencies.
2. Start it when the app launches
import SwiftUI
import GhostStat
@main
struct MyApp: App {
init() {
GhostStat.configure(siteKey: "…")
}
var body: some Scene { WindowGroup { ContentView() } }
}
3. Name your screens and events
SettingsView()
.gsScreen("Settings")
GhostStat.event("signup_completed", props: ["plan": "pro"])
4. Deep links bring their campaign along
.onOpenURL { url in GhostStat.handle(url: url) } // utm_* from the link
5. Why it crashed (optional)
With SDK 1.2 each crash, hang and slow launch arrives with its reason and stack. Release builds have no function names in them: upload the dSYMs of each release (Xcode → Organizer → the archive → Show in Finder → dSYMs, zipped) to see functions, files and lines. From CI: make an upload key on the same page. App Insights → Symbol files
1. Add the Android module
Download GhostStatSDK-Android and unzip it next to your project. Include its ghoststat folder as a module and add it to your app. Android 5.0 (API 21) or later, no dependencies. Built for Android Gradle Plugin 9; on AGP 8, use the build file in its agp8 folder (see README.md).
// settings.gradle.kts
include(":ghoststat")
project(":ghoststat").projectDir = file("../GhostStatSDK-Android/ghoststat")
// app/build.gradle.kts
dependencies { implementation(project(":ghoststat")) }
2. Start it in your Application class
import android.app.Application
import me.ghoststat.sdk.GhostStat
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
GhostStat.configure(this, siteKey = "…")
}
}
3. Name your screens and events
GhostStat.screen("Settings") // e.g. in onResume, or LaunchedEffect(Unit) in Compose
GhostStat.event("signup_completed", mapOf("plan" to "pro"))
4. Deep links bring their campaign along
GhostStat.handle(intent?.data) // in onCreate and onNewIntent: utm_* from the link
5. Why it crashed (optional)
With SDK 1.2 each crash, ANR and native crash arrives with its reason and stack (never the exception message). For minified release builds, upload app/build/outputs/mapping/release/mapping.txt with its version name and code; for native code, the unstripped .so files. From CI: make an upload key on the same page. App Insights → Symbol files