DeployStack Frontend Development
The DeployStack frontend is a modern web application built with Vue 3, TypeScript, and Vite, specifically designed for managing MCP (Model Context Protocol) server deployments. This guide covers everything you need to know to develop and contribute to the frontend.
Technology Stack
- Framework: Vue 3 with Composition API
- Language: TypeScript for type safety
- Build Tool: Vite for fast development and building
- Styling: TailwindCSS with shadcn-vue components
- Icons: Lucide Icons
- Internationalization: Vue I18n
- State Management: Pinia (when needed)
- Routing: Vue Router
Quick Start
Prerequisites
- Node.js 18 or higher
- npm 8 or higher
Development Setup
-
Navigate to frontend directory:
cd services/frontend
-
Install dependencies:
npm install
-
Start development server:
npm run dev
-
Build for production:
npm run build
The development server will start at http://localhost:5173
with hot module replacement enabled.
Project Structure
services/frontend/
├── src/
│ ├── components/ # Reusable Vue components
│ ├── views/ # Page-level components
│ ├── router/ # Vue Router configuration
│ ├── stores/ # Pinia stores (state management)
│ ├── services/ # API services and utilities
│ ├── plugins/ # Frontend plugin system
│ ├── i18n/ # Internationalization files
│ ├── utils/ # Utility functions
│ ├── types/ # TypeScript type definitions
│ └── assets/ # Static assets
├── public/ # Public static files
├── dist/ # Built application (generated)
└── ...
Development Guidelines
Code Style
- Use TypeScript for all new code
- Follow Vue 3 Composition API patterns
- Use
<script setup>
syntax for components - Maintain consistent naming conventions
- Add proper TypeScript types for all functions and variables
Component Development
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
// Props with TypeScript
interface Props {
title: string
count?: number
}
const props = withDefaults(defineProps<Props>(), {
count: 0
})
// Composables
const { t } = useI18n()
// Reactive state
const isVisible = ref(true)
// Computed properties
const displayTitle = computed(() =>
`${props.title} (${props.count})`
)
// Methods
function toggleVisibility() {
isVisible.value = !isVisible.value
}
</script>
<template>
<div v-if="isVisible" class="component-container">
<h2 class="text-xl font-semibold">{{ displayTitle }}</h2>
<button
@click="toggleVisibility"
class="mt-2 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
>
{{ t('common.toggle') }}
</button>
</div>
</template>
UI Components and Styling
TailwindCSS Integration
The frontend uses TailwindCSS for styling with the shadcn-vue component library for consistent UI elements.
Installing New shadcn-vue Components
npx shadcn-vue@latest add button
npx shadcn-vue@latest add input
npx shadcn-vue@latest add dialog
Custom Component Example
<template>
<div class="p-6 bg-white rounded-lg shadow-md border">
<h3 class="text-lg font-semibold text-gray-900 mb-4">
MCP Server Status
</h3>
<div class="flex items-center space-x-2">
<div class="w-3 h-3 bg-green-500 rounded-full"></div>
<span class="text-sm text-gray-700">Running</span>
</div>
</div>
</template>
Icons
The project uses Lucide Icons through the lucide-vue-next
package.
Using Icons
<script setup lang="ts">
import { Mail, Lock, User, Settings, Play, Stop } from 'lucide-vue-next'
</script>
<template>
<div class="icon-examples">
<!-- Basic usage -->
<Mail class="h-4 w-4 text-gray-500" />
<!-- Different sizes -->
<Settings class="h-6 w-6" />
<!-- Different colors -->
<User class="text-indigo-600" />
<!-- Positioned icons -->
<div class="relative">
<input class="pl-10" />
<Lock class="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-500" />
</div>
<!-- Interactive icons -->
<button @click="toggleServer" class="flex items-center space-x-2">
<Play v-if="!isRunning" class="h-4 w-4" />
<Stop v-else class="h-4 w-4" />
<span>{{ isRunning ? 'Stop' : 'Start' }} Server</span>
</button>
</div>
</template>
Environment Configuration
The frontend supports environment variables for both development and production environments.
Development Environment
Create a .env
file in the services/frontend
directory:
VITE_API_URL=http://localhost:3000
VITE_APP_TITLE=DeployStack (Development)
VITE_ENABLE_DEBUG=true
Production Environment
Environment variables can be passed to the Docker container:
docker run -it -p 80:80 \
-e VITE_API_URL="https://api.deploystack.io" \
-e VITE_APP_TITLE="DeployStack" \
-e VITE_ENABLE_DEBUG="false" \
deploystack/frontend:latest
Accessing Environment Variables
Use the getEnv
utility function for consistent access:
import { getEnv } from '@/utils/env'
// In your components
const apiUrl = getEnv('VITE_API_URL')
const appTitle = getEnv('VITE_APP_TITLE')
const debugMode = getEnv('VITE_ENABLE_DEBUG') === 'true'
Adding New Environment Variables
- Add type definitions in
env.d.ts
:
interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_APP_TITLE: string
readonly VITE_ENABLE_DEBUG: string
readonly VITE_NEW_VARIABLE: string
}
interface Window {
RUNTIME_ENV?: {
VITE_API_URL?: string
VITE_APP_TITLE?: string
VITE_ENABLE_DEBUG?: string
VITE_NEW_VARIABLE?: string
// Non-VITE variables
CUSTOM_VAR?: string
}
}
- For non-VITE variables in Docker, update
env-config.sh
:
# Add specific non-VITE_ variables you want to expose
for var in CUSTOM_VAR OTHER_VAR; do
# Script logic here
done
API Integration
Service Layer Pattern
The frontend uses a service layer pattern for API communication:
// services/mcpServerService.ts
export class McpServerService {
private static baseUrl = getEnv('VITE_API_URL')
static async getAllServers(): Promise<McpServer[]> {
const response = await fetch(`${this.baseUrl}/api/mcp-servers`)
if (!response.ok) {
throw new Error('Failed to fetch MCP servers')
}
return response.json()
}
static async deployServer(serverId: string, config: DeployConfig): Promise<Deployment> {
const response = await fetch(`${this.baseUrl}/api/mcp-servers/${serverId}/deploy`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(config),
})
if (!response.ok) {
throw new Error('Failed to deploy MCP server')
}
return response.json()
}
}
Using Services in Components
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { McpServerService } from '@/services/mcpServerService'
import type { McpServer } from '@/types/mcp'
const servers = ref<McpServer[]>([])
const isLoading = ref(false)
const error = ref<string | null>(null)
async function fetchServers() {
isLoading.value = true
error.value = null
try {
servers.value = await McpServerService.getAllServers()
} catch (err) {
error.value = err instanceof Error ? err.message : 'Unknown error'
console.error('Failed to fetch servers:', err)
} finally {
isLoading.value = false
}
}
onMounted(() => {
fetchServers()
})
</script>
Next Steps
Continue reading the detailed guides:
- Internationalization (i18n) - Multi-language support
- Plugin System - Extending functionality
- Router Optimization - Performance improvements
- Contributing Guidelines - How to contribute
Docker Development
Building the Frontend
# Build the Docker image
docker build -t deploystack/frontend:dev .
# Run with development configuration
docker run -it -p 8080:80 \
-e VITE_API_URL="http://localhost:3000" \
-e VITE_APP_TITLE="DeployStack (Docker Dev)" \
deploystack/frontend:dev
Production Deployment
The frontend is designed to work seamlessly with the backend service:
# Production deployment
docker run -d -p 8080:80 \
-e VITE_API_URL="https://api.your-domain.com" \
-e VITE_APP_TITLE="DeployStack" \
deploystack/frontend:latest
Troubleshooting
Common Issues
- Build failures: Check Node.js and npm versions
- API connection issues: Verify
VITE_API_URL
environment variable - Styling issues: Ensure TailwindCSS is properly configured
- TypeScript errors: Run
npm run lint
to check for issues
Development Tips
- Use Vue DevTools browser extension for debugging
- Enable TypeScript strict mode in
tsconfig.json
- Use ESLint and Prettier for code consistency
- Test components in isolation when possible
Development Guide
Complete development documentation for DeployStack - covering frontend, backend, and contribution guidelines for the MCP server deployment platform.
Internationalization (i18n)
Guide to implementing multi-language support in DeployStack frontend using Vue I18n with modular file structure.