# No hardcoded localhost URLs in non-config source files

- **Pattern:** `ab-000264` (`ai-slop-half-finished.hardcoded-test-data.hardcoded-localhost-urls`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000264
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000264)

## Why it matters

A hardcoded `http://localhost:3000/api` or `ws://127.0.0.1:8080` in a shipped client works on exactly one machine: the developer's laptop. Every other environment — preview deploys, staging, production — fails as soon as the code runs, usually with opaque CORS or network errors. The defect often hides until after deploy because local dev still works, so it surfaces directly to users instead of in CI.

## Severity rationale

Low because the break is loud and usually caught quickly in preview, but it still reaches users when config files slip past review.

## Remediation

Read the base URL from environment variables and supply production-safe defaults. Put configuration in `.env.local` for dev and `.env.production` (or the platform's env panel) for deploy. Fix in `src/lib/api-client.ts`:

```ts
const API_URL = process.env.NEXT_PUBLIC_API_URL || '/api'
const WS_URL = process.env.NEXT_PUBLIC_WS_URL || 'wss://app.example.com/ws'
```

## Detection

- **ID:** `hardcoded-localhost-urls`
- **Severity:** `low`
- **What to look for:** Walk all source files EXCEPT those matching `**/config.*`, `**/.env*`, `**/*.test.*`, `**/*.spec.*`, `**/__tests__/**`, `**/dev.*`, `**/local.*`, `**/*.local.*`. Count all string literals matching these patterns: `http://localhost:`, `https://localhost:`, `http://127.0.0.1`, `https://127.0.0.1`, `http://0.0.0.0`, `ws://localhost`, `ws://127.0.0.1`. EXCLUDE literals inside conditional blocks guarded by `NODE_ENV === 'development'` or `process.env.NODE_ENV !== 'production'`.
- **Pass criteria:** 0 hardcoded localhost URLs in non-config, non-dev source files. Report: "Scanned X source files (excluding config and dev files), 0 hardcoded localhost URLs."
- **Fail criteria:** At least 1 non-config source file contains a hardcoded localhost URL that is not guarded by an environment check.
- **Skip (N/A) when:** Project has 0 non-config source files.
- **Detail on fail:** `"2 hardcoded localhost URLs: 'http://localhost:3000/api' in src/lib/api-client.ts line 5, 'ws://127.0.0.1:8080' in src/hooks/useWebSocket.ts line 12"`
- **Remediation:** Hardcoded localhost URLs break the moment the code runs anywhere except the original developer's laptop. Read the base URL from env:

  ```ts
  // Bad: only works on dev laptop
  const API_URL = 'http://localhost:3000/api'

  // Good: read from env with production fallback
  const API_URL = process.env.NEXT_PUBLIC_API_URL || '/api'
  ```

  For WebSockets, follow the same pattern with `NEXT_PUBLIC_WS_URL`.

---

Taxons: operational-readiness, placeholder-hygiene

HTML version: https://auditbuffet.com/patterns/ab-000264
