because I got bored of customising my CV for every job
README.md

Documentation Site#

This is the documentation site for the CV Generator project, built with React, Vite, and React Router.

Architecture#

The docs app follows a clean separation of concerns:

apps/docs/src/
├── components/          # UI components (presentation layer)
│   ├── DocPage.tsx     # Main documentation page component
│   ├── Sidebar.tsx     # Navigation sidebar
│   ├── Layout.tsx      # Page layout wrapper
│   └── MarkdownRenderer.tsx  # Markdown rendering logic
│
├── config/             # Configuration (content & structure)
│   ├── docs.config.ts  # Documentation content mapping
│   ├── navigation.config.ts  # Sidebar navigation structure
│   ├── env.config.ts   # Environment variable configuration
│   └── index.ts        # Barrel export
│
└── router/             # Application routing
    └── AppRouter.tsx

Design Principles#

  1. Separation of Concerns: Components render, configs define content/structure
  2. Single Responsibility: Each config file has one clear purpose
  3. Easy Maintenance: Add new docs by updating config files, not components

Features#

  • Markdown Rendering: Documentation is written in Markdown and rendered with syntax highlighting
  • Environment Variable Interpolation: Dynamic values are injected at runtime
  • Catppuccin Theme: Consistent design system with the main application
  • Hot Module Replacement: Changes to documentation update instantly
  • Configuration-Driven: Content and structure defined separately from UI components

Environment Variable Interpolation#

The documentation supports interpolating environment variables into markdown files at runtime. This allows for dynamic URLs and configuration values based on the deployment environment.

Usage#

In any markdown file, use double curly braces to reference an environment variable:

- **Client App**: [{{CLIENT_URL}}]({{CLIENT_URL}})
- **GraphQL Playground**: [{{GRAPHQL_URL}}]({{GRAPHQL_URL}})

Available Variables#

The following variables are available for interpolation:

Variable Default Value Description
CLIENT_URL http://localhost:5173 React client application URL
SERVER_URL http://localhost:3000 NestJS API server URL
DOCS_URL http://localhost:3001 Documentation site URL
GRAPHQL_URL http://localhost:3000/graphql GraphQL Playground URL
DB_HOST localhost Database host
DB_PORT 5432 Database port

Configuration#

Environment variables are configured in two places:

  1. Docker Compose (docker-compose.yml):

    docs:
      environment:
        VITE_CLIENT_URL: ${VITE_CLIENT_URL:-http://localhost:5173}
        VITE_SERVER_URL: ${VITE_SERVER_URL:-http://localhost:3000}
        # ... other variables
    
  2. Code (apps/docs/src/config/env.config.ts):

    export const ENV_VARS: Record<string, string> = {
      CLIENT_URL: import.meta.env.VITE_CLIENT_URL || "http://localhost:5173",
      SERVER_URL: import.meta.env.VITE_SERVER_URL || "http://localhost:3000",
      // ... other variables
    };
    

Adding New Variables#

To add a new interpolation variable:

  1. Add it to the ENV_VARS object in apps/docs/src/config/env.config.ts
  2. Add the corresponding VITE_* environment variable to docker-compose.yml
  3. Use it in markdown files with {{VARIABLE_NAME}}

How It Works#

The interpolation happens in env.config.ts using a simple regex replacement:

export const interpolateEnvVars = (content: string): string => {
  return content.replace(/\{\{(\w+)\}\}/g, (match, varName) => {
    return ENV_VARS[varName] ?? match;
  });
};

This ensures that:

  • Variables are replaced at render time (not build time)
  • Missing variables fall back to the placeholder text
  • The same markdown files work across different environments

Adding New Documentation#

To add a new documentation page:

  1. Create the markdown file in the appropriate location
  2. Import it in apps/docs/src/config/docs.config.ts:
    import myNewDocMd from "../../../../MY_NEW_DOC.md?raw";
    
  3. Add to the mapping:
    export const DOC_CONTENT: Record<string, string> = {
      // ... existing docs
      "my-new-doc": myNewDocMd,
    };
    
  4. Add navigation link in apps/docs/src/config/navigation.config.ts:
    export const DOC_LINKS: DocLink[] = [
      // ... existing links
      { title: "My New Doc", slug: "my-new-doc", icon: "📄" },
    ];
    

That's it! The UI components will automatically pick up the new documentation.

Development#

# Install dependencies
npm install

# Run development server
npm run dev

# Build for production
npm run build