Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ export default defineConfig({
},
],
customCss: ["./src/styles/custom.css"],
// Component overrides for custom design
// Component overrides for custom design and analytics
components: {
Sidebar: "./src/components/overrides/Sidebar.astro",
EditLink: "./src/components/overrides/EditLink.astro",
Head: "./src/components/overrides/Head.astro",
Search: "./src/components/overrides/Search.astro",
},
// Autogenerate sidebar from directory structure
// Contributors only need to add frontmatter to control ordering
Expand Down
113 changes: 113 additions & 0 deletions docs/src/components/PostHog.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
/**
* PostHog Analytics Component
*
* Initializes PostHog for:
* - Page view tracking
* - Autocapture (clicks, form submits)
* - Session replay
* - Custom event tracking
*
* Uses a reverse proxy through Vercel to bypass ad-blockers.
*
* Environment Variables:
* - PUBLIC_POSTHOG_KEY: Your PostHog project API key (required)
*
* @see https://posthog.com/docs/libraries/astro
*/

// Get PostHog key from environment variable
// In Astro, PUBLIC_ prefixed env vars are available on the client
const posthogKey = import.meta.env.PUBLIC_POSTHOG_KEY || "";
---

<script is:inline data-posthog-init data-posthog-key={posthogKey}>
// Prevent double-initialization during view transitions
if (!window.__posthog_initialized) {
window.__posthog_initialized = true;

// Get the API key from the script's data attribute
const scriptEl = document.querySelector("script[data-posthog-key]");
const posthogKey = scriptEl?.getAttribute("data-posthog-key");

if (!posthogKey) {
console.warn(
"[PostHog] No API key found. Set PUBLIC_POSTHOG_KEY environment variable.",
);
} else {
!(function (t, e) {
var o, n, p, r;
e.__SV ||
((window.posthog = e),
(e._i = []),
(e.init = function (i, s, a) {
function g(t, e) {
var o = e.split(".");
(2 == o.length && ((t = t[o[0]]), (e = o[1])),
(t[e] = function () {
t.push([e].concat(Array.prototype.slice.call(arguments, 0)));
}));
}
(((p = t.createElement("script")).type = "text/javascript"),
(p.crossOrigin = "anonymous"),
(p.async = !0),
(p.src = s.api_host + "/static/array.js"),
(r = t.getElementsByTagName("script")[0]).parentNode.insertBefore(
p,
r,
));
var u = e;
for (
void 0 !== a ? (u = e[a] = []) : (a = "posthog"),
u.people = u.people || [],
u.toString = function (t) {
var e = "posthog";
return (
"posthog" !== a && (e += "." + a),
t || (e += " (stub)"),
e
);
},
u.people.toString = function () {
return u.toString(1) + ".people (stub)";
},
o =
"capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys getNextSurveyStep onSessionId".split(
" ",
),
n = 0;
n < o.length;
n++
)
g(u, o[n]);
e._i.push([i, s, a]);
}),
(e.__SV = 1));
})(document, window.posthog || []);

// Initialize PostHog
// Use reverse proxy on Vercel to bypass ad-blockers
// Fall back to direct EU URL for local development/preview
const isLocalhost =
window.location.hostname === "localhost" ||
window.location.hostname === "127.0.0.1";
const apiHost = isLocalhost ? "https://eu.i.posthog.com" : "/ingest";

window.posthog.init(posthogKey, {
api_host: apiHost,
ui_host: "https://eu.posthog.com",
person_profiles: "always",
capture_pageview: true,
capture_pageleave: true,
autocapture: true,
// Enable session replay for watching user journeys
session_recording: {
maskAllInputs: false,
maskInputOptions: {
password: true,
},
},
});
}
}
</script>
20 changes: 20 additions & 0 deletions docs/src/components/overrides/Head.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
/**
* Custom Head Component with PostHog Analytics
*
* Extends Starlight's default Head component to inject PostHog analytics.
* PostHog is loaded early in the head to capture all page interactions.
*
* @see https://starlight.astro.build/guides/overriding-components/
*/
import PostHog from "../PostHog.astro";

const { head } = Astro.locals.starlightRoute;
---

{
head.map(({ tag: Tag, attrs, content }) => (
<Tag {...attrs} set:html={content} />
))
}
<PostHog />
Loading