@kern-di/prospect-tracker
v0.1.15
Published
React prospect engagement modal with scroll/idle tracking and notify events
Downloads
101
Readme
@kern-di/prospect-tracker
React component: scroll/idle engagement tracking, optional modal CTA, and visit / cta_click POSTs to your notify endpoint. The default URL is https://admin.<apex>/api/notify derived from window.location.hostname (e.g. on www.kern-di.de → https://admin.kern-di.de/api/notify). Override with notifyUrl if your admin host does not match that pattern.
Styling is inline (no Tailwind in consumer apps). Colors and type styles match @kern/ui / globals.css via @kern/shared/lib/kernUiTokens, which is bundled into the published package (no extra npm dependency).
Install
pnpm add @kern-di/prospect-trackerPeer dependencies: react ^18 and react-dom ^18 (portal + modal layer).
Local demo (develop UI & behavior)
From the monorepo root:
pnpm prospect-tracker:demoOpens http://localhost:7080 — a five-section landing page plus footer, ProspectTracker wired to a mock POST /api/notify (logs payloads in the terminal). Imports the component from src/ so edits hot-reload without running tsup. On each full refresh, the demo clears kern_shown_* / kern_engaged_* so the modal can trigger again.
Usage
Backend requirement (fleet / recommended)
For fleet/customer sites, the recommended setup is:
- Frontend posts to same-origin
notifyUrl="/api/notify"(no CORS headaches) - Your site implements
POST /api/notify(Vercelapi/notify.ts) which forwards to KERN’s central API (bearer-protected) - Your site exposes the
recipientIdfrom a backend env var (not a Vite public env var) via a same-origin config route
For fleet/customer sites, implement a same-origin POST /api/notify route that forwards to KERN’s central API (bearer-protected).
Vercel one-liner:
import { createVercelHandler } from "@kern-di/prospect-tracker/server";
export default createVercelHandler({
apiKey: process.env.KERN_API_KEY ?? "",
// Optional; if omitted uses KERN_API_URL / VITE_KERN_API_URL / production default.
apiUrl: process.env.KERN_API_URL,
});Backend: provide recipientId via server env
Create api/prospect-tracker-config.ts (Vercel Node runtime) to expose the configured recipient id:
import type { VercelRequest, VercelResponse } from "@vercel/node";
export default function handler(req: VercelRequest, res: VercelResponse) {
if (req.method !== "GET") {
return res.status(405).json({ error: "Method not allowed" });
}
const recipientId = process.env.PROSPECT_RECIPIENT_ID?.trim() ?? "";
if (!recipientId) {
return res.status(503).json({ error: "PROSPECT_RECIPIENT_ID not configured" });
}
return res.status(200).json({ recipientId });
}Set PROSPECT_RECIPIENT_ID on your Vercel project (server-side env var).
Frontend: mount once near app root
Fetch the recipient id and only render the tracker if it exists. Also set notifyUrl="/api/notify" so events hit your same-origin backend route.
import { useEffect, useState } from "react";
import { ProspectTracker } from "@kern-di/prospect-tracker";
export function App() {
const [recipientId, setRecipientId] = useState<string | null>(null);
useEffect(() => {
fetch("/api/prospect-tracker-config")
.then((r) => (r.ok ? r.json() : null))
.then((data) => setRecipientId(data?.recipientId ?? null))
.catch(() => setRecipientId(null));
}, []);
return (
<>
{/* Your page */}
{recipientId ? (
<ProspectTracker
recipientId={recipientId}
notifyUrl="/api/notify"
engagementSectionId="leistungen"
/>
) : null}
</>
);
}Props
| Prop | Description |
|------|-------------|
| recipientId | Required. Sent with notify events. |
| notifyUrl | Optional. Override POST URL if it is not https://admin.<your-apex-domain>/api/notify. |
| engagementSectionId | Optional. If the element exists, scrolling past it counts as engagement; otherwise depth/bottom heuristics apply. |
| primaryColor | Optional. Primary button background (hex/CSS color). |
| headline, description, ctaLabel | Optional. Override modal copy (defaults are warm, KERN-Di.–specific). |
| thankYouTitle, thankYouMessage | Optional. Copy after the CTA is clicked. |
| team photo | Always shown. The bundled Simon & Johannes photo is rendered in the modal. |
AI / coding-agent integration
Short copy-paste prompt: AGENT_PROMPT.md (also in node_modules/@kern-di/prospect-tracker/ after install).
Fleet integration instructions (backend route that forwards to the central API): CODING_AGENT.md (also in node_modules/@kern-di/prospect-tracker/ after install).
Your workflow (keep this)
1. While you edit the package
From the repo root:
pnpm prospect-tracker:watchLeave it running. It rebuilds dist/ when src/ changes. Nothing is sent to npm.
2. One-time: make npm let you publish
Do this once per machine (or when a publish returns 403):
- On npmjs.com → Access Tokens → Generate New Token → Granular Access Token.
- Allow read/write for
@kern-di/prospect-tracker(or the whole@kern-discope). - Enable Bypass two-factor authentication (or the automation option npm shows). Without this, publish will keep failing with
403if your account uses 2FA. - Save the token somewhere safe (password manager). Do not commit it.
Put it on this computer:
npm config set //registry.npmjs.org/:_authToken "paste_token_here"(If you ever paste a token in chat or a screenshot, revoke it on npm and make a new one.)
You also need permission to publish under the @kern-di org on npm.
3. When you want a new version on npm
From the repo root (patch bump + build + type-check + publish):
pnpm prospect-tracker:releaseOr from packages/prospect-tracker:
pnpm releaseThat bumps the patch version (e.g. 0.1.2 → 0.1.3), runs scripts/publish.mjs (build → type-check → pnpm publish), then you commit package.json (and root pnpm-lock.yaml if it changed).
Publish the current version only (no version bump), e.g. after a failed publish:
pnpm prospect-tracker:publish
# or: pnpm --filter @kern-di/prospect-tracker publish:npmExtra args are forwarded to pnpm publish (dry-run, OTP):
pnpm --filter @kern-di/prospect-tracker publish:npm -- --dry-run
pnpm --filter @kern-di/prospect-tracker publish:npm -- --otp=1234564. If release failed after bumping the version
You’ll see 403 and package.json already has a new version that is not on npm yet. Do not run release again (you’d skip a version).
Fix the token (step 2), then publish this version only:
pnpm prospect-tracker:publishIf you don’t use a token and rely on OTP instead:
pnpm prospect-tracker:publish -- --otp=PASTE_6_DIGITSThen commit as in step 3.
