Skip to content

Onboarding a New Site

Partner Documentation

This guide walks you through the complete process of adding a new customer site to DCS.

Prerequisites

Before starting, ensure you have:

  • [ ] A VitePress or compatible website
  • [ ] Access to the site's GitHub repository
  • [ ] Azure subscription with appropriate permissions
  • [ ] DCS partner account with admin access

Step 1: Prepare the Site Repository

Install DCS Dependencies

bash
pnpm add @dcs/client

Create Configuration Directory

bash
mkdir -p .dcs

Add DCS Configuration

Create .dcs/config.yaml:

yaml
site:
  slug: customer-site
  name: Customer Site Name

api:
  endpoint: https://portal.duffcloudservices.com/api

features:
  textOverrides: true
  seoMetadata: true
  blog: true
  analytics: true

Step 2: Implement Text Content Integration

Add the Composable

Create src/lib/use-text-content.ts:

typescript
import { ref, onMounted } from 'vue'

interface TextOverrides {
  [key: string]: string
}

const textOverrides = ref<TextOverrides>({})
const isLoading = ref(true)

export function useTextContent() {
  onMounted(async () => {
    if (Object.keys(textOverrides.value).length === 0) {
      await fetchOverrides()
    }
  })

  async function fetchOverrides() {
    try {
      const response = await fetch(
        `${import.meta.env.VITE_DCS_API}/sites/${import.meta.env.VITE_SITE_ID}/text-content`
      )
      if (response.ok) {
        textOverrides.value = await response.json()
      }
    } catch (error) {
      console.error('Failed to fetch text overrides:', error)
    } finally {
      isLoading.value = false
    }
  }

  function t(key: string, defaultValue: string): string {
    return textOverrides.value[key] ?? defaultValue
  }

  return { t, isLoading }
}

Use in Components

vue
<script setup lang="ts">
import { useTextContent } from '@/lib/use-text-content'

const { t } = useTextContent()
</script>

<template>
  <section class="hero">
    <h1>{{ t('home.hero.title', 'Welcome to Our Site') }}</h1>
    <p>{{ t('home.hero.subtitle', 'Building the future together') }}</p>
  </section>
</template>

Step 3: Register Pages

Create .dcs/pages.yaml:

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

  - slug: about
    path: /about
    type: static
    title: About Us
    deletable: true
    textKeys: []

  - slug: services
    path: /services
    type: static
    title: Services
    deletable: true
    textKeys: []

  - slug: contact
    path: /contact
    type: static
    title: Contact
    deletable: true
    textKeys: []

  - slug: blogs
    path: /blog
    type: index
    title: Blog
    deletable: false
    textKeys: []

Page Types

TypeUse CaseNotes
staticRegular pagesUser-editable content
indexCollection pagesBlog index, etc.
dynamicGenerated pagesAuto-created content

Step 4: Set Up GitHub Integration

Add Repository Secrets

In GitHub Settings → Secrets and variables → Actions:

AZURE_CLIENT_ID=<service-principal-id>
AZURE_CLIENT_SECRET=<service-principal-secret>
AZURE_TENANT_ID=<azure-tenant-id>
AZURE_SUBSCRIPTION_ID=<subscription-id>
DCS_SERVER_URL=https://portal.duffcloudservices.com

Add Copilot Instructions

Create .github/copilot-instructions.md:

markdown
# Copilot Instructions for [Site Name]

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

## Text Content
Use the `useTextContent` composable for all user-editable text:
\`\`\`vue
const { t } = useTextContent()
// t('key', 'default value')
\`\`\`

## Development Guidelines
- Follow Vue 3 Composition API patterns
- Use Tailwind CSS for styling
- Test changes in dev environment before production

Add Deployment Workflow

Create .github/workflows/draft-release-deploy.yml:

yaml
name: Draft Release Deploy

on:
  issues:
    types: [labeled]

jobs:
  deploy-draft:
    if: github.event.label.name == 'draft-release'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '22'
          
      - name: Install pnpm
        uses: pnpm/action-setup@v2
        with:
          version: 9
          
      - name: Install dependencies
        run: pnpm install
        
      - name: Build
        run: pnpm build
        
      - name: Deploy to Azure
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: ${{ secrets.AZURE_SWA_TOKEN }}
          action: 'upload'
          app_location: '.vitepress/dist'

Step 5: Create Azure Resources

Static Web App (Development)

bash
az staticwebapp create \
  --name customer-site-dev \
  --resource-group dcs-sites-rg \
  --location eastus2 \
  --sku Free

Static Web App (Production)

bash
az staticwebapp create \
  --name customer-site-prod \
  --resource-group dcs-sites-rg \
  --location eastus2 \
  --sku Standard

Configure Custom Domain (Production)

bash
az staticwebapp hostname set \
  --name customer-site-prod \
  --hostname www.customer-site.com

Step 6: Register in DCS Portal

Create Site Record

  1. Log into the DCS admin portal
  2. Navigate to Sites → Add Site
  3. Fill in site details:
    • Slug: customer-site
    • Name: Customer Site Name
    • GitHub Repo: owner/customer-site
    • Dev SWA Resource ID: (from Azure)
    • Prod SWA Resource ID: (from Azure)

Assign to Company

  1. Navigate to Companies → Select Company
  2. Add site to company
  3. Set appropriate user permissions

Step 7: Verify Integration

Test Text Overrides

  1. Create a test override in the portal
  2. Verify it appears on the dev site
  3. Delete the test override

Test Development Requests

  1. Submit a test request
  2. Verify GitHub issue is created
  3. Verify Copilot response
  4. Review and close test request

Onboarding Checklist

  • [ ] Site repository configured with DCS SDK
  • [ ] Text content composable implemented
  • [ ] Pages registered in .dcs/pages.yaml
  • [ ] GitHub secrets configured
  • [ ] Deployment workflows added
  • [ ] Azure SWA resources created
  • [ ] Site registered in DCS portal
  • [ ] Integration tested end-to-end
  • [ ] Site owner trained on portal usage

Troubleshooting

Text overrides not appearing

  1. Check API endpoint in configuration
  2. Verify CORS settings on DCS server
  3. Check browser console for errors

Deployment failing

  1. Verify GitHub secrets are correct
  2. Check Azure SWA resource IDs
  3. Review workflow logs

GitHub integration issues

  1. Verify webhook configuration
  2. Check service principal permissions
  3. Review DCS server logs

Next Steps

Duff Cloud Services Documentation