Docs
Get started
Add your site, install the script, and see your first visitor. About five minutes.
1. Add your website
Sign in to your Luminel dashboard and add your website's domain. Luminel gives the site an ID, which is what ties the script to it.
2. Add the script
Put this inside your site's <head>. It counts page loads and, on a single-page app, client-side navigation too.
<script defer src="https://www.luminel.app/script.js" data-id="YOUR_WEBSITE_ID" data-dnt="false"></script>data-id: your website ID. It decides where the traffic is recorded, whatever the domain.data-dnt: set totrueto send nothing for visitors whose browser asks not to be tracked. Off by default.
Nothing is sent from localhost, and the script finds its collector from its own address, so the same tag works on a self-hosted install.
3. Check it is working
- Deploy your site with the script in place.
- Open one of its pages.
- Open the site in your dashboard: the visit appears under Right now within a few seconds.
What is recorded
For each page view: the page's path and title, the referrer, and what the browser reports about itself: browser, operating system, device type, viewport, language, time zone and connection type. No cookies are set and no personal data is collected. The privacy policy lists every field.
Custom events
Call luminel.track to record something a page view does not show, such as a sign-up, a download, a purchase:
window.luminel.track("Signup", { plan: "pro" });Events appear under Custom events on the Analytics view, and can be the target of a goal.
AI crawlers
AI crawlers such as GPTBot, ClaudeBot and PerplexityBot read a page's HTML and never run its scripts, so the script above cannot see them. To count them, your own server reports their visits. On Next.js, add this middleware. Your site's copy, with its ID filled in, is under Settings → Server-side crawler tracking:
// middleware.ts
import { type NextFetchEvent, type NextRequest, NextResponse } from "next/server";
const BOT = /bot|crawl|spider|GPT|Claude|Perplexity|-User\b|Fetcher/i;
export function middleware(request: NextRequest, event: NextFetchEvent) {
const userAgent = request.headers.get("user-agent") ?? "";
if (BOT.test(userAgent)) {
event.waitUntil(
fetch("https://www.luminel.app/api/crawlers", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
websiteId: "YOUR_WEBSITE_ID",
host: request.nextUrl.host,
path: request.nextUrl.pathname,
userAgent,
}),
}).catch(() => {}),
);
}
return NextResponse.next();
}
// Pages only: skip assets and API routes.
export const config = { matcher: ["/((?!_next/|api/|.*\\..*).*)"] };Only requests from bots are sent, and the response never waits for the report, so your visitors are unaffected. On another framework, post the same JSON from any server.
A report needs only your website ID. If someone else starts inflating your crawler figures, switch on Require a token in the same settings; reports without your site's token are then refused. A crawler that also runs JavaScript, such as Googlebot, is counted by both the script and the middleware.
Privacy
- No cookies and no identifier that persists for a person.
- IP addresses are used in passing, to find a country and to make a session hash that changes every month, and are never stored.
- Visitors who ask not to be tracked are left out when you set
data-dnt="true".