# Frontend Development Guide

**Last Updated**: 2026-03-29

Complete guide to local development workflows, common tasks, debugging, and troubleshooting for the Semiont frontend.

## Table of Contents

- [Local Development with Semiont CLI](#local-development-with-semiont-cli)
- [Manual Development Setup](#manual-development-setup)
- [Common Development Tasks](#common-development-tasks)
- [Environment Variables](#environment-variables)
- [Debugging Tips](#debugging-tips)
- [Common Troubleshooting](#common-troubleshooting)
- [Code Style Guidelines](#code-style-guidelines)
- [CSS and Styling Workflow](#css-and-styling-workflow)
- [Related Documentation](#related-documentation)

## Local Development with Semiont CLI

The recommended way to develop the frontend is using the Semiont CLI, which automatically manages dependencies and environment configuration.

###Essential Commands

```bash
# Set your environment once
export SEMIONT_ENV=local

# Full stack development
semiont start              # Start everything (database + backend + frontend)
semiont start --force      # Fresh start with clean database
semiont stop               # Stop all services
semiont check              # Check service health

# Frontend development
semiont start --service frontend  # Start frontend only
semiont stop --service frontend   # Stop frontend service

# Backend + database
semiont start --service backend   # Start backend only
semiont start --service database  # Start database only
semiont restart --service backend # Restart backend with fresh connection
```

### Development Modes

**1. Full Stack Development** (`semiont start`)
- Complete development environment in one command
- PostgreSQL container with schema applied automatically
- Backend API with database connection
- Frontend with real API integration
- **Perfect for full-stack feature development**

**2. Frontend-Only Development** (`semiont start --service frontend`)
- Start just the frontend service
- Configure mock API in environment settings if needed
- Fast iteration for UI/UX work
- **Perfect for component development and styling**

**3. Backend-Connected Development** (`semiont start --service backend,frontend`)
- Start backend and frontend together
- Real API integration
- **Perfect for testing API integration**

**4. Manual Development** (`npm run dev` - traditional approach)
- Requires manual backend/database setup
- Full control over environment configuration
- **For developers who prefer manual environment management**

### Why Use Semiont CLI for Frontend?

- **Smart Dependencies**: Frontend auto-starts backend when needed
- **Consistent Environment**: Everyone gets identical setup
- **Zero Configuration**: No environment files, API URLs, or manual setup
- **No Separate Install**: `@semiont/frontend` is bundled with the CLI — `semiont provision` just creates runtime directories
- **Easy Reset**: Fresh database with sample data via `--reset`
- **Focused Development**: Mock mode for UI work, real API mode for integration
- **Container Runtime Flexibility**: Works with Apple Container, Docker, or Podman (auto-detected)

### Development Workflow with Semiont CLI

**First time setup** (run once):
```bash
cd /your/project/root
npm install  # Installs dependencies for all apps
semiont init --name "my-project"  # Initialize configuration
export SEMIONT_ENV=local  # Set default environment
```

**Frontend-focused development** (UI/UX work):
```bash
semiont start --service frontend
# Only frontend running (configure mock API in environment if needed)
# Perfect for component development, styling, layout work
```

**Full-stack development** (feature work):
```bash
semiont start
# Complete environment: database + backend + frontend
# Perfect for implementing features that need real API integration
```

**Backend integration testing**:
```bash
semiont start --service backend,frontend
# Frontend + real backend + database
# Perfect for testing API integration without manual backend setup
```

**Fresh start** (reset data):
```bash
semiont restart --force
# Clean restart with fresh connections
# Perfect when you need to reset state
```

## Manual Development Setup

If you prefer manual setup or need to understand the internals:

### Development Modes (Manual)

**1. Standard Development** (`npm run dev`)
- Uses Vite dev server with hot reload
- Requires backend API running on port 3001

**2. Mock API Development** (`npm run dev:mock`) - Recommended for UI work
- Starts mock API server on port 3001
- No backend dependencies needed
- Perfect for rapid UI/UX iteration

**3. Fast Mode** (`npm run dev:fast`)
- Vite dev server with favicons and PDF.js pre-copied
- Requires backend API running separately

### Fast Iteration Features

- **Hot Module Replacement (HMR)** - Changes update instantly without losing state
- **Fast Refresh** - Error recovery without losing component state
- **Mock API Server** - Pre-configured endpoints for common operations
- **TypeScript Path Aliases** - Use `@/components` instead of relative imports

### Mock API Endpoints

The mock server (`npm run dev:mock`) provides:
- `/api/health` - Health check endpoint
- `/api/auth/session` - Mock authentication state
- `/api/admin/stats` - Dashboard statistics
- `/api/admin/users` - User management data

### Tips for Faster Development

1. **Component Playground** - Create `src/app/playground/page.tsx` for isolated component testing
2. **Disable Type Checking** (temporarily run tsc without --noEmit checks)
3. **Clear Cache** - Run `rm -rf node_modules/.vite` if experiencing stale module issues
4. **VS Code Integration** - Use Command Palette (`Cmd+Shift+P`) for quick file navigation

## Common Development Tasks

### Adding a New Page

**1. Create page component** in `src/app/[route]/page.tsx`:
```typescript
// src/app/dashboard/page.tsx
import { AsyncErrorBoundary } from "@/components/ErrorBoundary";
import { DashboardContent } from "@/components/DashboardContent";

export default function Dashboard() {
  return (
    <main className="container mx-auto px-4 py-8">
      <AsyncErrorBoundary>
        <DashboardContent />
      </AsyncErrorBoundary>
    </main>
  );
}
```

**2. Create component** in `src/components/`:
```typescript
// src/components/DashboardContent.tsx
import { api } from "@/lib/api-client";
import { useKnowledgeBaseSession } from "@semiont/react-ui";

export function DashboardContent() {
  const { isFullyAuthenticated } = useKnowledgeBaseSession();
  const { data, isLoading, error } = api.dashboard.getData.useQuery();

  if (!isFullyAuthenticated) {
    return <div>Please sign in to view dashboard</div>;
  }

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h1>Dashboard</h1>
      {/* Your dashboard content */}
    </div>
  );
}
```

### Adding New API Integration

See [API Integration Guide](./API-INTEGRATION.md) for complete details.

**Quick example**:
```typescript
// 1. Define types in src/lib/api-client.ts
interface DashboardDataResponse {
  metrics: {
    activeUsers: number;
    totalPosts: number;
    systemStatus: string;
  };
  recentActivity: Activity[];
}

// 2. Add API service method
export const apiService = {
  dashboard: {
    getData: (): Promise<DashboardDataResponse> =>
      apiClient.get('/api/dashboard/data'),
  },
};

// 3. Add React Query hook
export const api = {
  dashboard: {
    getData: {
      useQuery: () => {
        return useQuery({
          queryKey: ['dashboard.data'],
          queryFn: () => apiService.dashboard.getData(),
          enabled: !!useKnowledgeBaseSession().isFullyAuthenticated,
        });
      }
    }
  }
};
```

### Adding New UI Components

**1. Create component** in `src/components/`:
```typescript
// src/components/MetricsCard.tsx
import { ReactNode } from 'react';

interface MetricsCardProps {
  title: string;
  value: string | number;
  icon?: ReactNode;
  trend?: 'up' | 'down' | 'neutral';
  className?: string;
}

export function MetricsCard({
  title,
  value,
  icon,
  trend = 'neutral',
  className = ''
}: MetricsCardProps) {
  const trendColors = {
    up: 'text-green-600',
    down: 'text-red-600',
    neutral: 'text-gray-600'
  };

  return (
    <div className={`bg-white rounded-lg shadow p-6 ${className}`}>
      <div className="flex items-center justify-between">
        <div>
          <p className="text-sm font-medium text-gray-600">{title}</p>
          <p className={`text-2xl font-semibold ${trendColors[trend]}`}>
            {value}
          </p>
        </div>
        {icon && (
          <div className="text-gray-400">
            {icon}
          </div>
        )}
      </div>
    </div>
  );
}
```

**2. Use with error boundary**:
```typescript
<AsyncErrorBoundary>
  <MetricsCard
    title="Active Users"
    value={dashboardData?.metrics.activeUsers ?? 0}
    trend="up"
  />
</AsyncErrorBoundary>
```

### Adding Custom Hooks

**Create hook** in `src/hooks/`:
```typescript
// src/hooks/useLocalStorage.ts
import { useState, useEffect } from 'react';

export function useLocalStorage<T>(key: string, initialValue: T) {
  const [storedValue, setStoredValue] = useState<T>(initialValue);

  useEffect(() => {
    try {
      const item = window.localStorage.getItem(key);
      if (item) {
        setStoredValue(JSON.parse(item));
      }
    } catch (error) {
      console.warn(`Error reading localStorage key "${key}":`, error);
    }
  }, [key]);

  const setValue = (value: T | ((val: T) => T)) => {
    try {
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      console.warn(`Error setting localStorage key "${key}":`, error);
    }
  };

  return [storedValue, setValue] as const;
}
```

### Adding Authentication Guards

**1. Create protected route wrapper**:
```typescript
// src/components/ProtectedRoute.tsx
"use client";

import { useKnowledgeBaseSession } from "@semiont/react-ui";
import { useRouter } from "@/i18n/routing";
import { useEffect } from "react";

interface ProtectedRouteProps {
  children: React.ReactNode;
  requireFullAuth?: boolean;
}

export function ProtectedRoute({
  children,
  requireFullAuth = false
}: ProtectedRouteProps) {
  const { isAuthenticated, isFullyAuthenticated, isLoading } = useKnowledgeBaseSession();
  const router = useRouter();

  useEffect(() => {
    if (!isLoading) {
      const hasRequiredAuth = requireFullAuth ? isFullyAuthenticated : isAuthenticated;

      if (!hasRequiredAuth) {
        router.push('/auth/signin');
      }
    }
  }, [isAuthenticated, isFullyAuthenticated, isLoading, requireFullAuth, router]);

  if (isLoading) {
    return <div className="flex justify-center p-8">Loading...</div>;
  }

  const hasRequiredAuth = requireFullAuth ? isFullyAuthenticated : isAuthenticated;

  return hasRequiredAuth ? <>{children}</> : null;
}
```

**2. Use in protected pages**:
```typescript
// src/app/admin/page.tsx
import { ProtectedRoute } from "@/components/ProtectedRoute";

export default function AdminPage() {
  return (
    <ProtectedRoute requireFullAuth={true}>
      <AdminContent />
    </ProtectedRoute>
  );
}
```

## Environment Variables

Environment variables are configured automatically based on your environment configuration files in `/config/environments/`.

**1. Add to environment JSON** in `/config/environments/[env].json`:
```json
{
  "services": {
    "frontend": {
      "url": "https://staging.example.com",
      "port": 3000
    }
  }
}
```

**2. Access in code** via validation schema in `src/lib/env.ts`:
```typescript
const envSchema = z.object({
  SEMIONT_BACKEND_URL: z.string().url(),
});
```

**3. Deployment**: Environment variables are set automatically during deployment based on your configuration.

## Debugging Tips

### Authentication Issues
- Check browser dev tools Network tab
- Verify httpOnly JWT cookie in Application tab > Cookies
- Check /api/auth/me response for current session state
- Verify backend is running and accessible

### API Errors
- Review browser Network tab for failed requests
- Check API client error handling in console
- Verify backend is running and accessible
- Check CORS configuration

### Performance Issues
- Use `npm run analyze` to identify large bundles
- Review React DevTools Profiler
- Monitor Network waterfall in dev tools

### Build Errors
- Run `npm run type-check` to identify TypeScript errors
- Verify all environment variables are set
- Check for unused imports or missing dependencies
- Clear Vite cache: `rm -rf node_modules/.vite`

### Runtime Errors
- Error boundaries capture detailed error information
- Check browser console for stack traces
- Review error boundary fallback UI
- Enable React strict mode for dev warnings

## Common Troubleshooting

### "API calls failing"
**Symptoms**: 404 or network errors when making API requests

**Solutions**:
- Verify `SEMIONT_BACKEND_URL` is set correctly
- Check network tab for CORS issues
- Ensure backend is running and accessible
- Verify API endpoint path is correct
- Check authentication token is included

### "Authentication not working"
**Symptoms**: Unable to sign in or session not persisting

**Solutions**:
- Check backend logs for OAuth errors
- Verify httpOnly cookie is being set (Application tab in devtools)
- Check /api/auth/me returns correct user data
- Ensure OAuth callback URL in Google Cloud Console points to backend (/api/auth/oauth/google/callback)

### "Build failing"
**Symptoms**: `npm run build` fails with errors

**Solutions**:
- Run `npm run type-check` to identify TypeScript errors
- Verify all environment variables are set
- Check for unused imports or missing dependencies
- Update dependencies: `npm update`
- Clear node_modules and reinstall: `rm -rf node_modules && npm install`

### "Performance issues"
**Symptoms**: Slow page loads, large bundle size

**Solutions**:
- Run `npm run perf` to identify bottlenecks
- Check bundle size with `npm run analyze`
- Implement code splitting with dynamic imports
- Optimize images (use appropriate sizes, lazy loading)

### "Hot reload not working"
**Symptoms**: Changes not reflecting in browser

**Solutions**:
- Check for syntax errors in console
- Restart dev server: `npm run dev`
- Clear Vite cache: `rm -rf node_modules/.vite`
- Check file watcher limits on Linux: `echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf`

## Code Style Guidelines

### Functional Programming

**Functional, side-effect free code is strongly preferred**:
- Use functional components with hooks
- Avoid class components and mutations
- Prefer pure functions
- Use immutable data structures
- Avoid side effects in business logic

### Component Patterns

- Use descriptive component and variable names
- Follow existing patterns in the codebase
- Prefer composition over inheritance
- Extract reusable logic into custom hooks
- Use error boundaries for error handling

### Documentation

- No unnecessary comments - code should be self-documenting
- Add JSDoc for complex functions
- Document non-obvious business logic
- Keep README and docs up to date

### TypeScript

- Enable strict mode
- Avoid `any` type
- Use type inference where possible
- Define interfaces for props and data structures
- Use const assertions for literal types

## CSS and Styling Workflow

The frontend uses a **hybrid CSS architecture** combining semantic CSS from @semiont/react-ui with Tailwind for app-specific styling.

### When to Use Which System

#### Use @semiont/react-ui Components (Semantic CSS)
When the component exists in @semiont/react-ui, use it directly:

```tsx
import { Button, Card, Toolbar } from '@semiont/react-ui';

// These come with semantic CSS classes pre-applied
<Button variant="primary">Click me</Button>
<Card>
  <Card.Header>Title</Card.Header>
  <Card.Content>Content</Card.Content>
</Card>
```

**Benefits:**
- Consistent styling across the application
- Framework-agnostic (no Tailwind dependency)
- Built-in accessibility features
- Managed dark mode support

#### Use Tailwind for App-Specific Components
For components unique to the frontend application:

```tsx
// App-specific layout component
<div className="flex items-center gap-4 p-6 bg-white dark:bg-gray-800">
  <span className="text-lg font-semibold">Custom content</span>
</div>
```

**Use Tailwind for:**
- Page layouts and containers
- Custom components not in @semiont/react-ui
- Spacing and positioning utilities
- One-off styling needs

### Combining Both Systems

When you need to add spacing or layout to @semiont/react-ui components:

```tsx
// Good - adds spacing without breaking component styles
<Button variant="primary" className="mt-4">
  Submit
</Button>

// Bad - overriding semantic classes
<Button variant="primary" className="bg-blue-500 hover:bg-blue-600">
  Submit
</Button>
```

### CSS Import Structure

The CSS is imported in `src/app/globals.css`:

```css
/* Tailwind */
@import "tailwindcss";

/* Import all @semiont/react-ui styles */
@import '@semiont/react-ui/styles';
```

### Dark Mode Coordination

- **@semiont/react-ui**: Uses `data-theme="dark"` attribute
- **Tailwind**: Uses `class="dark"` on HTML element
- Both are coordinated by the theme provider

### Style File Locations

- **App-specific styles:** `/src/lib/button-styles.ts`, `/src/lib/annotation-styles.ts`
- **Global styles:** `/src/app/globals.css`
- **Component library styles:** `@semiont/react-ui/styles` (imported automatically)

### Development Tips

1. **Check @semiont/react-ui first** - Before creating a custom component
2. **Use semantic classes** - Don't override @semiont/react-ui styles
3. **Test dark mode** - Ensure both systems work in dark mode
4. **Keep separation clear** - Components vs. layout utilities

For detailed styling guidelines, see the [Style Guide](./style-guide.md).

## Related Documentation

### Development Guides
- [Testing Guide](./TESTING.md) - Test structure, running tests, writing tests
- [API Integration](./API-INTEGRATION.md) - API client usage, async operations
- [Performance](./PERFORMANCE.md) - Bundle optimization, monitoring
- [Deployment](./DEPLOYMENT.md) - Publishing and deployment workflows

### Architecture
- [Frontend Architecture](./ARCHITECTURE.md) - High-level system design
- [Rendering Architecture](../../../packages/react-ui/docs/RENDERING-ARCHITECTURE.md) - Document rendering pipeline
- [Authentication](./AUTHENTICATION.md) - OAuth, JWT, session management

### Features
- [Annotations](./ANNOTATIONS.md) - W3C annotation system
- [Style Guide](./style-guide.md) - UI/UX patterns
- [Keyboard Navigation](./KEYBOARD-NAV.md) - Keyboard navigation implementation
- [Accessibility](./ACCESSIBILITY.md) - WCAG 2.1 AA implementation patterns

### System Documentation
- [System Documentation](../../../docs/system/README.md) - Overall platform
- [Backend README](../../backend/README.md) - Backend API
- [CLI README](../../cli/README.md) - CLI usage

---

**Last Updated**: 2026-03-29
**For Questions**: See [System Documentation](../../../docs/) or file an issue
