Skip to main content
Most Web SDK issues fall into a small set of categories: misconfiguration, missing identification, storage restrictions, or network problems. Work through the relevant accordion below, then check the Common Error Messages table at the bottom if you need a quick reference.
Symptoms:
  • Console shows "App ID is required" on page load
  • No events appear in the Tappd dashboard
Cause: The appId field is missing, empty, or undefined in your config object.
// ❌ No appId provided
const tappd = new TappdSDK({});

// ❌ appId is undefined (env var not set)
const tappd = new TappdSDK({
  appId: process.env.TAPPD_APP_ID // undefined if not configured
});
Checklist:
  1. Copy your App ID from the Tappd dashboard — Settings → App ID.
  2. Confirm the environment variable is defined in your .env file and your build tool exposes it to the client.
  3. Verify the SDK script or npm package loads fully before your initialization code runs.
Symptoms:
  • track() resolves without errors
  • The Tappd dashboard shows no events
Step 1 — Enable debug mode to see what the SDK is doing:
const tappd = new TappdSDK({
  appId: 'YOUR_APP_ID',
  debug: true
});
// Console output examples:
// [Tappd SDK] Initialized with App ID: a1b2c3d4...
// [Tappd SDK] New session started: sess_abc123
// [Tappd SDK] Event tracked: purchase
Step 2 — Check the network tab:
  1. Open DevTools → Network.
  2. Filter by track or api.
  3. Confirm requests are sent and check their HTTP status codes.
  4. A 4xx response points to a config problem; a 5xx indicates a server issue.
Step 3 — Verify your API URL:
const tappd = new TappdSDK({
  appId: 'YOUR_APP_ID',
  apiUrl: 'https://sdk.gotappd.com/api/v1/sdk' // default — only override if needed
});
Step 4 — Look for CORS errors:
  • Check the browser console for "Access-Control-Allow-Origin" messages.
  • See the CORS Errors accordion below for fixes.
Symptoms:
  • Events tracked before identify() don’t appear on the user’s profile in the dashboard
  • User journeys look incomplete — the pre-login funnel is missing
Cause: identify() was never called, was called without a valid identifier, or was called after the session that contained the anonymous events had expired.
// ❌ Tracking events but never identifying the user
await tappd.track('page_view');
await tappd.track('button_click');
// These events stay anonymous forever
Common mistakes:
  • Passing null, undefined, or an empty string as external_id — the SDK throws "external_id is required in attributes".
  • Calling identify() in a later session without the same external_id — the SDK creates a new profile instead of merging.
  • Calling reset() before identify() — this clears the anonymous ID and breaks the merge chain.
Verify your anonymous ID is stable:
// Check this before and after identify() — the value should be the same
const anonymousId = tappd.getAnonymousId();
console.log('Anonymous ID:', anonymousId);
Symptoms:
  • getSessionId() returns null
  • Sessions restart far too frequently
Fix 1 — Increase the session timeout if sessions expire too quickly:
const tappd = new TappdSDK({
  appId: 'YOUR_APP_ID',
  sessionTimeout: 60 // minutes — default is 30
});
Fix 2 — Verify the session ID after initialization:
const sessionId = tappd.getSessionId();
console.log('Session ID:', sessionId);
// Should be a non-null string like sess_abc123def456
Sessions automatically pause when the browser tab is hidden and resume when it becomes visible again. This is expected behavior — it does not create a new session.
Symptoms:
  • Only the initial page load registers as a page view
  • Route changes in your single-page app are not tracked
Fix 1 — Confirm autoTrack is enabled (it is true by default):
const tappd = new TappdSDK({
  appId: 'YOUR_APP_ID',
  autoTrack: true
});
The SDK intercepts history.pushState to detect navigation. If your router overrides this in a non-standard way, use the manual approach below.Fix 2 — Track route changes manually in your router’s navigation hooks:
// Vue Router example
router.beforeEach((to, from) => {
  tappd.trackPageView(to.fullPath, {
    from: from.fullPath,
    routeName: to.name
  });
});

// React Router v6 example (inside a component that renders on every route)
useEffect(() => {
  tappd.trackPageView(window.location.pathname);
}, [location.pathname]);
Symptoms:
  • Each page load produces a different anonymous ID
  • Users appear as new visitors on every visit
Cause: The SDK stores the anonymous ID in localStorage. If storage is unavailable, blocked, or cleared between visits, a new ID is generated every time.Check 1 — Verify localStorage is available:
if (typeof Storage === 'undefined') {
  console.error('localStorage is not supported in this environment.');
}
Check 2 — Review your browser environment:
  • Private/incognito mode limits or blocks localStorage in some browsers — this is expected.
  • Check for browser extensions (ad blockers, privacy tools) that clear or block storage.
  • Confirm no other script in your app calls localStorage.clear() on page load.
Symptoms:
  • Browser console shows "CORS policy" or "Access-Control-Allow-Origin" errors
  • All network requests to the Tappd API fail
Fix 1 — Verify the default endpoint is reachable:Open a new tab and navigate to https://sdk.gotappd.com to confirm there is no network-level block (firewall, VPN, or DNS issue).Fix 2 — Check your custom domain setup:If you’re using a custom apiUrl, your domain must be allowlisted on the Tappd side. Contact Tappd support and provide:
  • Your production domain(s)
  • The custom apiUrl you are using
Do not set apiUrl to a custom value unless Tappd support has explicitly provided one for your account. Pointing to the wrong endpoint is the most common cause of CORS failures.
Symptoms:
  • TypeScript compiler reports errors when importing from @tappd/web-sdk
  • IntelliSense does not recognize SDK types
Fix — Use the named imports from the package:
import { TappdSDK, TappdConfig, CustomerAttributes } from '@tappd/web-sdk';

const config: TappdConfig = {
  appId: 'YOUR_APP_ID',
  debug: true
};

const tappd = new TappdSDK(config);

const userAttributes: CustomerAttributes = {
  external_id: 'user_123',
  email: 'jane@example.com',
  name: 'Jane Smith'
};

await tappd.identify(userAttributes);
If your project still shows type errors, install the Node type definitions:
npm install --save-dev @types/node
Symptoms:
  • Build fails with a module resolution error
  • SDK import throws at runtime in the browser
Fix — Use the correct import style for your build tool:
import { TappdSDK } from '@tappd/web-sdk';
Bundle size note: The SDK weighs approximately 10 KB — it should not cause any meaningful bundle size increase. Modern bundlers automatically tree-shake unused exports, so you only pay for what you import.

Getting Help

If you’ve worked through the accordions above and still can’t resolve the issue, follow these steps before reaching out to support:
1

Check the browser console

Look for red error messages when the SDK initializes or when you call a method. Copy the full error text.
2

Enable debug mode

Set debug: true in your TappdSDK config and reproduce the issue. The SDK logs every action to the console — capture the full output.
3

Inspect network requests

Open DevTools → Network, filter by api or tappd, and check the status codes and response bodies of failed requests.
4

Confirm your SDK version

Run npm list @tappd/web-sdk and verify you’re on the latest release. Update if needed: npm install @tappd/web-sdk@latest.
5

Contact support

Reach out with the following information so the team can reproduce and fix your issue quickly:
  • The full error message from the console
  • Your browser name and version
  • Your @tappd/web-sdk version
  • The debug log output from step 2

Common Error Messages

Error MessageCauseFix
"App ID is required"appId is missing or empty in the configProvide a valid appId from the Tappd dashboard
"User must be identified first"A method that requires identification was called before identify()Call identify() with at least one valid identifier first
"external_id is required in attributes"external_id passed as null, undefined, or ""Pass a non-empty string for external_id
"Request failed: ..."Network failure or API-level errorCheck your apiUrl, internet connection, and CORS configuration
"Push notifications not supported"Browser does not support the Push APIOnly prompt for push in supported browsers (check 'PushManager' in window)
"Notification permission denied"User has blocked notifications at the browser levelPrompt users before they deny, or guide them to reset permissions in browser settings