Connect admin dashboard to Cloudflare analytics
All checks were successful
/ deploy (push) Successful in 46s

This commit is contained in:
Loyyd 2026-07-10 12:18:29 +02:00
parent b8cd4f0789
commit 3c29cc5192
4 changed files with 25 additions and 20 deletions

View file

@ -7,7 +7,9 @@ PUBLIC_CONTACT_RECIPIENTS=directors@familyfed.ie,info@familyfed.ie,media@familyf
# Optional override for the submissions URL configured in src/config/contact.ts.
PUBLIC_CONTACT_SUBMISSIONS_URL=
# Optional Plausible analytics configuration.
# Optional override for the Cloudflare Web Analytics dashboard link in admin.
PUBLIC_ANALYTICS_DASHBOARD_URL=
# Optional Plausible tracking in addition to Cloudflare Web Analytics.
PUBLIC_PLAUSIBLE_DOMAIN=familyfed.ie
PUBLIC_PLAUSIBLE_SCRIPT_SRC=https://plausible.io/js/script.js
PUBLIC_ANALYTICS_DASHBOARD_URL=

View file

@ -44,9 +44,13 @@ workflow passes them into the Astro build.
## Analytics
Set `PUBLIC_PLAUSIBLE_DOMAIN=familyfed.ie` to load Plausible analytics on the
public site. If using a self-hosted Plausible instance, set
`PUBLIC_PLAUSIBLE_SCRIPT_SRC` to the script URL.
Cloudflare Web Analytics is enabled for the proxied `familyfed.ie` zone. It
automatically injects its beacon at the Cloudflare edge, so the Astro build does
not need a tracking token or script.
Set `PUBLIC_ANALYTICS_DASHBOARD_URL` to the analytics dashboard URL so the admin
page can link directly to visitor reports.
The admin dashboard links to Cloudflare Web Analytics by default. Set
`PUBLIC_ANALYTICS_DASHBOARD_URL` only to override that destination.
Plausible remains available as an optional additional provider. Set
`PUBLIC_PLAUSIBLE_DOMAIN=familyfed.ie` to load its tracking script, and set
`PUBLIC_PLAUSIBLE_SCRIPT_SRC` when using a self-hosted Plausible instance.

3
src/config/analytics.ts Normal file
View file

@ -0,0 +1,3 @@
export const analyticsProvider = "Cloudflare Web Analytics";
export const analyticsTrackedDomain = "familyfed.ie";
export const defaultAnalyticsDashboardUrl = "https://dash.cloudflare.com/?to=/:account/web-analytics";

View file

@ -1,6 +1,7 @@
---
import { getArchiveEntries } from "../../lib/archive";
import { speechAdminEntryFromArchiveEntry } from "../../lib/admin-speeches";
import { analyticsProvider, analyticsTrackedDomain, defaultAnalyticsDashboardUrl } from "../../config/analytics";
import { defaultContactFormEndpoint, defaultContactSubmissionsUrl } from "../../config/contact";
import { calendarEvents, recurringCalendarEvents } from "../../data/events";
@ -9,8 +10,7 @@ const blogEntries = entries.filter((entry) => entry.data.type === "blog");
const speechEntries = entries.filter((entry) => entry.data.type === "speech");
const contactFormEndpoint = import.meta.env.PUBLIC_CONTACT_FORM_ENDPOINT || defaultContactFormEndpoint;
const contactSubmissionsUrl = import.meta.env.PUBLIC_CONTACT_SUBMISSIONS_URL || defaultContactSubmissionsUrl;
const analyticsDashboardUrl = import.meta.env.PUBLIC_ANALYTICS_DASHBOARD_URL ?? "";
const plausibleDomain = import.meta.env.PUBLIC_PLAUSIBLE_DOMAIN ?? "";
const analyticsDashboardUrl = import.meta.env.PUBLIC_ANALYTICS_DASHBOARD_URL || defaultAnalyticsDashboardUrl;
const today = new Date().toISOString().slice(0, 10);
const latestEntry = entries[0];
const latestEntryTitle = latestEntry?.data.title ?? latestEntry?.id ?? "No content yet";
@ -21,7 +21,7 @@ const latestEntryDate = latestEntry?.data.published
: "No date";
const totalEvents = calendarEvents.length + recurringCalendarEvents.length;
const contactConfigured = Boolean(contactFormEndpoint);
const analyticsConfigured = Boolean(plausibleDomain);
const analyticsConfigured = true;
const configuredServices = [contactConfigured, analyticsConfigured].filter(Boolean).length;
const speechAdminEntries = speechEntries.map((entry) => speechAdminEntryFromArchiveEntry(entry, today));
const speakerLabels = {
@ -31,9 +31,9 @@ const speakerLabels = {
};
const adminConfig = {
analyticsDashboardUrl,
analyticsProvider,
contactEndpointConfigured: contactConfigured,
contactSubmissionsUrl,
plausibleDomain,
};
---
@ -283,7 +283,7 @@ const adminConfig = {
<div class="admin-status-row">
<div class="admin-status-row-copy">
<strong>Analytics</strong>
<small>Website reporting</small>
<small>{analyticsProvider}</small>
</div>
<span class={`admin-status-pill ${analyticsConfigured ? "is-ready" : "is-warning"}`}>
{analyticsConfigured ? "Ready" : "Setup needed"}
@ -651,21 +651,17 @@ const adminConfig = {
</span>
<div class="admin-setting-card-title">
<h3>Analytics</h3>
<p>Plausible reporting for public website visits.</p>
<p>Privacy-first traffic and performance reporting from Cloudflare.</p>
</div>
<span class={`admin-status-pill ${analyticsConfigured ? "is-ready" : "is-warning"}`}>
{analyticsConfigured ? "Connected" : "Not configured"}
</span>
</div>
<div class="admin-setting-detail">
<span>Tracked domain</span>
<strong>{plausibleDomain || <code>PUBLIC_PLAUSIBLE_DOMAIN</code>}</strong>
<span>{analyticsProvider}</span>
<strong>{analyticsTrackedDomain}</strong>
</div>
{analyticsDashboardUrl ? (
<a class="admin-link-button" href={analyticsDashboardUrl} target="_blank" rel="noreferrer">Open analytics dashboard</a>
) : (
<p class="admin-field-help">Add <code>PUBLIC_ANALYTICS_DASHBOARD_URL</code> to link reports here.</p>
)}
<a class="admin-link-button" href={analyticsDashboardUrl} target="_blank" rel="noreferrer">Open analytics dashboard</a>
</article>
<article class="admin-setting-card">