Skip to content

Configuration Files

Partner Documentation

Complete reference for all DCS configuration files.

.dcs/config.yaml

Main configuration file for DCS integration.

Full Schema

yaml
# Required: Site identification
site:
  slug: my-site                    # Unique identifier (lowercase, hyphens)
  name: My Site                    # Display name
  description: Site description    # Optional
  language: en-US                  # Optional, default: en-US

# Required: API configuration
api:
  endpoint: https://portal.duffcloudservices.com/api
  timeout: 5000                    # Optional, milliseconds
  retries: 3                       # Optional, retry count

# Feature flags
features:
  textOverrides: true              # Enable text editing
  seoMetadata: true                # Enable SEO management
  blog: true                       # Enable blog CMS
  analytics: true                  # Enable analytics
  devRequests: true                # Enable development requests

# Build configuration
build:
  outputDir: .vitepress/dist       # Build output directory
  command: pnpm build              # Build command
  contentDir: docs                 # Content directory

# Deployment configuration  
deployment:
  provider: azure-swa              # Hosting provider
  devResourceId: /subscriptions/.../staticSites/my-site-dev
  prodResourceId: /subscriptions/.../staticSites/my-site-prod

# Optional: Analytics configuration
analytics:
  trackPageViews: true
  trackEvents: true
  anonymizeIp: true
  excludePaths:                    # Paths to exclude from tracking
    - /admin/*
    - /preview/*

# Optional: Content caching
cache:
  enabled: true
  ttl: 300                         # Seconds
  strategy: stale-while-revalidate

.dcs/pages.yaml

Registry of pages for the portal.

Full Schema

yaml
pages:
  - slug: home                     # URL-safe identifier
    path: /                        # Route path
    type: static                   # Page type: static, index, dynamic
    title: Home                    # Display title
    deletable: false               # Can be deleted via portal
    textKeys:                      # Text keys (auto-discovered if empty)
      - home.hero.title
      - home.hero.subtitle
    meta:                          # Optional metadata
      template: landing            # Template name
      priority: high               # sitemap priority
      changefreq: weekly           # sitemap change frequency

Page Types

TypeDescriptionExample
staticStandard pages/about, /services
indexCollection landing/blog
dynamicGenerated from data/blog/:slug

Required Pages

Every site should have:

yaml
pages:
  - slug: home
    path: /
    type: static
    title: Home
    deletable: false

Environment Variables

Required Variables

bash
# .env
VITE_DCS_API=https://portal.duffcloudservices.com/api
VITE_SITE_ID=your-site-id

Optional Variables

bash
# Development
VITE_DCS_DEBUG=true                # Enable debug logging

# Build
VITE_BUILD_TIME=true               # Fetch content at build time

# Analytics
VITE_ANALYTICS_ENABLED=true        # Enable client-side analytics

Environment Files

FilePurpose
.envDefault variables
.env.localLocal overrides (git-ignored)
.env.developmentDevelopment mode
.env.productionProduction mode

GitHub Configuration

Repository Secrets

Required secrets for GitHub Actions:

# Azure Authentication
AZURE_CLIENT_ID=<service-principal-id>
AZURE_CLIENT_SECRET=<service-principal-secret>
AZURE_TENANT_ID=<tenant-id>
AZURE_SUBSCRIPTION_ID=<subscription-id>

# DCS Integration
DCS_SERVER_URL=https://portal.duffcloudservices.com
AZURE_SWA_TOKEN=<static-web-app-token>

# Optional: Content fetching
VITE_DCS_API=https://portal.duffcloudservices.com/api
VITE_SITE_ID=<site-id>

Copilot Instructions

Create .github/copilot-instructions.md:

markdown
# Copilot Instructions for [Site Name]

## Project Overview
This is a VitePress marketing site integrated with DCS.

## Architecture
- Framework: VitePress
- Styling: Tailwind CSS
- DCS Integration: useTextContent composable

## Text Content Pattern
Use the `useTextContent` composable for editable text:
\`\`\`vue
import { useTextContent } from '@/lib/use-text-content'
const { t } = useTextContent()
// Usage: t('key', 'default value')
\`\`\`

## Key Conventions
- Use Composition API with TypeScript
- Follow BEM naming for custom CSS
- Keep components small and focused

## Pages Configuration
Update `.dcs/pages.yaml` when adding new pages.

## Development Workflow
1. Create feature branch
2. Make changes
3. Test locally
4. Submit PR to release branch

Azure SWA Configuration

staticwebapp.config.json

json
{
  "navigationFallback": {
    "rewrite": "/index.html",
    "exclude": [
      "/images/*",
      "/fonts/*",
      "/*.ico",
      "/*.xml",
      "/*.json"
    ]
  },
  "routes": [
    {
      "route": "/api/*",
      "rewrite": "/api/{*}"
    }
  ],
  "responseOverrides": {
    "404": {
      "rewrite": "/404.html"
    }
  },
  "mimeTypes": {
    ".webmanifest": "application/manifest+json"
  },
  "globalHeaders": {
    "X-Content-Type-Options": "nosniff",
    "X-Frame-Options": "DENY",
    "Referrer-Policy": "strict-origin-when-cross-origin"
  }
}

VitePress Configuration

typescript
import { defineConfig } from 'vitepress'

export default defineConfig({
  title: 'My Site',
  description: 'A DCS-powered website',
  
  head: [
    ['link', { rel: 'icon', href: '/favicon.ico' }],
    ['meta', { name: 'theme-color', content: '#3b82f6' }],
  ],
  
  themeConfig: {
    logo: '/logo.svg',
    siteTitle: 'My Site',
    
    nav: [
      { text: 'Home', link: '/' },
      { text: 'About', link: '/about' },
      { text: 'Blog', link: '/blog/' },
    ],
    
    socialLinks: [
      { icon: 'twitter', link: 'https://twitter.com/...' },
      { icon: 'github', link: 'https://github.com/...' }
    ],
    
    footer: {
      message: 'Powered by DCS',
      copyright: `© ${new Date().getFullYear()} My Company`
    }
  },
  
  sitemap: {
    hostname: 'https://mysite.com'
  },
  
  lastUpdated: true,
  
  vite: {
    define: {
      __DCS_API__: JSON.stringify(process.env.VITE_DCS_API),
      __SITE_ID__: JSON.stringify(process.env.VITE_SITE_ID)
    }
  }
})

TypeScript Configuration

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "jsx": "preserve",
    "paths": {
      "@/*": ["./src/*"]
    },
    "types": ["vitepress/client"]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.vue",
    ".vitepress/**/*.ts",
    ".vitepress/**/*.vue"
  ]
}

Validation

Config Validation Script

typescript
// scripts/validate-config.ts
import { readFileSync, existsSync } from 'fs'
import YAML from 'yaml'

function validateConfig() {
  const errors: string[] = []
  
  // Check required files
  const requiredFiles = [
    '.dcs/config.yaml',
    '.dcs/pages.yaml',
    '.env'
  ]
  
  for (const file of requiredFiles) {
    if (!existsSync(file)) {
      errors.push(`Missing required file: ${file}`)
    }
  }
  
  // Validate config.yaml
  if (existsSync('.dcs/config.yaml')) {
    const config = YAML.parse(readFileSync('.dcs/config.yaml', 'utf-8'))
    
    if (!config.site?.slug) {
      errors.push('Missing site.slug in config.yaml')
    }
    if (!config.api?.endpoint) {
      errors.push('Missing api.endpoint in config.yaml')
    }
  }
  
  if (errors.length > 0) {
    console.error('Configuration errors:')
    errors.forEach(e => console.error(`  - ${e}`))
    process.exit(1)
  }
  
  console.log('✓ Configuration valid')
}

validateConfig()

Next Steps

Duff Cloud Services Documentation