Skip to content

Default Theme: Carbon Ads ​

Learn how to integrate Carbon Ads with the VitePress default theme.

Overview ​

Carbon Ads is a privacy-focused ad network for developers and designers. VitePress provides built-in support for Carbon Ads integration.

Basic Setup ​

Configuration ​

Add Carbon Ads to your theme configuration:

javascript
// .vitepress/config.js
export default {
  themeConfig: {
    carbonAds: {
      code: 'your-carbon-code',
      placement: 'your-placement-id'
    }
  }
}

Getting Carbon Ads Credentials ​

  1. Sign up at Carbon Ads
  2. Create a new ad placement
  3. Get your code and placement values
  4. Add them to your VitePress configuration

Configuration Options ​

Basic Configuration ​

javascript
export default {
  themeConfig: {
    carbonAds: {
      code: 'CEBDT27Y',
      placement: 'vitepressdevcom'
    }
  }
}

Advanced Configuration ​

javascript
export default {
  themeConfig: {
    carbonAds: {
      code: 'CEBDT27Y',
      placement: 'vitepressdevcom',
      
      // Custom configuration
      serve: 'CEBDT27Y',
      format: 'cover',
      
      // Targeting options
      segment: 'placement:vitepressdevcom',
      
      // Custom styling
      className: 'custom-carbon-ads'
    }
  }
}

Placement Options ​

Carbon Ads appear in the sidebar by default:

javascript
export default {
  themeConfig: {
    carbonAds: {
      code: 'CEBDT27Y',
      placement: 'vitepressdevcom'
    }
  }
}

Custom Placement ​

Place ads in custom locations:

vue
<!-- In your custom theme or component -->
<template>
  <div class="custom-ad-container">
    <CarbonAds 
      :code="carbonConfig.code"
      :placement="carbonConfig.placement"
    />
  </div>
</template>

<script setup>
import { useData } from 'vitepress'

const { theme } = useData()
const carbonConfig = theme.value.carbonAds
</script>

Multiple Placements ​

Use different placements for different pages:

javascript
export default {
  themeConfig: {
    carbonAds: {
      code: 'CEBDT27Y',
      placement: 'vitepressdevcom',
      
      // Page-specific placements
      placements: {
        '/guide/': 'vitepressguide',
        '/api/': 'vitepressapi',
        '/examples/': 'vitepressexamples'
      }
    }
  }
}

Styling Carbon Ads ​

Default Styling ​

Carbon Ads come with default styling that matches the VitePress theme:

css
.carbon-ads {
  display: block;
  overflow: hidden;
  max-width: 330px;
  border-radius: 4px;
  text-align: center;
  border: 1px solid var(--vp-c-border);
  background-color: var(--vp-c-bg-soft);
}

.carbon-img {
  display: block;
  margin: 0 auto;
  line-height: 1;
}

.carbon-text {
  display: block;
  padding: 10px;
  line-height: 1.35;
  text-decoration: none;
  color: var(--vp-c-text-1);
  font-size: 12px;
}

.carbon-poweredby {
  display: block;
  padding: 6px 10px;
  background: var(--vp-c-bg-mute);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-weight: 600;
  font-size: 9px;
  line-height: 1;
  border-top: 1px solid var(--vp-c-border);
  color: var(--vp-c-text-2);
}

Custom Styling ​

Customize the appearance:

css
/* Custom Carbon Ads styling */
.custom-carbon-ads {
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

.custom-carbon-ads:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

.custom-carbon-ads .carbon-text {
  font-size: 13px;
  line-height: 1.4;
  padding: 12px;
}

.custom-carbon-ads .carbon-poweredby {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  font-size: 10px;
}

Responsive Design ​

Make ads responsive:

css
.carbon-ads {
  width: 100%;
  max-width: 330px;
}

@media (max-width: 768px) {
  .carbon-ads {
    max-width: 280px;
    margin: 0 auto;
  }
  
  .carbon-text {
    font-size: 11px;
    padding: 8px;
  }
}

@media (max-width: 480px) {
  .carbon-ads {
    max-width: 100%;
  }
}

Advanced Integration ​

Conditional Display ​

Show ads conditionally:

vue
<script setup>
import { computed } from 'vue'
import { useData } from 'vitepress'

const { page, theme } = useData()

const shouldShowAds = computed(() => {
  // Don't show ads on certain pages
  const excludedPaths = ['/privacy', '/terms', '/contact']
  if (excludedPaths.includes(page.value.relativePath)) {
    return false
  }
  
  // Only show ads in production
  if (import.meta.env.DEV) {
    return false
  }
  
  return theme.value.carbonAds?.code
})
</script>

<template>
  <div v-if="shouldShowAds" class="carbon-ads-container">
    <CarbonAds 
      :code="theme.carbonAds.code"
      :placement="theme.carbonAds.placement"
    />
  </div>
</template>

A/B Testing ​

Implement A/B testing for ad placements:

vue
<script setup>
import { ref, onMounted } from 'vue'
import { useData } from 'vitepress'

const { theme } = useData()
const adVariant = ref('A')

onMounted(() => {
  // Simple A/B testing
  adVariant.value = Math.random() > 0.5 ? 'A' : 'B'
})

const adConfig = computed(() => {
  const baseConfig = theme.value.carbonAds
  
  if (adVariant.value === 'B') {
    return {
      ...baseConfig,
      placement: baseConfig.placementB || baseConfig.placement
    }
  }
  
  return baseConfig
})
</script>

<template>
  <CarbonAds 
    :code="adConfig.code"
    :placement="adConfig.placement"
    :data-variant="adVariant"
  />
</template>

Analytics Integration ​

Track ad performance:

vue
<script setup>
import { onMounted } from 'vue'

onMounted(() => {
  // Track ad impressions
  if (typeof gtag !== 'undefined') {
    gtag('event', 'carbon_ad_impression', {
      event_category: 'advertising',
      event_label: 'carbon_ads'
    })
  }
  
  // Track ad clicks
  document.addEventListener('click', (event) => {
    if (event.target.closest('.carbon-ads')) {
      if (typeof gtag !== 'undefined') {
        gtag('event', 'carbon_ad_click', {
          event_category: 'advertising',
          event_label: 'carbon_ads'
        })
      }
    }
  })
})
</script>

Custom Carbon Ads Component ​

Enhanced Component ​

Create a custom Carbon Ads component:

vue
<!-- components/EnhancedCarbonAds.vue -->
<template>
  <div 
    v-if="shouldShow"
    class="enhanced-carbon-ads"
    :class="{ 'is-loading': isLoading }"
  >
    <div v-if="isLoading" class="carbon-loading">
      <div class="loading-skeleton"></div>
    </div>
    
    <div 
      ref="carbonContainer"
      class="carbon-container"
      :style="{ opacity: isLoading ? 0 : 1 }"
    ></div>
    
    <div v-if="showLabel" class="carbon-label">
      Advertisement
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed } from 'vue'

const props = defineProps({
  code: {
    type: String,
    required: true
  },
  placement: {
    type: String,
    required: true
  },
  showLabel: {
    type: Boolean,
    default: true
  },
  lazy: {
    type: Boolean,
    default: false
  }
})

const carbonContainer = ref(null)
const isLoading = ref(true)
const isVisible = ref(!props.lazy)

const shouldShow = computed(() => {
  return props.code && props.placement && isVisible.value
})

let observer = null

onMounted(() => {
  if (props.lazy) {
    // Lazy load ads when they come into view
    observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            isVisible.value = true
            observer.unobserve(entry.target)
          }
        })
      },
      { threshold: 0.1 }
    )
    
    observer.observe(carbonContainer.value)
  } else {
    loadAd()
  }
})

onUnmounted(() => {
  if (observer) {
    observer.disconnect()
  }
})

function loadAd() {
  if (!carbonContainer.value) return
  
  // Create Carbon Ads script
  const script = document.createElement('script')
  script.src = `//cdn.carbonads.com/carbon.js?serve=${props.code}&placement=${props.placement}`
  script.id = '_carbonads_js'
  script.async = true
  
  script.onload = () => {
    isLoading.value = false
  }
  
  script.onerror = () => {
    isLoading.value = false
    console.warn('Failed to load Carbon Ads')
  }
  
  carbonContainer.value.appendChild(script)
}

// Watch for visibility changes
watch(isVisible, (visible) => {
  if (visible && !isLoading.value) {
    loadAd()
  }
})
</script>

<style scoped>
.enhanced-carbon-ads {
  position: relative;
  margin: 20px 0;
}

.carbon-container {
  transition: opacity 0.3s ease;
}

.carbon-loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-skeleton {
  width: 330px;
  height: 132px;
  background: linear-gradient(
    90deg,
    var(--vp-c-bg-mute) 25%,
    var(--vp-c-bg-soft) 50%,
    var(--vp-c-bg-mute) 75%
  );
  background-size: 200% 100%;
  animation: loading 1.5s infinite;
  border-radius: 4px;
}

@keyframes loading {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.carbon-label {
  text-align: center;
  font-size: 10px;
  color: var(--vp-c-text-3);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-top: 8px;
}

.is-loading .carbon-label {
  opacity: 0.5;
}
</style>

Privacy and Compliance ​

GDPR Compliance ​

Handle GDPR requirements:

vue
<script setup>
import { ref, computed } from 'vue'

const hasConsent = ref(false)
const showConsentBanner = ref(true)

const shouldShowAds = computed(() => {
  // Only show ads if user has consented
  return hasConsent.value
})

function grantConsent() {
  hasConsent.value = true
  showConsentBanner.value = false
  localStorage.setItem('carbon-ads-consent', 'true')
}

function denyConsent() {
  hasConsent.value = false
  showConsentBanner.value = false
  localStorage.setItem('carbon-ads-consent', 'false')
}

onMounted(() => {
  const consent = localStorage.getItem('carbon-ads-consent')
  if (consent === 'true') {
    hasConsent.value = true
    showConsentBanner.value = false
  } else if (consent === 'false') {
    hasConsent.value = false
    showConsentBanner.value = false
  }
})
</script>

<template>
  <div v-if="showConsentBanner" class="consent-banner">
    <p>We use Carbon Ads to show relevant advertisements. Do you consent to personalized ads?</p>
    <button @click="grantConsent">Accept</button>
    <button @click="denyConsent">Decline</button>
  </div>
  
  <CarbonAds v-if="shouldShowAds" />
</template>

Do Not Track ​

Respect Do Not Track headers:

javascript
function shouldShowAds() {
  // Check Do Not Track setting
  if (navigator.doNotTrack === '1' || 
      window.doNotTrack === '1' || 
      navigator.msDoNotTrack === '1') {
    return false
  }
  
  return true
}

Performance Optimization ​

Lazy Loading ​

Implement lazy loading for better performance:

vue
<script setup>
import { ref, onMounted } from 'vue'

const adContainer = ref(null)
const isLoaded = ref(false)

onMounted(() => {
  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting && !isLoaded.value) {
          loadCarbonAds()
          observer.unobserve(entry.target)
        }
      })
    },
    { threshold: 0.1 }
  )
  
  if (adContainer.value) {
    observer.observe(adContainer.value)
  }
})

function loadCarbonAds() {
  isLoaded.value = true
  // Load Carbon Ads script
}
</script>

Preloading ​

Preload Carbon Ads resources:

html
<!-- In your HTML head -->
<link rel="dns-prefetch" href="//cdn.carbonads.com">
<link rel="preconnect" href="//cdn.carbonads.com">

Troubleshooting ​

Common Issues ​

Ads not showing:

  1. Check your code and placement values
  2. Verify your domain is approved by Carbon Ads
  3. Ensure you're not using ad blockers during testing
  4. Check browser console for errors

Styling issues:

  1. Check CSS specificity
  2. Verify CSS variables are defined
  3. Test in different browsers
  4. Check for conflicting styles

Performance issues:

  1. Implement lazy loading
  2. Use DNS prefetching
  3. Optimize CSS delivery
  4. Monitor Core Web Vitals

Debug Mode ​

Enable debug mode for troubleshooting:

javascript
export default {
  themeConfig: {
    carbonAds: {
      code: 'CEBDT27Y',
      placement: 'vitepressdevcom',
      debug: process.env.NODE_ENV === 'development'
    }
  }
}

Best Practices ​

User Experience ​

  1. Non-intrusive placement - Don't interfere with content
  2. Relevant ads - Use proper targeting
  3. Fast loading - Implement lazy loading
  4. Responsive design - Work on all devices

Performance ​

  1. Lazy loading - Load ads only when needed
  2. DNS prefetching - Preload Carbon Ads resources
  3. Minimal CSS - Keep styling lightweight
  4. Error handling - Gracefully handle loading failures

Privacy ​

  1. Respect user preferences - Honor Do Not Track
  2. GDPR compliance - Obtain proper consent
  3. Transparent disclosure - Clearly label advertisements
  4. Data minimization - Only collect necessary data

Maintenance ​

  1. Monitor performance - Track loading times and errors
  2. Update regularly - Keep Carbon Ads integration current
  3. Test thoroughly - Verify functionality across browsers
  4. Backup plans - Have fallbacks for ad failures

Examples ​

Basic Implementation ​

javascript
// .vitepress/config.js
export default {
  themeConfig: {
    carbonAds: {
      code: 'CEBDT27Y',
      placement: 'vitepressdevcom'
    }
  }
}

Advanced Implementation ​

javascript
// .vitepress/config.js
export default {
  themeConfig: {
    carbonAds: {
      code: 'CEBDT27Y',
      placement: 'vitepressdevcom',
      
      // Conditional display
      enabled: process.env.NODE_ENV === 'production',
      
      // Custom styling
      className: 'custom-carbon-ads',
      
      // Analytics
      trackImpressions: true,
      trackClicks: true,
      
      // A/B testing
      variants: {
        A: { placement: 'vitepressdevcom' },
        B: { placement: 'vitepressdevcom-alt' }
      }
    }
  }
}

Custom Theme Integration ​

vue
<!-- .vitepress/theme/components/CarbonAdsWrapper.vue -->
<template>
  <div class="carbon-ads-wrapper">
    <h4 class="ads-title">Sponsored</h4>
    <CarbonAds 
      v-if="shouldShowAds"
      :code="carbonConfig.code"
      :placement="carbonConfig.placement"
      @load="onAdLoad"
      @error="onAdError"
    />
    <div v-else class="ads-placeholder">
      <p>Support us by disabling your ad blocker</p>
    </div>
  </div>
</template>

<script setup>
import { computed } from 'vue'
import { useData } from 'vitepress'

const { theme } = useData()

const carbonConfig = computed(() => theme.value.carbonAds || {})
const shouldShowAds = computed(() => {
  return carbonConfig.value.code && 
         carbonConfig.value.placement && 
         !window.navigator.doNotTrack
})

function onAdLoad() {
  console.log('Carbon ad loaded successfully')
}

function onAdError() {
  console.warn('Failed to load Carbon ad')
}
</script>

<style scoped>
.carbon-ads-wrapper {
  margin: 24px 0;
  padding: 16px;
  border: 1px solid var(--vp-c-border);
  border-radius: 8px;
  background: var(--vp-c-bg-soft);
}

.ads-title {
  margin: 0 0 12px 0;
  font-size: 12px;
  font-weight: 500;
  color: var(--vp-c-text-2);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.ads-placeholder {
  text-align: center;
  padding: 20px;
  color: var(--vp-c-text-2);
  font-size: 14px;
}
</style>

This completes the comprehensive guide for integrating Carbon Ads with VitePress, covering everything from basic setup to advanced customization and best practices.

VitePress Development Guide