Quick Start #
Add a single <script> tag to your site and TesterBuddy starts capturing events immediately. No npm install, no build step.
<script src="https://testerbuddy.app/sdk/testerbuddy.js"
data-app-key="YOUR_API_KEY"
data-mode="all">
</script>
Paste this snippet just before the closing </body> tag. Replace YOUR_API_KEY with the key found in the Web SDK tab of your app in TesterBuddy.
-
1
Create a Web App in TesterBuddyOpen TesterBuddy → tap + → choose platform Web → enter your site URL and app name.
-
2
Copy your API KeyGo to the Web SDK tab inside your app. Copy the Web API Key shown at the top.
-
3
Add the script to your sitePaste the snippet above into every HTML page (or your base template /
<head>partial). Works with React, Vue, Nuxt, plain HTML — anything that serves HTML. -
4
Trigger an event and verifyLoad your site, open the console and deliberately trigger a JS error (
undeclaredVar.foo). Within seconds it appears in the Web Events list in TesterBuddy.
API Key #
Each web app in TesterBuddy has a unique Web API Key. This key is used by the SDK to authenticate your events. It is safe to include in your front-end HTML — it can only be used to write events, never to read them or access your account.
- Open TesterBuddy on iOS
- Tap your web app to open the detail view
- Tap Web SDK (the code icon in the toolbar)
- The Web API Key is displayed at the top — tap to copy
If you accidentally expose your key, contact support via Settings → Contact Support inside TesterBuddy to request a rotation. After rotation, update the data-app-key attribute in your HTML.
Tracking Modes #
The data-mode attribute controls which visitors the SDK tracks. Choose the mode that fits your testing workflow.
| Mode | Who is tracked | Best for |
|---|---|---|
all (default) |
Every visitor to your site | Public beta or staging sites where you want maximum coverage |
testers |
Only visitors who are enrolled TesterBuddy testers | Production sites — limits noise from real users |
<script src="https://testerbuddy.app/sdk/testerbuddy.js"
data-app-key="YOUR_API_KEY"
data-mode="testers">
</script>
testers mode the SDK checks for a TesterBuddy session cookie set when the tester opened your test URL from the iOS app. No login popup is shown — unrecognised visitors are simply ignored silently.
Automatic Tracking #
As soon as the script loads, TesterBuddy passively monitors four categories of events. Nothing extra to configure.
fetch() and XMLHttpRequest calls — captures the URL, HTTP status, and response time.TesterBuddy never captures form values, passwords, credit card fields, or any DOM content. It never uses fingerprinting. Events contain: URL, error message, stack trace, user agent string, and a randomly generated session ID.
Custom Events — track()
#
Log any user action with TesterBuddy.track(name, metadata). Custom events appear in the dashboard with type custom and are grouped by their event name.
// Basic event
TesterBuddy.track('button_clicked', { label: 'Sign Up' });
// With rich metadata
TesterBuddy.track('checkout_started', {
plan: 'pro',
price: 29.99,
currency: 'USD',
items: 3
});
// React — on user interaction
<button onClick={() =>
TesterBuddy.track('hero_cta', { variant: 'A' })
}>
Get Started
</button>
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string |
required | Event name. Use snake_case for consistency. Max 200 chars. |
metadata |
object |
optional | Any JSON-serializable key/value pairs. Shown in the event detail view. Max depth 3. |
track() calls made before it initialises, so it's safe to call TesterBuddy.track() anywhere in your JS — even at the top of <head>.
Identified Testers #
When a tester is signed into TesterBuddy and visits your site, their identity is attached to every event they generate — automatically. You'll see their name and avatar next to each error in the dashboard.
You can also explicitly identify a tester from your own app using TesterBuddy.identify(). This links your internal user ID or email to the session:
// Identify by email (must match TesterBuddy account)
TesterBuddy.identify('tester@example.com');
// Or by TesterBuddy user ID
TesterBuddy.identify(42);
// Call after your own login flow completes
async function onSignIn(user) {
await yourAuthFlow(user);
TesterBuddy.identify(user.email);
}
identify() doesn't match a TesterBuddy account enrolled in your app, the event is still recorded — it will just appear without a name in the dashboard.
Script Attributes #
All configuration is done via data-* attributes on the script tag — no JavaScript setup required.
| Attribute | Required | Default | Description |
|---|---|---|---|
data-app-key |
required | — | Your Web API Key. Found in the Web SDK tab of your app. |
data-mode |
optional | "all" |
"all" or "testers". See Tracking Modes. |
data-session-id |
optional | auto | Override the auto-generated session ID. Useful if you have your own session management. |
<script
src="https://testerbuddy.app/sdk/testerbuddy.js"
data-app-key="tb_live_abc123xyz"
data-mode="testers"
data-session-id="your-own-session-id"
></script>
Browser Support #
TesterBuddy uses modern Web APIs. All evergreen browsers are fully supported. For older environments the SDK degrades gracefully — it will still capture JS errors but some metrics may be unavailable.
| Browser | Support | Notes |
|---|---|---|
| Chrome / Edge 90+ | ✓ Full | All features including performance metrics |
| Firefox 88+ | ✓ Full | All features |
| Safari 14+ | ✓ Full | All features; sendBeacon used for exit events |
| Safari 12–13 | ◑ Partial | Errors + page views; no performance timing |
| IE 11 | ◑ Partial | Errors only; custom events not available |
| IE <11 | — | SDK loads silently and does nothing |
Web Events View #
In TesterBuddy, open any web app and tap the Web Events tab (globe icon). You'll see all events captured from your site in real time.
Tap the segmented control at the top to filter by event type: All, Errors, Network, Performance, Page Views, or Custom.
Tap any event to see the full detail view: error message, stack trace (formatted), page URL, user agent, session ID, and the tester's name and avatar if they were identified.
Toggle between Grouped (deduplicated by message) and Individual (chronological stream) using the control at the top right. Grouped view is the default — it's the most useful for spotting patterns.
Grouped Errors #
The grouped view deduplicates events by message. Instead of seeing 47 identical "Cannot read properties of undefined" entries, you see one row with ×47. Each row shows:
- Occurrence count — total times this event was captured
- Unique sessions — how many independent visits triggered it
- Affected testers — identified testers who hit this issue
- Last seen — relative time (e.g. "3h ago")
- Fixed badge — shown in green when the error hasn't recurred in 24 hours
Tap any row to see the full timeline: first occurrence, last occurrence, the most recent individual event, and an explanation of whether it's considered fixed.
Fixed Status Indicator #
TesterBuddy automatically marks an error group as Fixed when it has not been seen in the last 24 hours. This gives you a quick signal that a bug is likely resolved — without requiring you to manually close tickets.
now − last_occurrence ≥ 24 hours. If the same error recurs after that window, the badge disappears and the occurrence count increments. There is no permanent "close" action — the system self-heals based on activity.
- Fixed (green badge) — No recurrence in 24h. Likely resolved by a recent deploy or no longer triggered.
- No badge — Error is still occurring or occurred within the last 24h. Needs attention.
The 24-hour window is the current default. Future versions may allow this threshold to be configured per app.
AI Summary #
Tap AI Summary on any app to generate an AI-powered analysis. For web apps, the summary incorporates three sources of signal:
- Tester chat messages and direct feedback
- Survey responses from testers
- Web SDK events — top recurring errors, network failures, and performance issues from the last 30 days
The AI correlates these sources and produces a structured report with a sentiment overview, key issues raised by testers, a technical incidents section (from SDK events), and actionable next steps.
Troubleshooting #
- Check the browser console for a
401 Unauthorizedresponse from/api/sdk/ingest. This means yourdata-app-keyis wrong or your app is not set to "active". - Make sure you're using the Web API Key, not your account token or TestFlight URL.
- Check that the script tag is present in the rendered HTML. Some frameworks (Next.js, etc.) require placing scripts in specific locations.
- If you're on a staging environment with CSP headers, add
https://testerbuddy.appto yourconnect-srcdirective.
Content-Security-Policy header:
Content-Security-Policy:
script-src 'self' https://testerbuddy.app;
connect-src 'self' https://testerbuddy.app;
- The SDK listens to
popstateand patcheshistory.pushState/replaceStateto detect SPA navigation. - If your framework uses hash routing (
#/path), page views may not be captured. UseTesterBuddy.track('pageview', { path: location.hash })manually in your router's navigation hook.
- TesterBuddy tries to scrape your site's
apple-touch-icon,og:image, then falls back to Google's favicon service. - If your site has a strict CORS or CSP policy, the backend scraper may be blocked. Use the Custom Icon URL option in Edit App to paste a direct image URL.
- The icon fetch is triggered when the app is created or when you tap Refresh Icon in the app detail menu.
Frequently Asked Questions #
navigator.sendBeacon where available, so they don't block page unload. In all our testing the SDK adds <1 ms to page load time.
TesterBuddy.identify(). It never reads form values, DOM content, or fingerprints users. Session IDs are randomly generated per browser session and are not linked to any real identity. Events are associated with testers only when the tester is signed in to TesterBuddy and has opted into testing your app.
<Script strategy="afterInteractive"> in your _app.tsx or layout.tsx. For Vue, add it to your index.html. For React, use react-helmet or add it to public/index.html.
POST /api/sdk/ingest endpoint directly with a JSON body and your API key in the X-TB-Key header. See the API reference for the full payload schema.