Hyphen User Guides

Analytics Feature Description

Feature description and technical reference for the analytics module, with deep-dives on content-performance and subscription/revenue metrics

Version 1.2|Updated 2026-06-23|QA Team, Customer Success, Product Stakeholders

0. Overview — What This Guide Covers

This is the deep-dive reference for two specific analytics surfaces:

  1. Content Performance Analytics — how individual articles and sections are performing (page views, active users, engagement time, scroll depth).
  2. Subscription & Revenue Metrics — the business-health view (MRR, ARR, churn, growth, revenue by plan and by month).

For the dashboard overview, the full GA4 event catalog, traffic sources, device/browser, institutional usage, social, and export workflows, see the companion Analytics guide. This document focuses on how the two feature areas above are computed end-to-end and what every field means, so you can trust the numbers and debug them when they look wrong.

The single most important rule to internalise: content performance is sourced from Google Analytics 4 (GA4); subscription and revenue metrics are sourced from the platform's own PostgreSQL database (Prisma). They never cross over. GA4 is never used for money; the database is never used for traffic.

Top-level process flow: traffic-derived content performance comes from GA4; money-derived subscription metrics come from the platform database. Both render in the Admin Console Analytics page.

1. What Is the Analytics & Reporting System?

The Analytics & Reporting system tracks, measures, and visualizes how readers interact with the Hyphen publishing platform. It combines two data sources:

  1. Google Analytics 4 (GA4) — Tracks real-time reader behavior on the Reader Portal: page views, scroll depth, article reading time, paywall interactions, device types, geographic data, and traffic sources.

  2. Internal Platform Data (PostgreSQL/Prisma) — Tracks subscription metrics, revenue, reader registrations, institutional usage, content moderation, and social media performance from the platform's own database.

Together, these provide a complete picture across the entire reader lifecycle: from first visit to content consumption to subscription conversion to long-term retention.


How It Works (Behind the Scenes)

The two feature areas this guide covers have two completely separate pipelines. Understanding the difference is the key to trusting and debugging the numbers.

Content Performance pipeline (GA4)

  1. The Reader Portal loads gtag.js (subject to cookie consent). GA4 records page_view events automatically and scroll events via GA4 enhanced measurement (the native percent_scrolled parameter at 90% by default, plus the platform's own article_scroll_depth milestones).
  2. GA4 ingests and aggregates this server-side in the Google Analytics property.
  3. The Admin Console calls GET /api/analytics/content-performance?days=N. That route authenticates to the GA4 Data API — with a service-account JWT when GA4_SERVICE_ACCOUNT_KEY is set, or via Application Default Credentials (ADC) from a VM-attached service account when it is not — and runs three runReport queries:
    • Top articles — dimensions pagePath + pageTitle, metrics averageSessionDuration, screenPageViews, activeUsers, filtered to paths beginning with /articles/, ordered by engagement time (limit 20).
    • Scroll-depth distribution — dimension percentScrolled, metric eventCount, filtered to eventName = scroll; counts are bucketed into 25/50/75/100 and converted to percentages of total scroll events.
    • Engagement by section — dimension contentGroup, metrics averageSessionDuration, screenPageViews, activeUsers (limit 15; (not set) rows dropped).
  4. If GA4 is not configured, the route returns { configured: false } with empty arrays — the page renders an empty state rather than erroring.

Subscription & Revenue pipeline (Prisma)

  1. Real subscription lifecycle events (create, renew, cancel) and successful Payment rows accumulate in PostgreSQL as readers transact.
  2. The Admin Console calls GET /api/analytics/subscription-metrics, which queries Prisma directly and derives MRR, ARR, churn, growth, revenue-by-month (12 buckets) and revenue-by-plan in real time.
  3. In parallel, an hourly cron (POST /api/cron/snapshot-analytics) computes the current-period subscription/revenue figures and upserts one row per calendar day into daily_analytics_snapshots. This snapshot table backs fast dashboard loads and powers trend/alerting without re-running heavy aggregates on every request.
End-to-end data flow. Content performance is a live GA4 Data API read; subscription metrics are a live Prisma read backed by an hourly snapshot table for fast loads and alerting.

Naming caution — doc_activity_events is NOT a content-analytics table. Despite the name, the doc_activity_events model records Google Drive document editing activity (edits, comments, suggestions on Drive docs) for the Editorial Workflow — see Editorial. It does not feed content-performance views. Article-level performance comes from GA4; per-reader reading progress comes from ReadingHistory; article ratings come from article_ratings.


Concepts: Content Performance & Subscription Metrics

Source-of-truth matrix (the two areas in this guide)

Metric classSource of truthEndpointNever sourced from
Top articles, engagement time, active usersGA4 Data API/api/analytics/content-performanceDatabase view counts
Scroll-depth distributionGA4 (scroll / percentScrolled)/api/analytics/content-performanceDatabase
Engagement by sectionGA4 (contentGroup)/api/analytics/content-performanceDatabase
Per-reader reading progressPrisma ReadingHistory/api/account/history/[articleId]GA4
Article ratings (1–5)Prisma article_ratingsreader rating endpointsGA4
MRR / ARR / revenuePrisma Payment/api/analytics/subscription-metricsGA4 (financial data never from GA4)
Churn / growth / active subsPrisma Subscription/api/analytics/subscription-metricsGA4
Daily aggregated business KPIsPrisma daily_analytics_snapshotssnapshot cronGA4

How content-performance metrics are derived

Each row in the Top Content table is one GA4 page path under /articles/. There is no separate "reads" or "completion" column computed server-side here — completion is inferred from the scroll-depth distribution (% of scroll events that reached 100%). "Dwell" is GA4's averageSessionDuration surfaced as Avg. Engagement Time.

Event-to-metric mapping for content performance. All four metrics come from GA4 dimensions/metrics; completion is derived from the 100% scroll bucket, not stored separately.

How subscription metrics are derived

The subscription-metrics route computes everything from Prisma in one request:

  • MRR = sum of Payment.amount where status = SUCCEEDED and createdAt >= start of current month. (The hourly snapshot cron uses a more stable plan-price-based MRR — summing active subscriptions' plan prices — so the snapshot doesn't swing with payment timing.)
  • ARR = MRR × 12.
  • Churn rate = subscriptions CANCELED this month ÷ subscriptions ACTIVE at the start of the month, as a percentage.
  • Growth = (new subs this month − new subs last month) ÷ new subs last month × 100 (or 100% if there were none last month).
  • Revenue by month = 12 monthly buckets, each the sum of SUCCEEDED Payment.amount in that calendar month.
  • Revenue by plan = successful payments in the trailing 12 months grouped by the subscription's plan, with per-plan revenue and subscriber count.
  • Total active = count of Subscription where status = ACTIVE.
Subscription state drives the financial metrics: ACTIVE subscriptions and their SUCCEEDED payments build MRR/ARR; CANCELED-this-month builds churn.

Configuration Reference

There is very little to configure on these surfaces — most controls are read-only views over upstream data. The table below lists every metric and control, what it means, whether it is a UI control or backend-derived value, and the role required.

Content-performance metrics & controls

Metric / OptionWhat it means / doesTypeMandatory?DefaultWhere (UI path)Role
Page ViewsGA4 screenPageViews for the article pathBackend (GA4)n/aAnalytics > Top Contentanalytics:read
Active UsersGA4 activeUsers (unique readers)Backend (GA4)n/aAnalytics > Top Contentanalytics:read
Avg. Engagement TimeGA4 averageSessionDurationBackend (GA4)n/aAnalytics > Top Contentanalytics:read
Scroll Depth (25/50/75/100%)% of scroll events reaching each bucketBackend (GA4)n/aAnalytics > Content Engagementanalytics:read
Engagement by SectionAvg engagement time per contentGroupBackend (GA4)n/aAnalyticsanalytics:read
Date RangeLookback window for all GA4 queriesUI controlNo30dAnalytics > date pickeranalytics:read
RefreshRe-runs all queriesUI controlNoAnalytics > Refreshanalytics:read

Subscription & revenue metrics

Metric / OptionWhat it means / doesTypeMandatory?DefaultWhere (UI path)Role
MRRSum of SUCCEEDED payments this monthBackend (Prisma)n/aAnalytics > Subscription Metricsanalytics:read
ARRMRR × 12Derivedn/aAnalytics > Subscription Metricsanalytics:read
Churn RateCanceled this month ÷ active at month startDerivedn/aAnalytics > Subscription Metricsanalytics:read
Growth RateMoM change in new subscriptionsDerivedn/aAnalytics > Subscription Metricsanalytics:read
Total ActiveCount of ACTIVE subscriptionsBackend (Prisma)n/aAnalytics > Subscription Metricsanalytics:read
Revenue by Month12-month revenue seriesBackend (Prisma)n/aAnalytics > Revenue Trendanalytics:read
Revenue by PlanPer-plan revenue + subscriber count (trailing 12mo)Backend (Prisma)n/aAnalytics > By Plananalytics:read

Export & access controls

Metric / OptionWhat it means / doesTypeMandatory?DefaultWhere (UI path)Role
CSV ExportDownloads traffic/subscription/revenue/content dataUI actionNoAnalytics > ExportANALYTICS_EXPORT
Page accessView the Analytics page at allGateYesSidebar > Analyticsanalytics:read
GA4 configurationGA4_PROPERTY_ID enables content-performance. Auth is either a GA4_SERVICE_ACCOUNT_KEY (JSON) or, when that env var is absent, Application Default Credentials (ADC) from a VM-attached service accountEnv/backendProperty ID required for GA4 data; key optionalunset → empty stateEnvironment / settingsn/a (ops)
Content performance metrics
Content Performance: top articles by engagement time with page views, active users, and scroll-depth distribution — all sourced live from the GA4 Data API.
Subscription metrics
Subscription & Revenue Metrics: MRR, ARR, churn, growth, revenue by plan and by month — all derived from the platform database (Payment + Subscription).

Dependencies & Impact

These two feature areas sit at a crossroads of several modules. Changes upstream ripple into the numbers shown here.

  • Analytics — the dashboard overview, full GA4 event catalog, traffic sources, device/browser, institutional usage, and export workflows. This guide is the deep-dive companion; the overview is the canonical reference for everything not covered here.
  • Editorial — owns doc_activity_events (Drive editing activity) and contentGroup / section tagging that feeds engagement by section. Mis-tagged sections show up as Uncategorised.
  • Subscriptions — the source of every financial number. Subscription status transitions and Payment rows directly drive MRR, ARR, churn, and growth. Plan price/config changes shift the snapshot's plan-price-based MRR.
  • Reader ManagementReadingHistory (per-reader progress) and article_ratings live here; they complement (but do not feed) GA4 content performance.
  • Marketing — campaigns and conversion surfaces add UTM-tagged traffic that appears in GA4 acquisition reports and influences the funnels referenced from the overview guide.

Impact notes:

  • Cookie-consent declines suppress GA4 events, so content-performance numbers under-count real traffic. Subscription metrics are unaffected (authenticated DB writes).
  • If the GA4 service account (key-based or ADC) loses access, content-performance silently returns the empty state — subscription metrics keep working.
  • The hourly snapshot cron must run for trend/alerting accuracy; a stalled cron leaves daily_analytics_snapshots stale even though the live subscription-metrics endpoint stays correct.

2. Business Objectives & KPIs

Primary KPIs Tracked

KPI CategoryMetricsData SourceUpdate Frequency
TrafficPage Views, Unique Visitors, Sessions, Avg. Session Duration, Bounce RateGA4Near real-time
Content EngagementScroll Depth (25/50/75/100%), Read Completion Rate, Avg. Time on Article, Top ArticlesGA4Near real-time
Subscription HealthTotal Subscribers, New Subscribers, Churn Rate, MRR, ARR, ARPU, LTVPrisma DBReal-time
RevenueMonthly Recurring Revenue, Annual Recurring Revenue, Revenue by Plan, Growth RatePrisma DB (Payment table)Real-time
ConversionPaywall View Rate, Paywall Click-Through Rate, Subscribe Start Rate, Subscribe Completion RateGA4 (custom events)Near real-time
RegistrationVisitor-to-Registration Rate, Email Verification Rate, Registration-to-Subscription RateGA4 + PrismaMixed
AudienceDesktop/Mobile/Tablet Split, Browser Distribution, Top Countries, Traffic Sources (Organic/Direct/Social/Referral/Email/Paid)GA4Near real-time
InstitutionalSeat Utilization Rate, Active Users per Institution, Content Access PatternsPrisma DBReal-time
Social MediaImpressions, Reach, Engagement Rate, Follower Growth, Best Posting TimesPlatform APIs (Meta, X)Periodic sync
E-CommerceProduct Views, Add-to-Cart Rate, Checkout Start RateGA4 (custom events)Near real-time
NewsletterNewsletter Views, Scroll Depth, Read Completion, Share RateGA4 (custom events)Near real-time

Business Questions the System Answers

QuestionWhere to Find the Answer
"How many people are reading our content?"Analytics Overview > Key Metrics Cards (Page Views, Unique Visitors)
"Which articles are most popular?"Analytics Overview > Top Content section
"How are subscriptions growing?"Analytics Overview > Subscription Metrics (MRR, New Subscribers, Churn)
"Where is our traffic coming from?"Analytics Overview > Traffic Sources (Organic, Direct, Social, etc.)
"How well is the paywall converting?"Analytics Overview > Paywall Funnel (view -> click -> start -> complete)
"What devices do our readers use?"Analytics Overview > Device Breakdown (Desktop/Mobile/Tablet)
"Are institutional subscribers using their access?"Analytics > Institutional Usage Reports
"How are our social posts performing?"Social > Analytics (Impressions, Engagement, Best Times)
"How deep are readers reading articles?"Analytics Overview > Scroll Depth (25/50/75/100% distribution)
"Which marketing channels drive the most conversions?"GA4 > Acquisition > UTM attribution from conversion surfaces

3. System Architecture — Where Data Comes From

Reader Portal (Next.js)                      Admin Console (Next.js)
+---------------------------+                +---------------------------+
|                           |                |                           |
|  GoogleAnalytics.tsx      |   GA4 Data     |  Analytics Page           |
|  (gtag.js script)   -----+---API---------->  /api/analytics/*         |
|                           |                |  (ga4-data-client.ts)     |
|  analytics.ts             |                |                           |
|  (custom events)          |   Custom       |  Dashboard Page            |
|  - paywall_view           |   Events       |  /api/stats/dashboard     |
|  - article_scroll_depth   |                |                           |
|  - subscribe_start        |                |  /api/analytics/          |
|  - shop_add_to_cart       |                |   - traffic-sources       |
|  - conversion_surface_*   |                |   - content-performance   |
|  - newsletter_*           |                |   - subscription-metrics  |
|  etc.                     |                |   - paywall-funnel        |
|                           |                |   - registration-funnel   |
|  CookieConsent.tsx        |                |   - device-browser        |
|  (consent gating)         |   Prisma       |   - institutional-usage   |
|                           |   DB Data      |   - author-stats          |
|  ReadingTracker.tsx       +---API---------->   - export                |
|  (progress to backend)    |                |                           |
|                           |                |  /api/stats/subscribers   |
+---------------------------+                +---------------------------+
         |                                              |
         v                                              v
   Google Analytics 4                          PostgreSQL Database
   (GA4 Property)                              (Prisma Models)
   - pageview events                           - Subscription
   - custom events                             - Payment
   - real-time data                            - Reader
   - audience data                             - ReadingHistory
   - acquisition data                          - Institution
                                               - InstitutionUser
                                               - Comment
                                               - ArticleRating
                                               - ConversionEvent

Data Source Mapping

Data PointSourceHow It Gets There
Page viewsGA4Automatic — gtag.js fires page_view on every navigation
Unique visitorsGA4Automatic — GA4 deduplicates by client ID
Article scroll depthGA4Custom event — observeScrollDepth() in article templates fires at 25/50/75/100%
Article read completeGA4Custom event — fires when reader scrolls to 100%
Paywall viewsGA4Custom event — trackPaywallView() fires when PaywallOverlay renders
Subscribe button clicksGA4Custom event — trackPaywallClickSubscribe() fires on paywall CTA click
Subscription startGA4Custom event — trackSubscribeStart() fires when reader begins checkout
Subscription completeGA4Custom event — trackSubscribeComplete() fires after payment verification
Product viewsGA4Custom event — trackProductView() fires on shop product page
Add to cartGA4Custom event — trackAddToCart() fires on "Add to Cart" button click
Newsletter scroll depthGA4Custom event — observeNewsletterScrollDepth() fires at 25/50/75/100%
Conversion surface interactionsGA4 + InternalDual tracked — GA4 events + ConversionEvent table
MRR / ARR / RevenuePrisma DBCalculated from Payment + Subscription tables
Subscriber countsPrisma DBCOUNT queries on Subscription table
Churn ratePrisma DBCancelled subscriptions / total subscriptions
Institutional usagePrisma DBInstitutionUser activity data
Reading historyPrisma DBReadingTracker component POSTs progress data to admin API
Traffic sourcesGA4 Data APIServer-side query via ga4-data-client.ts
Device breakdownGA4 Data APIServer-side query for deviceCategory dimension

4. GA4 Event Catalog — Every Event the Platform Fires

4.1 Automatic Events (fired by gtag.js)

EventWhen FiredParameters
page_viewEvery page navigationpage_path, page_title

4.2 Article Engagement Events

EventWhen FiredParametersTrigger LocationStatus
article_viewReader opens an article pagearticle_slug, article_section, content_typeAnalyticsPageView on article/[slug]/page.tsxWired
article_scroll_depthReader scrolls past 25%, 50%, 75%, or 100% of articlearticle_slug, article_section, scroll_depth (25/50/75/100)observeScrollDepth() in article templatesWired
article_read_completeReader scrolls to 100% of articlearticle_slug, read_time_secondsobserveScrollDepth() at 100% milestoneWired

4.3 Paywall Events

EventWhen FiredParametersTrigger LocationStatus
paywall_viewPaywall renders on screen in the article viewarticle_slug, article_sectionArticleContent (fires when the paywall renders)Wired
paywall_click_subscribeReader clicks "Subscribe" on a paywallarticle_slugArticleContent paywall CTA onClickWired

4.4 Subscription Events

EventWhen FiredParametersTrigger LocationStatus
subscribe_startReader begins subscription checkoutplan_name, plan_priceCheckout page on mountPending wiring
subscribe_completePayment verified and subscription activatedplan_name, payment_methodAfter payment verification successPending wiring

4.5 E-Commerce / Shop Events

EventWhen FiredParametersTrigger LocationStatus
shop_product_viewReader opens a product detail pageproduct_handle, product_name, priceShopProductDetail on mountWired
shop_add_to_cartReader clicks "Add to Cart"product_handle, product_name, price, quantityShopProductDetail and ShopProductGrid add-to-cart handlersWired
shop_checkout_startReader clicks "Checkout" in cartcart_value, item_countShop checkout page on mountWired

4.6 Conversion Surface Events

EventWhen FiredParametersTrigger Location
conversion_surface_impressionConversion surface is displayed to readersurface_id, surface_name, surface_type, conversion_goal, page_urlConversionSurfaceRenderer on trigger
conversion_surface_clickReader clicks surface CTAsurface_id, surface_name, surface_type, conversion_goal, cta_typeConversionSurfaceProvider trackClick
conversion_surface_dismissReader dismisses surfacesurface_id, surface_name, surface_type, conversion_goalConversionSurfaceProvider dismissSurface
conversion_surface_conversionReader completes desired actionsurface_id, surface_name, conversion_goal, conversion_typeConversionSurfaceProvider trackConversion
coupon_copiedReader copies a coupon codesurface_id, coupon_code, discount_percent, discount_amountSurface component copy handler

4.7 Newsletter Events

EventWhen FiredParametersTrigger Location
newsletter_viewReader opens a newsletter edition pagenewsletter_slug, edition_number, topicNewsletter edition page
newsletter_scroll_depthReader scrolls newsletter at 25/50/75/100%newsletter_slug, scroll_depthobserveNewsletterScrollDepth()
newsletter_read_completeReader reaches 100% of newsletternewsletter_slug, read_time_secondsAt 100% milestone
newsletter_shareReader shares a newsletternewsletter_slug, platformSocialShare on newsletter page
newsletter_list_viewReader views newsletter archive listtopicNewsletter listing page
newsletter_signupReader subscribes to newslettersource, surface_idNewsletter form submit

4.8 Registration Events

EventWhen FiredParametersTrigger LocationStatus
registration_startReader begins registration flowsource, surface_idRegister page (fires with source: register_page)Wired

Event Flow Summary

Reader Journey:
  Visit site -----> page_view (automatic)
  Browse article -> article_view
  Scroll reading -> article_scroll_depth (25%, 50%, 75%)
  Finish article -> article_scroll_depth (100%) + article_read_complete
  Hit paywall ----> paywall_view
  Click Subscribe > paywall_click_subscribe
  Start checkout -> subscribe_start
  Complete payment> subscribe_complete

  Browse shop ----> shop_product_view
  Add to cart ----> shop_add_to_cart
  Checkout -------> shop_checkout_start

  See promo modal > conversion_surface_impression
  Click CTA ------> conversion_surface_click
  Copy coupon ----> coupon_copied
  Complete action > conversion_surface_conversion

5. Admin Dashboard — Quick Daily Snapshot

Admin dashboard
The admin dashboard provides a quick daily snapshot of key platform metrics.

Location

Admin Console > Dashboard (landing page after login)

What It Shows

4 Primary Stat Cards:

CardSourceDescription
Total ArticlesPrisma DBAll articles across all statuses
SubscribersPrisma DBActive subscriber count + "+X this month"
Total ViewsPrisma DB / GA4Total article view count
EngagementPrisma DBComments + shares combined

6 Status Cards:

CardSourceClickable?
Pending ReviewPrisma DB (Article.status = pending_review)Yes -- opens filtered content page
DraftsPrisma DB (Article.status = draft)Yes -- opens filtered content page
Published (7d)Prisma DBNo
Comments QueuePrisma DB (Comment.status = pending)Yes -- opens moderation page
FlaggedPrisma DB (Comment.status = flagged)Yes -- opens moderation page
New ReportsPrisma DB (ContentReport.status = open)Yes -- opens moderation page

3-Column Section:

  • Most Popular articles (by view count)
  • Under Review articles (pending editorial review)
  • Quick Actions (New Article, Moderation, Analytics)

Social Overview Widget:

  • Scheduled Today / This Week / Failed post counts
  • Quick links to Compose Post and Social Analytics

Recently Published:

  • Last 6 published articles with views, comments, shares

6. Analytics Overview Page — Deep Metrics

Analytics overview
The analytics overview page with detailed traffic, subscription, content, and geographic metrics.

Location

Admin Console > Analytics

Controls

  • Date Range Picker: 7d, 30d (default), 90d, 12m, Custom
  • Refresh Button: Reloads all data
  • Export Button: Downloads CSV report (requires ANALYTICS_EXPORT permission)

Section Layout

SectionPositionData SourceDescription
Key Metrics CardsTop rowGA4Page Views, Unique Visitors, Sessions, Avg. Session Duration -- each with % change vs previous period
Traffic ChartLeft 2/3GA4Time-series line chart with toggleable lines (Page Views, Unique Visitors, Sessions)
Traffic SourcesRight 1/3GA4Channel breakdown bars (Organic, Direct, Social, Referral, Email, Paid)
Subscription MetricsLeft halfPrismaTotal Subscribers, New Subscribers, Churn Rate, MRR, plan breakdown, subscriber trend sparkline, Conversion Rate, ARPU, LTV
Top ContentRight halfGA4Table: Rank, Title, Page Views, Time on Page, Shares, Comments
Paywall Conversion FunnelLeft halfGA44-stage funnel: Paywall Viewed -> Clicked Subscribe -> Subscription Started -> Subscription Completed
Scroll Depth DistributionRight halfGA4Estimated distribution at 25%, 50%, 75%, 100% thresholds
Device BreakdownLeft 1/3GA4Desktop / Mobile / Tablet percentages
Top CountriesRight 1/3GA4Top 5 countries with flag icons and percentage
GA4 Link BannerBottom--"Need more detailed analytics?" link to Google Analytics

7. Paywall Conversion Funnel

What It Tracks

The paywall funnel measures the step-by-step conversion journey from seeing a paywall to completing a paid subscription.

StageGA4 EventDescriptionExample Count
Paywall Viewedpaywall_viewReader saw a paywall overlay or gate10,000
Clicked Subscribepaywall_click_subscribeReader clicked the "Subscribe" CTA on a paywall2,500 (25% of stage 1)
Subscription Startedsubscribe_startReader began the checkout process1,200 (12% of stage 1)
Subscription Completedsubscribe_completeReader completed payment and subscription activated450 (4.5% of stage 1)

How to Read the Funnel

  • The conversion rate shown at each stage is relative to the top of the funnel (stage 1)
  • A healthy paywall funnel converts 2-5% of paywall views to completed subscriptions
  • Large drop-offs between stages indicate friction points:
    • Big drop between "Viewed" and "Clicked Subscribe" = paywall messaging isn't compelling
    • Big drop between "Started" and "Completed" = checkout friction (price, payment method, UX)

Data Source

GA4 Data API -- server-side query aggregating custom event counts over the selected date range.


8. Registration Funnel

What It Tracks

The registration funnel measures how effectively the platform converts anonymous visitors to active subscribers.

StageData SourceDescription
Total VisitorsGA4Unique visitors in the period
RegisteredPrisma DBReaders who created an account
VerifiedPrisma DBReaders who verified their email
Active SubscribersPrisma DBReaders with active paid subscriptions

API Endpoint

GET /api/analytics/registration-funnel?days=30


9. Subscription & Revenue Metrics

Analytics overview
Subscription and revenue metrics are available on the Analytics Overview page. Scroll down to see active subscribers, MRR, churn rate, and conversion funnel data.

Metrics Displayed

MetricDefinitionSource
Total SubscribersActive + recently cancelled subscribersPrisma: Subscription table
Active SubscribersCurrently paying subscribersPrisma: Subscription.status = ACTIVE
New SubscribersSubscriptions created in the current monthPrisma: Subscription.createdAt within month
Cancelled SubscribersSubscriptions cancelled in the periodPrisma: Subscription.status = CANCELED
Churn Rate(Cancelled / Total) as percentageCalculated
MRR (Monthly Recurring Revenue)Sum of monthly subscription paymentsPrisma: Payment table aggregation
ARR (Annual Recurring Revenue)MRR x 12Calculated
ARPU (Avg Revenue Per User)MRR / Active SubscribersCalculated
LTV (Lifetime Value)ARPU / Monthly Churn RateCalculated (estimated)
Conversion RateTrial-to-paid conversion percentagePrisma: Subscription.status transitions

Revenue by Plan Breakdown

Shows subscriber distribution and revenue contribution per plan (e.g., "Digital Only: 45%, Print+Digital: 30%, Annual: 25%").

Revenue Trend

Monthly time-series chart of revenue, showing growth trajectory.

API Endpoint

GET /api/analytics/subscription-metrics


10. Content Performance Analytics

Analytics overview
Content performance metrics are part of the Analytics Overview. Per-article data includes pageviews, read time, engagement rate, and social shares.

Metrics Per Article

MetricSourceDescription
Page ViewsGA4Total times the article was loaded
Active UsersGA4Unique readers who viewed the article
Avg. Engagement TimeGA4Average time spent reading
Scroll DepthGA4Distribution at 25/50/75/100% thresholds

Top Content Table

Ranked list showing the highest-performing articles by page views, with time-on-page, shares, and comments.

Author Statistics

GET /api/analytics/author-stats — Per-author metrics for editorial performance review.

API Endpoint

GET /api/analytics/content-performance


11. Traffic Source Analysis

Channels Tracked

ChannelHow It's IdentifiedExample
Organic SearchVisitors from search engines (Google, Bing)google / organic
DirectVisitors who typed URL or used bookmark(direct) / (none)
SocialVisitors from social media linksfacebook / social, twitter / social
ReferralVisitors from other websites linking to youblog.example.com / referral
EmailVisitors from email links (UTM tagged)newsletter / email
PaidVisitors from paid advertisinggoogle / cpc, facebook / paid

UTM Attribution from Conversion Surfaces

When readers click a conversion surface CTA, the URL is automatically tagged with:

  • utm_source=conversion_surface
  • utm_medium=promo
  • utm_campaign=cs_{goal}_{surfaceId}

This appears in GA4 traffic source reports, allowing you to measure the direct impact of conversion surfaces on subscriptions.

API Endpoint

GET /api/analytics/traffic-sources


12. Device & Browser Analytics

Device Categories

  • Desktop (screen > 1024px)
  • Mobile (screen < 768px)
  • Tablet (768-1024px)

Browser Distribution

Top browsers by usage (Chrome, Safari, Firefox, Edge, etc.)

Operating Systems

Distribution across Windows, macOS, iOS, Android, Linux.

API Endpoint

GET /api/analytics/device-browser


13. Institutional Usage Reporting

What It Tracks

For each institution with an active subscription:

MetricDescription
Seats Used / TotalHow many assigned seats are actively logging in
Utilization Rate(Active users / Total seats) as percentage
Active UsersUsers who logged in during the period
Content AccessedNumber of articles/issues accessed

Use Case

Sales and customer success teams use this data to:

  • Identify underutilized institutional accounts for engagement outreach
  • Prepare usage reports for institutional renewal conversations
  • Upsell additional seats to institutions with high utilization

API Endpoint

GET /api/analytics/institutional-usage


14. Social Media Analytics

Location

Admin Console > Social > Analytics

Tabs

  1. Performance -- Impressions, Reach, Engagements, Engagement Rate, Posts Published, Likes, Comments, Clicks
  2. Content -- Per-post performance breakdown
  3. Growth -- Follower growth trends
  4. Best Times -- Optimal posting time recommendations based on engagement data
  5. Executive -- Summary view for leadership (requires SOCIAL_EXECUTIVE_READ permission)

Metrics

MetricDescription
Total ImpressionsTimes posts were displayed
Total ReachUnique people who saw posts
Total EngagementsLikes + comments + shares + clicks
Avg. Engagement RateEngagements / Impressions
Posts PublishedNumber of posts in the period
Follower GrowthNet new followers

15. Data Export & Reporting

Export Formats

  • CSV -- Comma-separated values for spreadsheet analysis
  • JSON -- Machine-readable format for programmatic use

Available Exports

ExportContents
TrafficPage views, visitors, sessions by date
SubscriptionsSubscriber counts, MRR, churn by month
RevenueRevenue by month and by plan
ContentTop articles with page views, engagement time

How to Export

  1. Navigate to Analytics page
  2. Set the desired date range
  3. Click the Export button (top-right)
  4. CSV file downloads automatically

Permission Required

ANALYTICS_EXPORT permission

API Endpoint

GET /api/analytics/export?type=subscriptions&format=csv&days=30


How It Works

  1. GoogleAnalytics component loads with analytics_storage: denied by default
  2. CookieConsent component shows a banner asking the reader to accept cookies
  3. If reader accepts, consent is stored in localStorage as hyphen_cookie_consent: accepted
  4. On subsequent visits, analytics_storage is set to granted based on stored consent
  5. If reader does not accept, GA4 events are still queued but not sent to Google

Impact on Analytics

  • Readers who decline cookies will NOT generate GA4 data
  • This means page views, scroll depth, and all custom events from those readers are invisible
  • Internal platform data (subscriptions, reading history, bookmarks) is NOT affected by cookie consent -- it's recorded via authenticated API calls

Privacy Compliance

  • Cookie consent follows GDPR principles
  • No tracking cookies set before consent
  • Consent status persisted only in localStorage (not server-side)

17. Scroll Depth & Reading Engagement Tracking

How Scroll Tracking Works

The observeScrollDepth() function in the Reader Portal:

  1. Attaches a passive scroll event listener when an article page mounts
  2. Calculates scroll percentage: (window.scrollY / (scrollHeight - windowHeight)) * 100
  3. Fires article_scroll_depth at each milestone (25%, 50%, 75%, 100%)
  4. Each milestone fires exactly once per page load
  5. At 100%, also fires article_read_complete with total read time in seconds

What the Admin Sees

In the Analytics Overview page, the Scroll Depth Distribution section shows estimated percentages:

  • % of readers who scrolled to 25%
  • % of readers who scrolled to 50%
  • % of readers who scrolled to 75%
  • % of readers who scrolled to 100% (completed reading)

Reading Progress (Internal Tracking)

Separately from GA4, the ReadingTracker component:

  • POSTs reading progress to /api/account/history/[articleId] at milestones (0/25/50/75/100%)
  • Tracks progress, scrollPosition, timeSpentSec
  • Records startedAt, lastReadAt, completedAt in the ReadingHistory table
  • This powers the reader's Reading History page and the Implicit Preference Learning system

18. Conversion Surface Analytics

See the dedicated Conversion Surfaces Feature Description for full details.

Summary of analytics integration:

  • 5 GA4 events: impression, click, dismiss, conversion, coupon_copied
  • Internal ConversionEvent table: every interaction recorded with reader context
  • Denormalized counters on each surface: impressionCount, clickCount, dismissCount, conversionCount
  • Admin stats dashboard: totals, rates, time-series, device breakdown, top pages, UTM source breakdown
  • UTM attribution: all CTA URLs auto-tagged for GA4 campaign tracking

19. User Stories

For Editors

IDAs a...I want to...So that...
US-01EditorSee which articles are most read this weekI can commission similar content
US-02EditorKnow what percentage of readers finish articlesI can assess if article length is appropriate
US-03EditorSee which sections have the most trafficI can allocate editorial resources accordingly

For Product Managers

IDAs a...I want to...So that...
US-04Product ManagerTrack the paywall conversion funnel end-to-endI can identify and fix friction points
US-05Product ManagerMonitor MRR and subscriber growth monthlyI can report business health to stakeholders
US-06Product ManagerSee the registration-to-subscription conversion rateI can measure the effectiveness of the onboarding flow
US-07Product ManagerCompare traffic between date rangesI can measure the impact of marketing campaigns

For Marketing

IDAs a...I want to...So that...
US-08Marketing ManagerSee which traffic sources drive the most subscribersI can allocate budget to the best channels
US-09Marketing ManagerTrack conversion surface performance (impressions, clicks, conversions)I can optimize promotional overlays
US-10Marketing ManagerKnow what percentage of traffic comes from social mediaI can justify social media investment
US-11Marketing ManagerExport analytics data as CSVI can create custom reports for stakeholders

For Sales / Customer Success

IDAs a...I want to...So that...
US-12Sales ManagerSee institutional subscription utilization ratesI can identify accounts at risk of churn
US-13Customer SuccessGenerate usage reports per institutionI can share data during renewal conversations

For QA

IDAs a...I want to...So that...
US-14QA EngineerVerify GA4 events fire correctly on the Reader PortalI can confirm the analytics pipeline is working
US-15QA EngineerConfirm the Admin Console displays real data when GA4 is configuredI can validate the full data flow
US-16QA EngineerVerify that declining cookie consent suppresses GA4 trackingI can confirm privacy compliance

20. Use Cases & Scenarios

Scenario 1: Monitoring a New Issue Launch

Context: New magazine issue published this week. Editor wants to measure reader response.

Steps:

  1. Open Dashboard -- check "Published (7d)" card for the new issue's articles
  2. Open Analytics -- set date range to "7d"
  3. Check Key Metrics -- expect a spike in Page Views and Unique Visitors
  4. Check Top Content -- new issue's articles should appear in the top 10
  5. Check Scroll Depth -- look for high completion rates (75-100%) indicating engaged readers
  6. Check Paywall Funnel -- if issue articles are premium, expect funnel activity

Scenario 2: Evaluating a Marketing Campaign

Context: Marketing ran a Facebook campaign to drive subscriptions.

Steps:

  1. Open Analytics -- set date range to cover the campaign period
  2. Check Traffic Sources -- "Social" percentage should be higher than baseline
  3. Open GA4 directly -- filter by utm_source=facebook to see campaign-specific metrics
  4. Check Subscription Metrics -- look for a spike in "New Subscribers"
  5. If conversion surfaces were used, check their stats for UTM attribution (utm_campaign=cs_subscribe_paid_*)

Scenario 3: Institutional Renewal Preparation

Context: Sales team preparing for an institutional subscription renewal meeting.

Steps:

  1. Open Analytics > Institutional Usage
  2. Find the institution by name
  3. Note: seats used vs total, utilization rate, most active users
  4. Export the data as CSV for the renewal proposal
  5. If utilization is low, recommend engagement strategies; if high, propose additional seats

Scenario 4: Diagnosing a Conversion Drop

Context: MRR has dropped this month. Need to diagnose why.

Steps:

  1. Open Analytics -- compare 30d vs previous 30d
  2. Check Subscription Metrics -- is churn rate up, or are new subscribers down?
  3. Check Paywall Funnel -- are fewer people seeing paywalls (traffic drop)? Or is the funnel leaking?
  4. Check Traffic Sources -- has any channel dropped significantly?
  5. Check Top Content -- is popular content shifting away from premium articles?
  6. Check Device Breakdown -- is a mobile issue causing bounce rate increases?

Known Limitations

LimitationDescriptionImpact
GA4 data delayGA4 Data API can have 24-48 hour lag for some metricsRecent data may not reflect the very latest activity
No real-time traffic dashboardReal-time monitoring shows placeholder dataUse GA4 real-time view directly for live monitoring
Cookie consent reduces dataReaders who decline cookies are invisible to GA4Traffic numbers may undercount actual visitors
Traffic trend chart not fully wiredfetchTrafficTrend() returns an empty arrayTime-series chart may show flat or no data
Geo data not fully wiredfetchGeoData() returns an empty arrayTop Countries may show limited data
PDF export is placeholdergeneratePDFReport() returns placeholder dataOnly CSV export is functional
No A/B test analyticsNo built-in A/B testing frameworkUse GA4's built-in experiments for A/B testing
Scroll depth is page-levelScroll tracking measures page scroll, not article content scrollFor very long pages with headers/footers, 100% may not mean "finished article"
Social analytics depends on API connectionsSocial data only appears when Meta/X APIs are connectedMust configure social integrations first
Subscription checkout events not yet wiredsubscribe_start and subscribe_complete are not yet called from the checkout and payment-verification flowsThe bottom two stages of the Paywall Conversion Funnel report zero until these events are wired

FAQ

On this page

0. Overview — What This Guide Covers1. What Is the Analytics & Reporting System?How It Works (Behind the Scenes)Content Performance pipeline (GA4)Subscription & Revenue pipeline (Prisma)Concepts: Content Performance & Subscription MetricsSource-of-truth matrix (the two areas in this guide)How content-performance metrics are derivedHow subscription metrics are derivedConfiguration ReferenceContent-performance metrics & controlsSubscription & revenue metricsExport & access controlsDependencies & Impact2. Business Objectives & KPIsPrimary KPIs TrackedBusiness Questions the System Answers3. System Architecture — Where Data Comes FromData Source Mapping4. GA4 Event Catalog — Every Event the Platform Fires4.1 Automatic Events (fired by gtag.js)4.2 Article Engagement Events4.3 Paywall Events4.4 Subscription Events4.5 E-Commerce / Shop Events4.6 Conversion Surface Events4.7 Newsletter Events4.8 Registration EventsEvent Flow Summary5. Admin Dashboard — Quick Daily SnapshotLocationWhat It Shows6. Analytics Overview Page — Deep MetricsLocationControlsSection Layout7. Paywall Conversion FunnelWhat It TracksHow to Read the FunnelData Source8. Registration FunnelWhat It TracksAPI Endpoint9. Subscription & Revenue MetricsMetrics DisplayedRevenue by Plan BreakdownRevenue TrendAPI Endpoint10. Content Performance AnalyticsMetrics Per ArticleTop Content TableAuthor StatisticsAPI Endpoint11. Traffic Source AnalysisChannels TrackedUTM Attribution from Conversion SurfacesAPI Endpoint12. Device & Browser AnalyticsDevice CategoriesBrowser DistributionOperating SystemsAPI Endpoint13. Institutional Usage ReportingWhat It TracksUse CaseAPI Endpoint14. Social Media AnalyticsLocationTabsMetrics15. Data Export & ReportingExport FormatsAvailable ExportsHow to ExportPermission RequiredAPI Endpoint16. Cookie Consent & PrivacyHow It WorksImpact on AnalyticsPrivacy Compliance17. Scroll Depth & Reading Engagement TrackingHow Scroll Tracking WorksWhat the Admin SeesReading Progress (Internal Tracking)18. Conversion Surface Analytics19. User StoriesFor EditorsFor Product ManagersFor MarketingFor Sales / Customer SuccessFor QA20. Use Cases & ScenariosScenario 1: Monitoring a New Issue LaunchScenario 2: Evaluating a Marketing CampaignScenario 3: Institutional Renewal PreparationScenario 4: Diagnosing a Conversion DropKnown LimitationsFAQ