// βββ Bookmarks ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ// Open bookmark draweranalytics.trackBookmarkDrawerOpen()// Total saves snapshot (engagement / histogram)analytics.trackUserTotalSaves(totalSaves)// Save from footer (detail page)analytics.trackSavePatternFromFooter(pageTitle,pageId,totalSaves)// Save from page headeranalytics.trackSavePatternFromHeader(pageTitle,pageId,totalSaves)// Save from card (collection page)analytics.trackSavePatternFromCard(pageTitle,pageId,totalSaves,device?)// Save from search resultsanalytics.trackSavePatternFromSearch(pageTitle,pageId,totalSaves)// Remove single bookmarkanalytics.trackRemoveBookmark(pageTitle,pageId)// Clear all bookmarksanalytics.trackClearAllBookmarks(count)// Navigate to pattern from draweranalytics.trackBookmarkItemClick(pageTitle,pageId,slug)// βββ Images βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ// Image clickanalytics.trackImageClicked(imageUrl,pageTitle?)// Image lightbox/zoom openedanalytics.trackImageZoomOpen(imageUrl,pageTitle?)// βββ Search βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ// Search query submittedanalytics.trackSearchSubmit(query,resultCount)// Search result clickedanalytics.trackSearchResultClick(resultTitle,resultType,query)// βββ Navigation βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ// Random pattern button clickedanalytics.trackRandomPatternClick(source)// βββ Library βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ// Navigate to /library from profile dropdownanalytics.trackLibraryOpenedFromProfile()// Navigate to /library from bookmark draweranalytics.trackLibraryOpenedFromDrawer()// Public (read-only) library visit via share tokenanalytics.trackLibraryPublicView(ownerName?)// AI context description saved by owneranalytics.trackLibraryContextSaved(charCount)// Library title saved by owneranalytics.trackLibraryTitleSaved(charCount)// Owner copies the public share linkanalytics.trackLibraryCopyLink()// Owner regenerates the public share linkanalytics.trackLibraryResetLink()// Library sharing status changedanalytics.trackLibraryShareChanged("enable"|"disable"|"regenerate"|"toggle-author")// βββ Auth / OAuth βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ// Login modal shown (reason captured in trigger)analytics.trackLoginModalPresented(trigger)// Sign-in button clicked (OAuth flow started)analytics.trackSignInStarted(provider,uiSource)// Session transition: unauthenticated β authenticatedanalytics.trackSignInCompleted(provider)// βββ Custom βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ// Custom eventanalytics.trackEvent(event)// Configure settingsanalytics.configure({enableLogging,googleAnalyticsId,customEndpoint})
Testing Without GA
Events will still log to console in development even without Google Analytics configured. Set enableLogging: true to see them.
Custom Endpoint Format
Your backend should accept POST requests with this structure: