Skip to content

Latest commit

 

History

History
93 lines (73 loc) · 3.2 KB

File metadata and controls

93 lines (73 loc) · 3.2 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

# Development
pnpm dev          # Start dev server with Turbopack
pnpm build        # Build all packages
pnpm type-check   # Run TypeScript checks
pnpm lint         # Run linting
pnpm test         # Run tests (validates locales)

# Translation (only modify en/ files, CI auto-generates others)
pnpm --filter @onruntime/web translate        # Generate missing translations
pnpm --filter @onruntime/web translate:init   # Initialize all translations locally

# Run commands for specific package
pnpm --filter @onruntime/web dev
pnpm --filter @onruntime/translations build

Architecture

Monorepo Structure (Turborepo + pnpm workspaces)

/
├── apps/
│   └── web/              # Next.js 16 website (@onruntime/web)
├── packages/
│   ├── translations/     # i18n library (@onruntime/translations)
│   └── next-sitemap/     # Dynamic sitemap generation (@onruntime/next-sitemap)
├── turbo.json            # Turborepo configuration
└── pnpm-workspace.yaml   # pnpm workspace config

Web App Structure (apps/web/src/)

  • app/: Next.js App Router pages and API routes (under [locale]/)
  • components/: React components (ui/, layout/, marketing/)
  • services/: External API clients with lazy initialization
  • constants/: Static data (projects, agencies, services, team members)
  • content/: MDX content (glossary, legal pages)
  • lib/: Utilities and helpers
  • locales/: Translation files (see locales/README.md for conventions)
  • types/: TypeScript type definitions

Key Patterns

Services: Use lazy initialization for external API clients to avoid build failures when env vars are missing in CI:

// services/email.ts - Proxy pattern for lazy init
export const resend = new Proxy({} as Resend, {
  get(_, prop) {
    if (!instance) {
      instance = new Resend(env.RESEND_API_KEY);
    }
    return instance[prop as keyof Resend];
  },
});

// services/join.ts - Client pattern
export const joinClient = {
  async jobs() { ... },
  async job(id) { ... },
};

Environment Variables: Managed via @t3-oss/env-nextjs in env.ts. Validation is skipped in CI (skipValidation: !!process.env.CI).

API Routes: Use unstable_cache from Next.js for caching external API responses.

Translations: Uses @onruntime/translations package. Only edit files in locales/en/ - other locales are auto-generated by CI. Namespace path matches file path from locales/{locale}/.

// Server Components
import { getTranslation } from "@/lib/translations.server";
const { t } = await getTranslation("layout/footer");

// Client Components
import { useTranslation } from "@onruntime/translations/react";
const { t } = useTranslation("layout/footer");

See apps/web/src/locales/README.md for full naming conventions and usage patterns.

Environment Variables

Required for runtime (optional for build due to skipValidation in CI):

  • RESEND_API_KEY: Email sending via Resend
  • JOIN_API_KEY: Job listings from join.com API
  • NEXT_PUBLIC_APP_URL: App URL (defaults to https://onruntime.com)