File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -46,12 +46,16 @@ NODE_ENV=development
4646# ANALYTICS (Optional)
4747# ============================================================================
4848
49- # Google Analytics Measurement ID
50- # Get yours at: https://analytics.google.com
51- # VITE_GA_MEASUREMENT_ID=G-XXXXXXXXXX
52-
53- # Plausible Analytics domain
54- # VITE_PLAUSIBLE_DOMAIN=yourdomain.com
49+ # Cloudflare Web Analytics beacon token.
50+ # When set at build time, the build:
51+ # 1. Injects the Cloudflare beacon <script> into index.html
52+ # 2. Adds the two Cloudflare origins to the CSP allowlist
53+ # When unset, the template ships with a tight CSP and no beacon.
54+ #
55+ # How to get one:
56+ # dash.cloudflare.com → Web Analytics → your site → Setup
57+ # → copy the value of `data-cf-beacon`'s "token" field
58+ # VITE_CF_BEACON_TOKEN=your_beacon_token_here
5559
5660# ============================================================================
5761# EXTERNAL INTEGRATIONS (Optional - for future features)
Original file line number Diff line number Diff line change @@ -137,6 +137,10 @@ jobs:
137137 # cache helpers. On normal pushes this stays unset, so each deploy
138138 # reuses fresh JSON from the previous run / the live site.
139139 FORCE_REFRESH : ${{ github.event.inputs.force_refresh == 'true' && '1' || '' }}
140+ # Cloudflare Web Analytics beacon token. Optional — when unset, the
141+ # build no-ops the analytics plugin and the template's tight CSP
142+ # stays in place. Set as a repo secret to enable tracking.
143+ VITE_CF_BEACON_TOKEN : ${{ secrets.VITE_CF_BEACON_TOKEN }}
140144
141145
142146 - name : ⚙️ Configure GitHub Pages
Original file line number Diff line number Diff line change @@ -79,6 +79,29 @@ const templateSignaturePlugin = (): Plugin => {
7979 } ;
8080} ;
8181
82+ const cloudflareAnalyticsPlugin = ( ) : Plugin => {
83+ return {
84+ name : 'cloudflare-analytics-injector' ,
85+ transformIndexHtml ( html ) {
86+ const token = process . env . VITE_CF_BEACON_TOKEN ;
87+ if ( ! token ) return html ;
88+
89+ html = html . replace (
90+ "script-src 'self' 'unsafe-inline'" ,
91+ "script-src 'self' 'unsafe-inline' static.cloudflareinsights.com"
92+ ) ;
93+ html = html . replace (
94+ "connect-src 'self'" ,
95+ "connect-src 'self' cloudflareinsights.com"
96+ ) ;
97+
98+ const beaconConfig = JSON . stringify ( { token } ) ;
99+ const snippet = ` <!-- Cloudflare Web Analytics -->\n <script defer src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon='${ beaconConfig } '></script>\n ` ;
100+ return html . replace ( '</body>' , `${ snippet } </body>` ) ;
101+ } ,
102+ } ;
103+ } ;
104+
82105const buildVersionPlugin = ( ) : Plugin => {
83106 return {
84107 name : 'build-version' ,
@@ -108,6 +131,7 @@ export default defineConfig({
108131 themeInjectorPlugin ( ) ,
109132 siteMetadataPlugin ( ) ,
110133 templateSignaturePlugin ( ) ,
134+ cloudflareAnalyticsPlugin ( ) ,
111135 buildVersionPlugin ( ) ,
112136 ...( process . env . NODE_ENV !== "production" &&
113137 process . env . REPL_ID !== undefined
You can’t perform that action at this time.
0 commit comments