Analytics

Arc CMS reports visits to Google Analytics from the browser, and, once you connect your GA4 property, shows the last 28 days of traffic on the admin dashboard.

What it is

Two separate parts, set up in different places:

PartWhat it doesSet up with
TrackingFirebase Analytics (GA4) runs in the browser on the pages the app draws, recording page views and Arc CMS's own events. Published content pages and static pages carry no tracking codeThe measurementId in your Firebase web config
Dashboard analyticsCloud Functions read your GA4 property and the admin dashboard shows the numbersA Google OAuth client, on Admin, Settings, Analytics

Besides page views, tracking records these events:

EventsWhen
content_list_view, content_detail_view, public_page_view, share_clickA content list, a content item or a static page is viewed, or a share button is clicked
waitlist_view, waitlist_signup_submit, waitlist_otp_verify, waitlist_signup_complete, waitlist_existing_user, waitlist_errorSteps of a signup form (see Signup forms)
unsubscribe_viewThe unsubscribe page is viewed

Content events need the Content feature, and signup form events the Signup forms feature. UTM parameters in the address are saved as user properties. After a form sign-up, the visitor is linked to their user id and the form. Nothing from their email address is sent.

The dashboard shows nine numbers for the last 28 days, each compared with the 28 days before: Users, New Users, Sessions, Bounce Rate, Avg. Duration, Pages/Session, Pageviews, Event Count and Engaged Sessions. Beside them are five lists: Top Pages, Traffic Sources, Devices, Top Countries, and AI assistants (sessions sent by AI assistants, which GA4 files under Referral).

The other cards on the dashboard (content, users, sign-ups) are counted from Firestore, not from Google Analytics; see Use the admin area. App install numbers are on Installable app (PWA).

Turn it on or off

Analytics is the feature analytics, on unless you list it in off in src/custom/features.ts (see Choose your app's features). Off, no Google Analytics code loads in the browser at all, and the dashboard's analytics section, Admin, Settings, Analytics (its tile, its link on the dashboard, and the page at both /admin/settings/analytics and /admin/analytics-setting) and the five functions below go.

On, tracking runs whenever your Firebase web config has a measurementId. The dashboard part shows numbers only after you connect a property, and stops when you disconnect it.

Each install chooses whether Google Analytics waits for the visitor's consent, per Firebase project:

npm run arc:configure -- --analytics-consent=required
ValueWho is tracked
alwaysThe default, as Arc CMS always did: every visitor, from the first page. The site usage banner, if on, only records the visitor's choice.
requiredOnly visitors who clicked accept on the site usage banner. Until then no Google Analytics code is even downloaded, and no cookie is set. With the banner off, nobody is tracked, because nobody can accept.

The value is written to arccms.config.json (key analyticsConsent) and src/environments/arc-install.ts; build and deploy the website for it to apply. Admin, Settings, Analytics and the dashboard say in one line which of these is happening, and warn when nobody is tracked because the banner is off, with a link to turn it on.

In required mode, after the visitor accepts, the same events are sent as in always mode: Google's page view, the screen views (named as AngularFire's screen tracking names them), the user id, and the events above. The numbers then cover only those who accepted.

The Firebase Analytics code is a chunk of its own, never part of the code every page loads. It is downloaded when tracking starts: as the site opens in always mode, after the visitor accepts in required mode, and never with the feature off.

Set it up

Tracking

Copy the web app config from the Firebase console, including measurementId, into your environment file (see Configure a project; the shape is in src/environments/environment.example.ts). Nothing else is needed.

Dashboard analytics

  1. In the Google Cloud console for your Firebase project, enable the Google Analytics Data API and the Google Analytics Admin API.

  2. Create an OAuth client ID of type Web application. Add your site's address and http://localhost:5173 under both Authorized JavaScript origins and Authorized redirect URIs, and also add http://localhost under Authorized JavaScript origins. If Google asks for a consent screen first, choose External and fill in the app name and emails.

  3. Open Admin, Settings, Analytics, click Configure Analytics, paste the client ID and secret, and click Save Credentials. The page has these steps as a guide, with the addresses to copy.

  4. Click Connect Google Analytics and allow access in the Google popup, with the account that can see your Analytics property.

  5. Arc CMS lists the Analytics properties the account can see, under Select GA4 Property: pick the one your site reports to and click Connect. The first numbers are fetched straight away.

Use it

Open the admin dashboard. When the numbers are more than 5 minutes old, opening it fetches fresh ones; Refresh fetches them at any time. The header shows when they were last fetched, and View Full Analytics opens your project's Analytics page in the Firebase console.

To connect another property or another account, click Disconnect on Admin, Settings, Analytics, then connect again. Disconnecting revokes Arc CMS's access at Google.

Extend it

Log your own events with AnalyticsService (src/app/core/analytics/analytics.service.ts): log(name, params), setUserProperties() and setUserId(). They send nothing unless this visitor may be tracked on this page right now (the feature, the consent mode and the route), so your events follow the same rules as Arc CMS's. Do not import @angular/fire/analytics or firebase/analytics yourself: that would bypass consent, and a test fails if any file outside src/app/core/analytics does. GaTrackingService (src/shared/services/ga-tracking.service.ts) is core; call its methods, but put new event helpers in your own code in src/custom/.

The dashboard's metrics and lists are fixed in core (functions/src/AnalyticsDashboard/analyticsHelpers.ts). A different set is a feature request for Arc CMS, not a change in an app.

What it stores

WhereHolds
Settings/analyticsThe OAuth client ID and secret, the access and refresh tokens, the chosen property, and whether it is connected
Settings/analytics_statusNo secrets: whether it is connected, the property name and id, the measurement id, and when data was last fetched
AnalyticsDashboards/analyticsDataThe last fetched numbers and lists, the date range and the property id

Nothing is kept in Storage. The Cloud Functions, all callables:

FunctionDoes
connectGoogleAnalyticsExchanges the Google authorization for tokens, finds the property, fetches the first numbers
selectAnalyticsPropertySaves the property you picked
refreshAnalyticsDataFetches fresh numbers
disconnectGoogleAnalyticsRevokes access, clears the connection and deletes the stored numbers
testAnalyticsConnectionA debugging check for a service-account setup; the admin pages do not use it

See Cloud Functions and Data model.

Who can do what

WhoCan
AdminRead and write Settings/analytics and AnalyticsDashboards; connect, pick a property, refresh and disconnect
Signed-in personRead Settings/analytics_status (no secrets)

The client secret is shown masked on the settings page and is only sent to Google by the functions.

Troubleshooting

You seeWhy, and what to do
"No refresh token received"Google remembers an earlier grant. Remove the app's access at https://myaccount.google.com/permissions and connect again.
"OAuth client ID and secret not configured"Save the credentials before you connect.
"Google Analytics access has been revoked. Please reconnect."The grant expired or was removed at Google. Connect again.
The Google popup shows an origin or redirect error, or "Authorization timed out"The address you are on is not in the OAuth client's origins and redirect URIs; add it in the Google Cloud console. For a timeout, allow popups for your site.
Dashboard shows placeholders, no numbersThe stored numbers are for another property. Click Refresh.
"No GA4 property selected."No property was picked when you connected, or the account can see none. On Admin, Settings, Analytics, click Disconnect, connect again, and pick a property.
No page views in Google AnalyticsCheck measurementId in the environment file, and look for Analytics in the browser's network requests. With analyticsConsent required, nothing is sent until you accept the site usage banner.
"Not tracking anyone" on Settings or the dashboardThe install waits for consent and the site usage banner is off. Turn the banner on (Admin, Settings, Site Usage), or set --analytics-consent=always if consent is not needed.
Far fewer visitors than beforeWith required, only visitors who accept are counted. That is expected.