Set up Plainview
Most sites are done in two minutes. Add the snippet, visit your site once, and the dashboard starts filling in.
Install
Add your site in the dashboard, then paste its snippet inside the <head> of every page:
<script defer data-site="pv_yoursiteid" src="https://plainview.app/t.js"></script>
The script is about 3 KB, loads after your page and never blocks rendering. Go to Settings and press Check installation to confirm it’s working.
Website builders
- Squarespace: Settings, Advanced, Code Injection, Header.
- Wix: Settings, Custom Code, Add Custom Code, place in Head on all pages.
- Webflow: Site settings, Custom code, Head code. Publish afterwards.
- Shopify: Online Store, Themes, Edit code,
theme.liquid, before</head>. - WordPress: use any “header and footer scripts” plugin, or add it to your theme’s
header.php. - Next.js: add it with
next/scriptandstrategy="afterInteractive"in your root layout.
What’s tracked automatically
Without any extra setup Plainview records pageviews, the referring site, campaign tags, country, device, browser, time on page, scroll depth, and every click on a link or button with its text. Outbound links, phone taps (tel:), email links (mailto:) and form submits are recorded as their own actions. Clicks on things that look clickable but aren’t, and rapid repeated clicks, are marked as dead clicks.
Custom events
For anything else, call plainview() from your own code:
plainview('Signed up')
plainview('Order placed', { value: 49 })
Or skip the JavaScript and add an attribute to any button, link or form:
<button data-pv-event="Booked a table">Book</button>
If your code might run before the script loads, add this line first and calls will be queued:
<script>window.plainview = window.plainview || function(){(plainview.q = plainview.q || []).push(arguments)}</script>
Goals
A goal counts each visit that did something you care about, once. There are three kinds:
- Visits a page, like
/thank-you. Use*as a wildcard:/order/*. - An event fires, like
Form submitted: contactor a custom event name. - Clicks something, matched on the button or link text, like
Book now.
Goals apply to your past data too, so you can add one today and see last month’s conversion rate straight away.
Campaign links
Add utm_source, utm_medium and utm_campaign to links in emails, ads and posts. Plainview reads them to sort traffic into channels. Clicks from Google Ads, Microsoft Ads, Meta and TikTok ads are detected from their click IDs even when you forget to tag them.
https://yourshop.com/?utm_source=newsletter&utm_medium=email&utm_campaign=october-specials
Heatmaps
Heatmaps are drawn on your live page, so they always match what visitors actually saw. If your site blocks being shown inside the dashboard, use Open on your site to see the overlay on the real page. The link is signed and expires after two hours.
Single-page apps
Route changes through history.pushState are picked up automatically in React, Vue, Svelte, Next.js and similar frameworks. Nothing to configure.
Excluding your own visits
Open your site and run this once in the browser console. Visits from that browser stop counting:
localStorage.plainview_ignore = '1'
Privacy
Plainview sets no cookies and stores no IP addresses. Each visitor is counted with a one-way hash of their IP address, browser and your site, mixed with a secret that changes every day. The hash can’t be reversed, and the same person shows up as a different visitor tomorrow and on every other site. Read the privacy policy.
Running your own copy
Plainview is a single Node.js service with a SQLite database. Set SECRET, APP_URL and APP_DOMAIN, mount a volume at DATA_DIR, and run npm start. Optional: ANTHROPIC_API_KEY for written summaries, Stripe keys for billing, and a Resend key for invite emails. The README in the repository lists every setting.