Conditional AdSense Script Loading in Confluence

CK CK 3788 
Created at
Updated at  
1,424 0 0

Confluence no longer sells standalone versions, so legacy users like me may be impacted by this post.

In a standalone Confluence instance, you typically have direct access to the server's file system and Confluence's administrative settings. This allows for several methods to inject custom HTML, CSS, and JavaScript.

 

1. Confluence Administration: Look and Feel > Custom HTML

This is the recommended and most straightforward method for global injections without modifying core Confluence files directly.

  • Access: Log in as a Confluence Administrator. Navigate to Administration (gear icon) > General Configuration > Look and Feel > Custom HTML.
  • Fields: Confluence provides specific fields for injecting HTML into different parts of every page:
    • Atlassian Navigation Bar HTML: Content placed here will appear within the global navigation bar.
    • Head HTML: Content placed here will be inserted just before the closing tag. This is ideal for scripts, meta tags, and stylesheets that need to load early.
    • Body HTML: Content placed here will be inserted just after the opening tag. Useful for scripts or content that should appear at the very top of the page body.
    • Footer HTML: Content placed here will be inserted just before the closing tag. This is suitable for scripts that can load later, or for footer-specific content.
  • Usage: Paste your custom HTML, CSS blocks, or JavaScript <script> blocks directly into the relevant fields.

    Conditional AdSense Script Loading in Confluence

 

The below code is what I added to HEAD - it conditionally load Google Analytics and Adsense scripts when the page URL is not starting as /pages/

<meta name="google-adsense-account" content="<your adsense account info>">

<script>
// External links in new tab
jQuery(document).ready(function() {
    jQuery(".external-link").attr("target", "_blank");
});

// Only run if the URL path does NOT start with /pages/
if (!window.location.pathname.startsWith('/pages/')) {
    
    // Google Analytics (gtag.js)
    var gtagScript = document.createElement('script');
    gtagScript.async = true;
    gtagScript.src = 'https://www.googletagmanager.com/gtag/js?id=<your google analytics id>';
    document.head.appendChild(gtagScript);
    
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', 'UA-1093021-16');
    
    // Google AdSense
    var adsenseScript = document.createElement('script');
    adsenseScript.async = true;
    adsenseScript.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=<your google adsense id>';
    adsenseScript.crossOrigin = 'anonymous';
    document.head.appendChild(adsenseScript);
}
</script>

 

The above code is actually working when the user loads the page, and I learned that it is not working when Confluence loads pages dynamically with no real page loading, and the below additional code will help you.

<script>
function manageTrackingAndAds() {
    const isExcludedPath = window.location.pathname.startsWith('/pages/');
    
    // Check if scripts are already there to avoid duplicate injections
    const adsenseExists = document.querySelector('script[src*="adsbygoogle.js"]');

    if (!isExcludedPath) {
        if (!adsenseExists) {
            // Inject AdSense only if we are on a valid page and it's not already there
            var adsenseScript = document.createElement('script');
            adsenseScript.async = true;
            adsenseScript.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=<your adsense id>';
            adsenseScript.crossOrigin = 'anonymous';
            document.head.appendChild(adsenseScript);
        }
    } else {
        // If we are on an excluded path, we can't easily "kill" the script,
        // but we can hide the ad units via CSS
        document.querySelectorAll('.adsbygoogle').forEach(el => el.style.display = 'none');
    }
}

// Listen for URL changes in Single Page Apps
window.addEventListener('popstate', manageTrackingAndAds);

// For frameworks that use pushState (like React/Vue/Next.js)
const originalPushState = history.pushState;
history.pushState = function() {
    originalPushState.apply(this, arguments);
    manageTrackingAndAds();
};

// Run on initial load
manageTrackingAndAds();
</script>

 

Below is another powerful one that only works for non-signin users.

<meta name="google-adsense-account" content="<your Adsense account info>">

<script>
(function() {
    // 1. Check if user is NOT logged in
    // AJS.params.remoteUser is empty for anonymous users
    var isAnonymous = typeof AJS !== 'undefined' && !AJS.params.remoteUser;

    if (isAnonymous) {
        
        // --- Logic A: External links in new tab ---
        jQuery(document).ready(function() {
            jQuery(".external-link").attr("target", "_blank");
        });

        // --- Logic B: Tracking & Ads Injection ---
        function manageTrackingAndAds() {
            var path = window.location.pathname;
            var isExcludedPath = path.includes('/pages/') || path.includes('.action');
            var adsenseExists = document.querySelector('script[src*="adsbygoogle.js"]');

            if (!isExcludedPath && !adsenseExists) {
                // Google Analytics (gtag.js)
                var gtagScript = document.createElement('script');
                gtagScript.async = true;
                gtagScript.src = 'https://www.googletagmanager.com/gtag/js?id=<your Adsense ID>';
                document.head.appendChild(gtagScript);

                window.dataLayer = window.dataLayer || [];
                function gtag(){dataLayer.push(arguments);}
                gtag('js', new Date());
                gtag('config', 'UA-1093021-16');

                // Google AdSense
                var adsenseScript = document.createElement('script');
                adsenseScript.async = true;
                adsenseScript.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=<yount Adsense ID>';
                adsenseScript.crossOrigin = 'anonymous';
                document.head.appendChild(adsenseScript);
            }
        }

        // Initialize and handle SPA transitions
        window.addEventListener('popstate', manageTrackingAndAds);
        var originalPushState = history.pushState;
        history.pushState = function() {
            originalPushState.apply(this, arguments);
            manageTrackingAndAds();
        };

        manageTrackingAndAds();
    }
})();
</script>

 

Tags Confluence Custom HTML Custom HTML Google Adsense Google Analytics Facebook X
Comments 0
  1. Invalid Auction Storms in Ad Tech
    108
  2. Building MRC-Compliant Instrumentation in Ad Tech: Implementation Steps and Key Challenges
    209
  3. The Two Clocks of Ad Server Architecture
    78
  4. Collecting Proof-of-Play from 100,000 Screens
    154
  5. Extracting Context from Live Video: The Architecture Got Simpler When We Stopped Building Features
    264
  6. The New Ad Stack Behind Live Sports Streaming: Inside SGAI, EABN, and the Standards Race to Fix Live Monetization
    674
  7. IAS IP Blocklist: Causes, Resolution, and Detection Strategies
    198
  8. What Is UniversalAdId? The Complete Guide to VAST Video Ad Tracking
    206
  9. End-to-End Contextual Video Processing Architecture for AdTech
    217
  10. UCP for AVOD: Standardizing Ad Monetization
    355
  11. Advertiser Universal Commerce Protocol (UCP) Readiness Checklist
    449
  12. SEO is dying, AEO is coming
    1,241
  13. Architecting ML/LLM Ad Targeting with Kafka, Flink, FAISS, and Milvus
    285
  14. What is VAST? What is VMAP? How VAST/VMAP works?
    903
  15. Render Ad creatives using setSafeFrameConfig in Google IMA
    1,085
  16. AWS Real-Time Dashboards: Druid, ClickHouse, or Lambda?
    627
  17. Ad Tech Multi-Tenancy: A Spectrum of Isolation Architectures on AWS
    337
  18. Attribution's New Blueprint: Balancing Performance and Privacy
    507
  19. Ad Auction Architectures: A Publisher's Guide to Optimal Monetization
    686
  20. Ad Pacing Unpacked: Architecting Guaranteed Delivery
    368
  21. Brand Safety: AI-Driven Content Moderation on AWS
    739
  22. The Future of Programmatic Advertising: Privacy-First Strategies and Trade-offs
    523
  23. Measuring Ad Viewability: AWS Architectures for Programmatic Accountability
    480
  24. AI-Powered Ad Fraud Detection: Architectural Strategies
    337
  25. AWS Ad Exchange Disaster Recovery: Active-Active, Active-Passive, and Cell Strategies - Disaster Recovery
    1,361
  26. Architecting Ad Tech's Terabyte Log Pipeline - Log Aggregation
    331
  27. Ad Tech Edge Architectures: Reducing Latency and Offloading Work - Edge Computing
    338
Recently updated
  1. Google OAuth Token Expiration: Causes and Solutions
    31
  2. Why 100% SEO Guarantees Better User Engagement and How to Achieve It in Your Service
    57
  3. Why SPF and DKIM Are Essential for Linux Email Servers?
    51
  4. How do I create animated background for Google Meet?
    23,256
  5. MaxMind GeoLite2 vs. DB-IP Lite vs. ip-api.com: Choosing the Right Free IP Geolocation Solution
    273
  6. Meet Valkey: Why Redis Changed Its License, Why Valkey is Better, and How to Use It as a Drop-in Replacement
    105
  7. How Rogue Web Scrapers Are Stealing My Content and Destroying My Server
    170
  8. Array of arguments passed to script in PHP
    99
  9. Frequency Cap Architecture Overview
    527
  10. Vector Search in Relational Databases (RDBs): Trends & Usage Environments
    304
  11. What is RedisVL?
    117
  12. Designing a Skill Registry Architecture: Minimize Token Usage and Maximize AI Performance
    247
  13. TPU & GPU Cluster Management Tools
    258
  14. The Concept of Scaffolding in AI Agents
    245
  15. Beyond Static Pipelines: Architecting LLM Multi-Agent Systems for Autonomous Workflow Orchestration
    599
  16. AI-DLC vs. AI-SDLC: Model-Centric vs. System-Centric AI Development
    269
  17. Fine-Tuning Open-Weight LLMs: Training, Licensing, and Deploying Custom Models with Ollama
    355
  18. Inside the Next-Generation Streaming Architecture: Ultra-Low Latency, SGAI, and AI Codecs
    207
  19. Machine Learning: Training vs. Ranking
    231
  20. The Continuous Learning Machine: Designing a Loop That Actually Turns
    229
  21. The Next-Gen Low-Latency Standards: LL-HLS & MoQ
    204
  22. Designing a Data Curation System Around a Vector Database
    230
  23. Designing MLOps Architectures to Handle Seasonal Data Drift in EV Fleet Models
    201
  24. From 15 to 40+ FPS: Accelerating PyTorch Object Detection on Automotive ECUs
    233
  25. Understanding Data Lineage
    272
  26. System Requirements and Architecture: Intelligent Priority-Based Scheduler
    176
  27. GPU & LLM Cluster Infrastructure & Task Scheduling Architecture
    255
  28. Java Variant Type
    213
  29. When Do You Need Real-Time Model Registry Versioning Powered by Autonomous Agents?
    242
  30. From SDI to MXL: Inside the Cloud-Native Infrastructure Powering Next-Gen Live Broadcast
    582