Why GA4 Tracking Is Breaking on Modern SharePoint Pages in 2026 — and How to Fix It
Billy Peralta
April 19, 2026
TL;DR
SharePoint Online began enforcing Content Security Policy (CSP) in early 2026. This enforcement is breaking older GA4 implementations that rely on inline script injection or basic script loading patterns. If your GA4 tracking stopped working on modern SharePoint pages, it is most likely a CSP issue, not Microsoft deliberately blocking Google Analytics.
The fix is to replace inline script injection with a CSP-compliant SPFx Application Customizer that bundles GA initialization inside the SPFx package, loads gtag.js from a trusted source, and manually tracks page views during client-side navigation.
Table of Contents
- What actually changed
- Why older GA4 implementations are breaking
- How to diagnose the issue
- The CSP-compliant SPFx solution
- Updating CSP trusted sources
- Validating GA4 is working
- Alternative analytics options
- Final thoughts
- FAQ
If you have been running Google Analytics 4 on a modern SharePoint Online site using an SPFx Application Customizer, there is a good chance your tracking recently stopped working.
You are not alone. I have been seeing this come up in community threads and client conversations. The common reaction is to assume that Microsoft blocked Google Analytics. That is not exactly what happened.
What actually happened is that SharePoint Online started enforcing Content Security Policy (CSP) for modern pages, and many existing GA4 implementations were not built to survive that change.
1. What Actually Changed
Three things are happening in SharePoint Online in 2026 that affect analytics tracking.
SharePoint Online CSP Enforcement
Microsoft announced that SharePoint Online would begin enforcing CSP starting around March 2026. Before this, CSP violations were mostly reported but not blocked. Now, non-compliant scripts can be actively blocked by the browser.
CSP enforcement affects SPFx solutions that:
- load scripts from external CDNs,
- dynamically inject scripts at runtime,
- use inline JavaScript,
- use Script Editor style patterns,
- rely on older modern page customization patterns.
Microsoft’s guidance is clear:
- bundled SPFx assets in the package are generally trusted,
- CDN-based SPFx assets can be trusted automatically when declared properly,
- dynamically loaded scripts may need manual Trusted Script Sources entries,
- inline scripts should be moved to script files because inline scripts are blocked,
- the CSP nonce value is not available to developers.
The New SharePoint Experience
Microsoft is also rolling out a refreshed SharePoint experience in 2026. This includes a redesigned app bar, updated page layouts, and visual changes that affect where and when Application Customizers load. While this may not be the direct cause of GA4 failure, it can affect timing and behavior.
GA4 Needs More Than script-src
Google’s own CSP guidance for GA4 requires more than just loading a script. GA4 also needs network endpoints for data collection:
script-src https://*.googletagmanager.com
img-src https://*.google-analytics.com https://*.googletagmanager.com
connect-src https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com
SharePoint’s Add-SPOContentSecurityPolicy cmdlet is primarily about adding sources to the script configuration. It may not fully solve all GA4 endpoint requirements depending on how SharePoint emits the CSP header.
2. Why Older GA4 Implementations Are Breaking
There are several root causes worth understanding.
Inline GA4 initialization is blocked
The popular PnP GA4 Application Customizer sample and many older tutorials append an inline script element containing code like this:
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
Microsoft explicitly states that inline scripts are blocked by SharePoint’s CSP and the nonce value is not available to developers. If your SPFx solution injects GA4 this way, it will be blocked.
Only script sources were trusted
Adding trusted sources like this:
Add-SPOContentSecurityPolicy -Source "https://www.googletagmanager.com"
Add-SPOContentSecurityPolicy -Source "https://www.google-analytics.com"
may allow gtag.js to load, but GA4 collection requests still depend on connect-src and img-src behavior. If those endpoints are not allowed, the g/collect requests can fail silently.
SharePoint modern pages are SPA-like
Modern SharePoint navigation happens without a full browser page reload. That means GA4 may only see the initial page load unless your Application Customizer manually sends page view events on every navigation change. If you are not handling navigatedEvent, you are only tracking the first page.
Application Customizer lifecycle timing
SharePoint Application Customizers can behave differently across initial page loads, client-side navigation, and cross-site navigation. The extension may initialize once but not re-run on every page transition. Without explicit navigation handling, page views get lost.
3. How to Diagnose the Issue
Before changing code, confirm what is actually failing.
- Open the modern SharePoint page in the browser.
- Open DevTools (F12).
- Check Console for CSP violation errors.
- Check Network tab for:
gtag/js?id=G-...— is the script loading?g/collect— are collection requests going through?- Any blocked, cancelled, or failed requests.
- Test with CSP query parameters:
?csp=enforce
?csp=report
- Check Microsoft Purview Audit logs for:
Violated Content Security Policy
ViolatedContentSecurityPolicy
- Test in an InPrivate/Incognito window with no extensions to rule out ad blockers and browser tracking prevention.
4. The CSP-Compliant SPFx Solution
The fix is to stop injecting inline scripts and move GA4 initialization into TypeScript inside the SPFx bundle. Here is a recommended implementation pattern:
import { override } from '@microsoft/decorators';
import { BaseApplicationCustomizer } from '@microsoft/sp-application-base';
import { SPComponentLoader } from '@microsoft/sp-loader';
export interface IAnalyticsApplicationCustomizerProperties {
trackingId: string;
debug?: boolean;
}
declare global {
interface Window {
dataLayer: unknown[];
gtag: (...args: unknown[]) => void;
}
}
export default class AnalyticsApplicationCustomizer
extends BaseApplicationCustomizer<IAnalyticsApplicationCustomizerProperties> {
private _lastTrackedUrl = '';
@override
public async onInit(): Promise<void> {
const trackingId = this.properties.trackingId;
if (!trackingId) {
return;
}
this._initializeDataLayer();
await SPComponentLoader.loadScript(
`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(trackingId)}`
);
window.gtag('js', new Date());
// Disable automatic page_view so SharePoint SPA navigation
// is handled manually.
window.gtag('config', trackingId, {
send_page_view: false,
debug_mode: !!this.properties.debug
});
this._trackPageView();
this.context.application.navigatedEvent.add(this, () => {
// Give SharePoint time to update document title and page context.
window.setTimeout(() => this._trackPageView(), 500);
});
}
private _initializeDataLayer(): void {
window.dataLayer = window.dataLayer || [];
window.gtag = window.gtag || function gtag(): void {
window.dataLayer.push(arguments);
};
}
private _trackPageView(): void {
const url = window.location.pathname + window.location.search;
if (url === this._lastTrackedUrl) {
return;
}
this._lastTrackedUrl = url;
window.gtag('event', 'page_view', {
page_title: document.title,
page_location: window.location.href,
page_path: url
});
}
}
Why this is better
- No inline script injection. GA initialization runs from inside the SPFx bundle, which is trusted by CSP.
gtag.jsloads from an explicit trusted source usingSPComponentLoader.loadScript.- SPA navigation is tracked manually using
navigatedEvent. - Duplicate page views are prevented by checking against the last tracked URL.
send_page_view: falsedisables the automatic page view so you control exactly when events fire.
5. Updating CSP Trusted Sources
You still need to register Google’s domains as trusted script sources in your tenant. Start with the minimum:
# Check current CSP configuration
Get-SPOContentSecurityPolicy
# Add Google trusted sources
Add-SPOContentSecurityPolicy -Source "https://www.googletagmanager.com"
Add-SPOContentSecurityPolicy -Source "https://www.google-analytics.com"
Add-SPOContentSecurityPolicy -Source "https://analytics.google.com"
Depending on your tenant behavior, you may need wildcard sources:
Add-SPOContentSecurityPolicy -Source "https://*.googletagmanager.com"
Add-SPOContentSecurityPolicy -Source "https://*.google-analytics.com"
Add-SPOContentSecurityPolicy -Source "https://*.analytics.google.com"
Keep in mind that SharePoint’s Trusted Script Sources are primarily script-source oriented. They may not fully address every GA4 endpoint requirement if the relevant CSP directive (like connect-src) is not under tenant control.
6. Validating GA4 Is Working
After deploying the updated Application Customizer:
- Enable
debug_modein the SPFx configuration temporarily. - Open GA4 DebugView in the Google Analytics console.
- Browse the SharePoint site and navigate between pages.
- Confirm
page_viewevents appear in DebugView for each navigation. - Check the Network tab in DevTools —
g/collectrequests should return200. - Confirm no duplicate page views after navigating back and forth.
- Use Tag Assistant if it can connect to your SharePoint URL.
7. Alternative Analytics Options
If GA4 continues to be problematic in your environment, there are alternatives worth considering.
Microsoft Clarity
Easier to implement and useful for heatmaps and session replays. It often works where GA4 becomes painful. However, it is not the same as GA4 and may not provide the granular event tracking stakeholders expect.
SharePoint Built-in Analytics and Viva Insights
Microsoft-native, no third-party tracking scripts required, and a better fit for internal intranet governance. The tradeoff is less flexibility and potentially different reporting from what existing GA dashboards provide.
Application Insights
Good for custom telemetry in SPFx solutions and internal Azure/Microsoft environments. Requires custom dashboards and is not a marketing analytics tool, but offers more control over the data model.
Server-Side GTM or Google Tag Gateway
A more durable tagging model that reduces browser-side dependency on Google domains. However, SharePoint Online runs on *.sharepoint.com so same-origin approaches are difficult. This may be overkill for internal intranet adoption tracking.
8. Final Thoughts
GA4 on modern SharePoint is not dead, but the old implementation pattern is.
SharePoint Online’s CSP enforcement is a positive change for security. It just means that analytics implementations need to be modernized alongside everything else.
If your GA4 tracking broke recently, do not panic. The path forward is:
- Diagnose what CSP is actually blocking.
- Replace inline script injection with a bundled SPFx approach.
- Handle SPA navigation explicitly with
navigatedEvent. - Register the correct trusted script sources.
- Validate end-to-end with GA4 DebugView.
If you are looking for my earlier guide on setting up GA4 with SPFx from scratch, check out my previous post on How to Add Google Analytics 4 to SharePoint with SPFx. The principles there still apply — the implementation just needs to be updated for CSP compliance.
FAQ
Did Microsoft block Google Analytics on SharePoint?
Not exactly. Microsoft began enforcing Content Security Policy on modern SharePoint pages in 2026. This blocks non-compliant scripts, including older GA4 implementations that use inline script injection.
Why did my GA4 stop working on SharePoint?
Most likely because your SPFx Application Customizer injects GA4 using inline JavaScript, which is now blocked by CSP. The fix is to move the initialization logic into the SPFx bundle.
Do I need to add trusted script sources for GA4?
Yes. You need to register Google’s domains using Add-SPOContentSecurityPolicy so that gtag.js can load from Google’s CDN.
Why am I only seeing one page view per session?
Modern SharePoint uses client-side navigation. Without handling navigatedEvent in your Application Customizer, GA4 only sees the initial page load.
Can I still use the PnP GA4 sample?
The PnP sample may need to be updated for CSP compliance. Check whether it injects inline scripts. If it does, you should modify the implementation to use the bundled approach shown in this post.
What SharePoint versions are affected?
This applies to SharePoint Online modern pages. SharePoint Server on-premises environments are not affected by the CSP enforcement.
Is there a way to test CSP before it breaks things?
Yes. You can append ?csp=report to a SharePoint page URL to see violations without enforcement, or ?csp=enforce to test enforcement behavior. You can also check Microsoft Purview Audit logs for CSP violation events.
Need help with SPFx?
I specialize in building enterprise solutions. Let's discuss your project.