Omnibus Instrument Integration
PostHogOfficialCreated by PostHog
- Skill
- Tool integration
- Data and AI
- MIT
- Low risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured, multi-step procedure for integrating the PostHog SDK into a wide variety of software projects. It guides the agent through detecting the project's framework, installing the appropriate SDK, initializing the client, and configuring environment variables. By leveraging a library of framework-specific reference files, the skill ensures that PostHog is implemented according to best practices for each supported platform, including web, mobile, and backend environments.
What it does
- Detects the project's framework and package manager automatically.
- Installs the correct PostHog SDK for the identified platform.
- Initializes the PostHog client using framework-specific patterns.
- Configures environment variables for API keys and host settings.
- Implements user identification logic for login and signup events.
- Verifies the integration and performs necessary cleanup.
When to use it
- When setting up PostHog in a project for the first time.
- When reviewing pull requests that require PostHog initialization.
- When migrating or adding analytics to an existing codebase.
- When you need to ensure PostHog is configured consistently across different frameworks.
Advantages
- Supports a broad range of frameworks and languages.
- Ensures secure configuration by enforcing the use of environment variables.
- Maintains consistency with existing codebase patterns.
- Reduces manual effort by automating SDK installation and boilerplate setup.
Usage examples
- “Add PostHog to my new Next.js project.”
- The agent will detect the Next.js framework, install the PostHog SDK, and provide the necessary initialization code in the appropriate file, such as instrumentation-client.ts.
- “Help me set up PostHog in our Android app.”
- The agent will identify the Android environment, guide the setup in the Application class, and configure the PostHog instance with the required API keys.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/posthog/omnibus-instrument-integration/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip omnibus-instrument-integration.zip -d .agents/skills
Documentation by PostHog
Add PostHog SDK integration
Use this skill to add the PostHog SDK to an application. Use it when setting up PostHog for the first time, or reviewing PRs that need PostHog initialization. Covers SDK installation, provider setup, and basic configuration. Supports any framework or language.
Supported frameworks: Next.js, React, React Router, Vue, Nuxt, TanStack Start, SvelteKit, Astro, Angular, Django, Flask, FastAPI, Laravel, Ruby on Rails, Android, Swift, React Native, Expo, Node.js, and vanilla JavaScript.
Instructions
Follow these steps IN ORDER:
STEP 1: Analyze the codebase and detect the platform.
Look for dependency files (package.json, requirements.txt, Gemfile, composer.json, go.mod, etc.) to determine the framework and language.
Look for lockfiles (pnpm-lock.yaml, package-lock.json, yarn.lock, bun.lockb) to determine the package manager.
Check for existing PostHog setup. If PostHog is already installed and initialized, do not modify its code. Inform the user and skip to verification.
STEP 2: Research integration. 2.1. Find the reference file below that matches the detected framework — it is the source of truth for SDK initialization, provider setup, and configuration patterns. Read it now. 2.2. If no reference matches, fall back to your general knowledge and web search. Use posthog.com/docs as the primary search source.
STEP 3: Install the PostHog SDK.
Add the PostHog SDK package for the detected platform. Do not manually edit package.json — use the package manager's install command.
Always install packages as a background task. Don't await completion; proceed with other work immediately after starting the installation.
STEP 4: Initialize PostHog.
Follow the framework reference for where and how to initialize. This varies significantly by framework (e.g., instrumentation-client.ts for Next.js 15.3+, AppConfig.ready() for Django, create_app() for Flask).
Set up the PostHog provider/wrapper component if the framework requires one.
STEP 5: Identify users.
Add PostHog
identify()calls on the client side during login and signup events.If both frontend and backend exist, pass the client-side session and distinct ID using
X-POSTHOG-DISTINCT-IDandX-POSTHOG-SESSION-IDheaders to the server-side code.
STEP 6: Set up environment variables.
Store the PostHog API key and host in environment variables (e.g.
.envor framework-specific env files).Reference these environment variables in code instead of hardcoding them.
STEP 7: Verify and clean up.
Check the project for errors. Look for type checking or build scripts in package.json.
Ensure any components created were actually used.
Run any linter or prettier-like scripts found in the package.json.
Reference files
references/EXAMPLE-next-app-router.md- next-app-router example project codereferences/EXAMPLE-next-pages-router.md- next-pages-router example project codereferences/EXAMPLE-react-react-router-6.md- react-react-router-6 example project codereferences/EXAMPLE-react-react-router-7-framework.md- react-react-router-7-framework example project codereferences/EXAMPLE-react-react-router-7-data.md- react-react-router-7-data example project codereferences/EXAMPLE-react-react-router-7-declarative.md- react-react-router-7-declarative example project codereferences/EXAMPLE-react-vite.md- react-vite example project codereferences/EXAMPLE-nuxt-3.6.md- nuxt-3.6 example project codereferences/EXAMPLE-nuxt-4.md- nuxt-4 example project codereferences/EXAMPLE-vue-3.md- vue-3 example project codereferences/EXAMPLE-react-tanstack-router-file-based.md- react-tanstack-router-file-based example project codereferences/EXAMPLE-react-tanstack-router-code-based.md- react-tanstack-router-code-based example project codereferences/EXAMPLE-tanstack-start.md- tanstack-start example project codereferences/EXAMPLE-sveltekit.md- sveltekit example project codereferences/EXAMPLE-astro-static.md- astro-static example project codereferences/EXAMPLE-astro-view-transitions.md- astro-view-transitions example project codereferences/EXAMPLE-astro-ssr.md- astro-ssr example project codereferences/EXAMPLE-astro-hybrid.md- astro-hybrid example project codereferences/EXAMPLE-angular.md- angular example project codereferences/EXAMPLE-javascript-node.md- javascript-node example project codereferences/EXAMPLE-javascript-web.md- javascript-web example project codereferences/EXAMPLE-django.md- django example project codereferences/EXAMPLE-flask.md- flask example project codereferences/EXAMPLE-fastapi.md- fastapi example project codereferences/EXAMPLE-python.md- python example project codereferences/EXAMPLE-laravel.md- laravel example project codereferences/EXAMPLE-ruby-on-rails.md- ruby-on-rails example project codereferences/EXAMPLE-ruby.md- ruby example project codereferences/EXAMPLE-android.md- android example project codereferences/EXAMPLE-swift.md- swift example project codereferences/EXAMPLE-react-native.md- react-native example project codereferences/EXAMPLE-expo.md- expo example project codereferences/next-js.md- Next.js - docsreferences/react.md- React - docsreferences/react-router-v6.md- React router v6 - docsreferences/react-router-v7-framework-mode.md- React router v7 framework mode (remix v3) - docsreferences/react-router-v7-data-mode.md- React router v7 data mode - docsreferences/react-router-v7-declarative-mode.md- React router v7 declarative mode - docsreferences/nuxt-js-3-6.md- Nuxt.js (v3.0 to v3.6) - docsreferences/nuxt-js.md- Nuxt.js - docsreferences/vue-js.md- Vue.js - docsreferences/tanstack-start.md- Tanstack start - docsreferences/svelte.md- Svelte - docsreferences/astro.md- Astro - docsreferences/angular.md- Angular - docsreferences/js.md- JavaScript web - docsreferences/posthog-js.md- PostHog JavaScript web SDKreferences/node.md- Node.js - docsreferences/posthog-node.md- PostHog Node.js SDKreferences/django.md- Django - docsreferences/flask.md- Flask - docsreferences/python.md- Python - docsreferences/posthog-python.md- PostHog python SDKreferences/laravel.md- Laravel - docsreferences/ruby-on-rails.md- Ruby on rails - docsreferences/ruby.md- Ruby - docsreferences/android.md- Android - docsreferences/ios.md- Ios - docsreferences/react-native.md- React native - docsreferences/identify-users.md- Identify users - docs
Each framework reference contains SDK-specific installation, initialization, and usage patterns. Find the one matching the user's stack.
Key principles
Environment variables: Always use environment variables for PostHog keys. Never hardcode them.
Minimal changes: Add PostHog code alongside existing integrations. Don't replace or restructure existing code.
Match the example: Your implementation should follow the example project's patterns as closely as possible.
Analytics contract: Treat event names, property names, and feature flag keys as part of an analytics contract. Reuse existing names and patterns found in the project. When introducing new ones, make them clear, descriptive, and consistent with existing conventions.
Files
- ATTRIBUTION.mdAdded by AutoGineer998 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md7.6 KiB
- references/EXAMPLE-android.md49.7 KiB
- references/EXAMPLE-angular.md23.4 KiB
- references/EXAMPLE-astro-hybrid.md26.8 KiB
- references/EXAMPLE-astro-ssr.md26.7 KiB
- references/EXAMPLE-astro-static.md19.4 KiB
- references/EXAMPLE-astro-view-transitions.md23.1 KiB
- references/EXAMPLE-django.md30.0 KiB
- references/EXAMPLE-expo.md35.5 KiB
- references/EXAMPLE-fastapi.md40.9 KiB
- references/EXAMPLE-flask.md32.0 KiB
- references/EXAMPLE-javascript-node.md9.0 KiB
- references/EXAMPLE-javascript-web.md11.7 KiB
- references/EXAMPLE-laravel.md59.5 KiB
- references/EXAMPLE-next-app-router.md17.3 KiB
- references/EXAMPLE-next-pages-router.md18.9 KiB
- references/EXAMPLE-nuxt-3.6.md22.1 KiB
- references/EXAMPLE-nuxt-4.md28.7 KiB
- references/EXAMPLE-python.md11.6 KiB
- references/EXAMPLE-react-native.md46.4 KiB
- references/EXAMPLE-react-react-router-6.md13.5 KiB
- references/EXAMPLE-react-react-router-7-data.md20.1 KiB
- references/EXAMPLE-react-react-router-7-declarative.md15.0 KiB
- references/EXAMPLE-react-react-router-7-framework.md32.2 KiB
- references/EXAMPLE-react-tanstack-router-code-based.md19.2 KiB
- references/EXAMPLE-react-tanstack-router-file-based.md18.0 KiB
- references/EXAMPLE-react-vite.md12.4 KiB
- references/EXAMPLE-ruby-on-rails.md37.6 KiB
- references/EXAMPLE-ruby.md10.3 KiB
- references/EXAMPLE-sveltekit.md18.4 KiB
- references/EXAMPLE-swift.md18.6 KiB
- references/EXAMPLE-tanstack-start.md28.4 KiB
- references/EXAMPLE-vue-3.md17.9 KiB
- references/android.md21.7 KiB
- references/angular.md12.5 KiB
- references/astro.md8.3 KiB
- references/django.md6.7 KiB
- references/flask.md2.9 KiB
- references/identify-users.md8.1 KiB
- references/ios.md5.4 KiB
- references/js.md12.3 KiB
- references/laravel.md2.1 KiB
- references/next-js.md12.5 KiB
- references/node.md28.8 KiB
- references/nuxt-js-3-6.md6.6 KiB
- references/nuxt-js.md7.2 KiB
- references/posthog-js.md42.3 KiB
- references/posthog-node.md23.4 KiB
- references/posthog-python.md31.3 KiB
- references/python.md31.1 KiB
- references/react-native.md43.8 KiB
- references/react-router-v6.md11.6 KiB
- references/react-router-v7-data-mode.md11.4 KiB
- references/react-router-v7-declarative-mode.md11.6 KiB
- references/react-router-v7-framework-mode.md14.9 KiB
- references/react.md18.5 KiB
- references/ruby-on-rails.md10.6 KiB
- references/ruby.md18.9 KiB
- references/svelte.md7.2 KiB
- references/tanstack-start.md5.1 KiB
- references/vue-js.md9.1 KiB
references/EXAMPLE-astro-static.md
PostHog astro-static Example Project
Repository: https://github.com/PostHog/context-mill Path: basics/astro-static
README.md
PostHog Astro Static Example
This is an Astro static site (SSG) example demonstrating PostHog integration with product analytics, session replay, and error tracking.
It uses the PostHog web snippet directly and shows how to:
Initialize PostHog in a static Astro site using a reusable component
Identify users after login
Track custom events from pages
Capture errors via
posthog.captureException()Reset PostHog state on logout
Features
Product analytics: Track login and burrito consideration events
Session replay: Enabled via PostHog snippet configuration
Error tracking: Manual error capture sent to PostHog
Simple auth flow: Demo login using localStorage
Getting started
1. Install dependencies
npm install
# or
pnpm install2. Configure environment variables
Create a .env file in the project root:
PUBLIC_POSTHOG_PROJECT_TOKEN=your_posthog_project_token
PUBLIC_POSTHOG_HOST=https://us.i.posthog.comGet your PostHog project token from your project settings in PostHog.
3. Run the development server
npm run dev
# or
pnpm devOpen http://localhost:4321 in your browser.
Project structure
src/
components/
posthog.astro # PostHog snippet with is:inline directive
Header.astro # Navigation + logout, calls posthog.reset()
layouts/
PostHogLayout.astro # Root layout that includes PostHog + Header
lib/
auth.ts # Auth utilities (localStorage-based)
pages/
index.astro # Login form, identifies user + captures 'user_logged_in'
burrito.astro # Burrito consideration demo, captures 'burrito_considered'
profile.astro # Profile + error tracking demo
styles/
global.css # Global stylesKey integration points
PostHog initialization (src/components/posthog.astro)
The PostHog snippet is included as an inline script to prevent Astro from processing it:
<script is:inline>
!function(t,e){...}(document,window.posthog||[]);
posthog.init('<ph_project_token>', {
api_host: 'https://us.i.posthog.com',
defaults: '2026-01-30'
})
</script>The is:inline directive is required to prevent TypeScript errors about window.posthog.
User identification (src/pages/index.astro)
After a successful "login", the app identifies the user and captures a login event:
window.posthog?.identify(username);
window.posthog?.capture("user_logged_in");Identification happens only on login, all further requests will automatically use the same distinct ID.
Event tracking (src/pages/burrito.astro)
The burrito page tracks a custom event when a user "considers" the burrito:
window.posthog?.capture("burrito_considered", {
total_considerations: newCount,
username: currentUser,
});This shows how to attach useful properties to events (e.g. counts, usernames).
Error tracking (src/pages/profile.astro)
The profile page includes a button to trigger a test error:
try {
throw new Error("Test error for PostHog error tracking");
} catch (err) {
window.posthog?.captureException(err);
}Logout and session reset (src/components/Header.astro)
On logout, both the local auth state and PostHog state are cleared:
window.posthog?.capture("user_logged_out");
localStorage.removeItem("currentUser");
window.posthog?.reset();posthog.reset() clears the current distinct ID and session so the next login starts a fresh identity.
Scripts
# Run dev server
npm run dev
# Build for production
npm run build
# Preview production build
npm run previewLearn more
.env.example
PUBLIC_POSTHOG_PROJECT_TOKEN=your_posthog_project_token_here
PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({});
src/components/Header.astro
---
// Header component with navigation and logout functionality
---
<header class="header">
<div class="header-container">
<nav>
<a href="/">Home</a>
<a href="/burrito" class="auth-link" style="display: none;">Burrito Consideration</a>
<a href="/profile" class="auth-link" style="display: none;">Profile</a>
</nav>
<div class="user-section">
<span class="welcome-text" style="display: none;">Welcome, <span class="username"></span>!</span>
<span class="not-logged-in">Not logged in</span>
<button class="btn-logout" style="display: none;">Logout</button>
</div>
</div>
</header>
<script is:inline>
function updateHeader() {
const currentUser = localStorage.getItem('currentUser');
const authLinks = document.querySelectorAll('.auth-link');
const welcomeText = document.querySelector('.welcome-text');
const notLoggedIn = document.querySelector('.not-logged-in');
const logoutBtn = document.querySelector('.btn-logout');
const usernameSpan = document.querySelector('.username');
if (currentUser) {
authLinks.forEach(link => link.style.display = 'inline');
welcomeText.style.display = 'inline';
notLoggedIn.style.display = 'none';
logoutBtn.style.display = 'inline';
usernameSpan.textContent = currentUser;
} else {
authLinks.forEach(link => link.style.display = 'none');
welcomeText.style.display = 'none';
notLoggedIn.style.display = 'inline';
logoutBtn.style.display = 'none';
}
}
function handleLogout() {
const currentUser = localStorage.getItem('currentUser');
if (currentUser) {
window.posthog?.capture('user_logged_out');
}
localStorage.removeItem('currentUser');
localStorage.removeItem('burritoConsiderations');
// IMPORTANT: Reset the PostHog instance to clear the user session
window.posthog?.reset();
window.location.href = '/';
}
document.addEventListener('DOMContentLoaded', () => {
updateHeader();
document.querySelector('.btn-logout')?.addEventListener('click', handleLogout);
});
// Listen for storage changes (login/logout in other tabs)
window.addEventListener('storage', updateHeader);
</script>
<style>
.header {
background-color: #333;
color: white;
padding: 1rem;
}
.header-container {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
}
.header nav {
display: flex;
gap: 1rem;
}
.header a {
color: white;
text-decoration: none;
padding: 0.5rem 1rem;
border-radius: 4px;
transition: background-color 0.2s;
}
.header a:hover {
background-color: #555;
text-decoration: none;
}
.user-section {
display: flex;
align-items: center;
gap: 1rem;
}
.btn-logout {
background-color: #dc3545;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.btn-logout:hover {
background-color: #c82333;
}
</style>
src/components/posthog.astro
---
// PostHog analytics snippet
// Uses is:inline to prevent Astro from processing the script
---
<script is:inline define:vars={{ apiKey: import.meta.env.PUBLIC_POSTHOG_PROJECT_TOKEN, apiHost: import.meta.env.PUBLIC_POSTHOG_HOST }}>
!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||[]);
posthog.init(apiKey || '', {
api_host: apiHost || 'https://us.i.posthog.com',
defaults: '2026-01-30'
})
</script>
src/layouts/PostHogLayout.astro
---
import PostHog from '../components/posthog.astro';
import Header from '../components/Header.astro';
import '../styles/global.css';
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Astro PostHog Integration Example" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>{title}</title>
<PostHog />
</head>
<body>
<Header />
<main>
<slot />
</main>
</body>
</html>
src/lib/auth.ts
// Client-side auth utilities for localStorage-based authentication
export interface User {
username: string;
burritoConsiderations: number;
}
export function getCurrentUser(): User | null {
if (typeof window === "undefined") return null;
const username = localStorage.getItem("currentUser");
if (!username) return null;
const considerations = parseInt(
localStorage.getItem("burritoConsiderations") || "0",
10,
);
return {
username,
burritoConsiderations: considerations,
};
}
export function login(username: string, password: string): boolean {
if (!username || !password) return false;
localStorage.setItem("currentUser", username);
// Initialize burrito considerations if not set
if (!localStorage.getItem("burritoConsiderations")) {
localStorage.setItem("burritoConsiderations", "0");
}
return true;
}
export function logout(): void {
localStorage.removeItem("currentUser");
localStorage.removeItem("burritoConsiderations");
}
export function incrementBurritoConsiderations(): number {
const current = parseInt(
localStorage.getItem("burritoConsiderations") || "0",
10,
);
const newCount = current + 1;
localStorage.setItem("burritoConsiderations", newCount.toString());
return newCount;
}
src/pages/burrito.astro
---
import PostHogLayout from '../layouts/PostHogLayout.astro';
---
<PostHogLayout title="Burrito Consideration - Astro PostHog Example">
<div class="container">
<h1>Burrito consideration zone</h1>
<p>Take a moment to truly consider the potential of burritos.</p>
<div style="text-align: center;">
<button id="consider-btn" class="btn-burrito">
I have considered the burrito potential
</button>
<p id="success-message" class="success" style="display: none;">
Thank you for your consideration! Count: <span id="consideration-count"></span>
</p>
</div>
<div class="stats">
<h3>Consideration stats</h3>
<p>Total considerations: <span id="total-considerations">0</span></p>
</div>
</div>
</PostHogLayout>
<script is:inline>
function checkAuth() {
const currentUser = localStorage.getItem('currentUser');
if (!currentUser) {
window.location.href = '/';
return false;
}
return true;
}
function updateStats() {
const count = localStorage.getItem('burritoConsiderations') || '0';
document.getElementById('total-considerations').textContent = count;
}
function handleConsideration() {
const currentUser = localStorage.getItem('currentUser');
if (!currentUser) return;
// Increment the count
const currentCount = parseInt(localStorage.getItem('burritoConsiderations') || '0', 10);
const newCount = currentCount + 1;
localStorage.setItem('burritoConsiderations', newCount.toString());
// Update the UI
updateStats();
const successMessage = document.getElementById('success-message');
const considerationCount = document.getElementById('consideration-count');
considerationCount.textContent = newCount;
successMessage.style.display = 'block';
// Hide success message after 2 seconds
setTimeout(() => {
successMessage.style.display = 'none';
}, 2000);
// Capture burrito consideration event in PostHog
window.posthog?.capture('burrito_considered', {
total_considerations: newCount,
username: currentUser
});
}
document.addEventListener('DOMContentLoaded', () => {
if (!checkAuth()) return;
updateStats();
document.getElementById('consider-btn')?.addEventListener('click', handleConsideration);
});
</script>
src/pages/index.astro
---
import PostHogLayout from '../layouts/PostHogLayout.astro';
---
<PostHogLayout title="Home - Astro PostHog Example">
<div class="container">
<div id="logged-in-view" style="display: none;">
<h1>Welcome back, <span id="welcome-username"></span>!</h1>
<p>You are now logged in. Feel free to explore:</p>
<ul>
<li>Consider the potential of burritos</li>
<li>View your profile and statistics</li>
</ul>
</div>
<div id="logged-out-view">
<h1>Welcome to Burrito Consideration App</h1>
<p>Please sign in to begin your burrito journey</p>
<form id="login-form" class="form">
<div class="form-group">
<label for="username">Username:</label>
<input
type="text"
id="username"
placeholder="Enter any username"
required
/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input
type="password"
id="password"
placeholder="Enter any password"
required
/>
</div>
<p id="error-message" class="error" style="display: none;"></p>
<button type="submit" class="btn-primary">Sign In</button>
</form>
<p class="note">
Note: This is a demo app. Use any username and password to sign in.
</p>
</div>
</div>
</PostHogLayout>
<script is:inline>
function updateView() {
const currentUser = localStorage.getItem('currentUser');
const loggedInView = document.getElementById('logged-in-view');
const loggedOutView = document.getElementById('logged-out-view');
const welcomeUsername = document.getElementById('welcome-username');
if (currentUser) {
loggedInView.style.display = 'block';
loggedOutView.style.display = 'none';
welcomeUsername.textContent = currentUser;
} else {
loggedInView.style.display = 'none';
loggedOutView.style.display = 'block';
}
}
function handleLogin(event) {
event.preventDefault();
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const errorMessage = document.getElementById('error-message');
if (!username || !password) {
errorMessage.textContent = 'Please provide both username and password';
errorMessage.style.display = 'block';
return;
}
// Client-side only fake auth - store in localStorage
localStorage.setItem('currentUser', username);
if (!localStorage.getItem('burritoConsiderations')) {
localStorage.setItem('burritoConsiderations', '0');
}
// Identify the user in PostHog (once on login is enough)
window.posthog?.identify(username);
window.posthog?.capture('user_logged_in');
// Clear form
document.getElementById('username').value = '';
document.getElementById('password').value = '';
errorMessage.style.display = 'none';
// Update view
updateView();
// Trigger header update
window.dispatchEvent(new Event('storage'));
}
document.addEventListener('DOMContentLoaded', () => {
updateView();
document.getElementById('login-form')?.addEventListener('submit', handleLogin);
});
// Listen for storage changes
window.addEventListener('storage', updateView);
</script>
src/pages/profile.astro
---
import PostHogLayout from '../layouts/PostHogLayout.astro';
---
<PostHogLayout title="Profile - Astro PostHog Example">
<div class="container">
<h1>User Profile</h1>
<div class="stats">
<h2>Your Information</h2>
<p><strong>Username:</strong> <span id="profile-username"></span></p>
<p><strong>Burrito Considerations:</strong> <span id="profile-considerations">0</span></p>
</div>
<div style="margin-top: 2rem;">
<h3>Your Burrito Journey</h3>
<p id="journey-message"></p>
</div>
<div style="margin-top: 2rem;">
<h3>Error Tracking Demo</h3>
<p>Click the button below to trigger a test error and send it to PostHog:</p>
<button id="error-btn" class="btn-error">
Trigger Test Error
</button>
<p id="error-feedback" class="success" style="display: none;">
Error captured and sent to PostHog!
</p>
</div>
</div>
</PostHogLayout>
<script is:inline>
function checkAuth() {
const currentUser = localStorage.getItem('currentUser');
if (!currentUser) {
window.location.href = '/';
return false;
}
return true;
}
function updateProfile() {
const username = localStorage.getItem('currentUser') || '';
const considerations = parseInt(localStorage.getItem('burritoConsiderations') || '0', 10);
document.getElementById('profile-username').textContent = username;
document.getElementById('profile-considerations').textContent = considerations;
// Update journey message based on consideration count
const journeyMessage = document.getElementById('journey-message');
if (considerations === 0) {
journeyMessage.textContent = "You haven't considered any burritos yet. Visit the Burrito Consideration page to start!";
} else if (considerations === 1) {
journeyMessage.textContent = "You've considered the burrito potential once. Keep going!";
} else if (considerations < 5) {
journeyMessage.textContent = "You're getting the hang of burrito consideration!";
} else if (considerations < 10) {
journeyMessage.textContent = "You're becoming a burrito consideration expert!";
} else {
journeyMessage.textContent = "You are a true burrito consideration master!";
}
}
function triggerTestError() {
try {
throw new Error('Test error for PostHog error tracking');
} catch (err) {
// Capture the error in PostHog
window.posthog?.captureException(err);
console.error('Captured error:', err);
// Show feedback to user
const feedback = document.getElementById('error-feedback');
feedback.style.display = 'block';
setTimeout(() => {
feedback.style.display = 'none';
}, 3000);
}
}
document.addEventListener('DOMContentLoaded', () => {
if (!checkAuth()) return;
updateProfile();
document.getElementById('error-btn')?.addEventListener('click', triggerTestError);
});
</script>
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an API key, Needs Python, Needs Node.js
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- PostHog
- Publisher
- PostHog (Official)
- Source
- PostHog/skills · skills/posthog/all/skills/omnibus-instrument-integration · commit a5d30e7
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by PostHog.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download omnibus-instrument-integration.zip