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