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/clientCreate Configuration Directory
bash
mkdir -p .dcsAdd 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: trueStep 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
| Type | Use Case | Notes |
|---|---|---|
static | Regular pages | User-editable content |
index | Collection pages | Blog index, etc. |
dynamic | Generated pages | Auto-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.comAdd 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 productionAdd 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 FreeStatic Web App (Production)
bash
az staticwebapp create \
--name customer-site-prod \
--resource-group dcs-sites-rg \
--location eastus2 \
--sku StandardConfigure Custom Domain (Production)
bash
az staticwebapp hostname set \
--name customer-site-prod \
--hostname www.customer-site.comStep 6: Register in DCS Portal
Create Site Record
- Log into the DCS admin portal
- Navigate to Sites → Add Site
- 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)
- Slug:
Assign to Company
- Navigate to Companies → Select Company
- Add site to company
- Set appropriate user permissions
Step 7: Verify Integration
Test Text Overrides
- Create a test override in the portal
- Verify it appears on the dev site
- Delete the test override
Test Development Requests
- Submit a test request
- Verify GitHub issue is created
- Verify Copilot response
- 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
- Check API endpoint in configuration
- Verify CORS settings on DCS server
- Check browser console for errors
Deployment failing
- Verify GitHub secrets are correct
- Check Azure SWA resource IDs
- Review workflow logs
GitHub integration issues
- Verify webhook configuration
- Check service principal permissions
- Review DCS server logs
Next Steps
- Site Configuration — Advanced configuration options
- Release Management — Managing deployments
- Portal Guide — Train site owners
