# Blockers (Website UX) This document defines **Blockers** as UX-only prevention mechanisms in the website. **IMPORTANT**: Blockers are **optional UX helpers**. They are NOT enforced by ESLint rules and do not belong in the strict architecture contract. Shared contract: [`docs/architecture/shared/BLOCKERS_AND_GUARDS.md`](docs/architecture/shared/BLOCKERS_AND_GUARDS.md:1) ## 1) Definition A Blocker is a website mechanism that prevents an action from being executed. Blockers exist solely to improve UX and reduce unnecessary requests. **Blockers are not security.** They are best-effort helpers that can be bypassed. ## 2) Purpose Use Blockers to: - Prevent multiple form submissions - Debounce rapid button clicks - Temporarily disable actions during loading - Show/hide UI elements based on state **Do NOT use Blockers for:** - Authorization checks - Security enforcement - Permanent access control ## 3) Placement Since Blockers are UX-only, they belong in: - `apps/website/components/**` (component-specific blockers) - `apps/website/hooks/**` (shared blocker hooks) - `apps/website/utils/**` (blocker utilities) **NOT in `lib/`** - `lib/` is for business logic and architecture contracts. ## 4) Example ```typescript // ✅ OK: Component-level blocker export function useSubmitBlocker() { const [isSubmitting, setIsSubmitting] = useState(false); return { isSubmitting, block: () => setIsSubmitting(true), release: () => setIsSubmitting(false), }; } // Usage const blocker = useSubmitBlocker(); async function handleSubmit() { if (blocker.isSubmitting) return; blocker.block(); await submitForm(); blocker.release(); } ``` ## 5) Key Principle **Blockers are optional.** The backend must never rely on them. If a blocker prevents a submission, the backend should still: - Validate the request - Return appropriate errors - Handle duplicate submissions gracefully This is why Blockers don't need ESLint enforcement - they're just UX sugar.