harden.md

  1Designs that only work with perfect data aren't production-ready. Harden the interface against the inputs, errors, languages, and network conditions that real users will throw at it.
  2
  3## Assess Hardening Needs
  4
  5Identify weaknesses and edge cases:
  6
  71. **Test with extreme inputs**:
  8   - Very long text (names, descriptions, titles)
  9   - Very short text (empty, single character)
 10   - Special characters (emoji, RTL text, accents)
 11   - Large numbers (millions, billions)
 12   - Many items (1000+ list items, 50+ options)
 13   - No data (empty states)
 14
 152. **Test error scenarios**:
 16   - Network failures (offline, slow, timeout)
 17   - API errors (400, 401, 403, 404, 500)
 18   - Validation errors
 19   - Permission errors
 20   - Rate limiting
 21   - Concurrent operations
 22
 233. **Test internationalization**:
 24   - Long translations (German is often 30% longer than English)
 25   - RTL languages (Arabic, Hebrew)
 26   - Character sets (Chinese, Japanese, Korean, emoji)
 27   - Date/time formats
 28   - Number formats (1,000 vs 1.000)
 29   - Currency symbols
 30
 31**CRITICAL**: Designs that only work with perfect data aren't production-ready. Harden against reality.
 32
 33## Hardening Dimensions
 34
 35Systematically improve resilience:
 36
 37### Text Overflow & Wrapping
 38
 39**Long text handling**:
 40```css
 41/* Single line with ellipsis */
 42.truncate {
 43  overflow: hidden;
 44  text-overflow: ellipsis;
 45  white-space: nowrap;
 46}
 47
 48/* Multi-line with clamp */
 49.line-clamp {
 50  display: -webkit-box;
 51  -webkit-line-clamp: 3;
 52  -webkit-box-orient: vertical;
 53  overflow: hidden;
 54}
 55
 56/* Allow wrapping */
 57.wrap {
 58  word-wrap: break-word;
 59  overflow-wrap: break-word;
 60  hyphens: auto;
 61}
 62```
 63
 64**Flex/Grid overflow**:
 65```css
 66/* Prevent flex items from overflowing */
 67.flex-item {
 68  min-width: 0; /* Allow shrinking below content size */
 69  overflow: hidden;
 70}
 71
 72/* Prevent grid items from overflowing */
 73.grid-item {
 74  min-width: 0;
 75  min-height: 0;
 76}
 77```
 78
 79**Responsive text sizing**:
 80- Use `clamp()` for fluid typography
 81- Set minimum readable sizes (14px on mobile)
 82- Test text scaling (zoom to 200%)
 83- Ensure containers expand with text
 84
 85### Internationalization (i18n)
 86
 87**Text expansion**:
 88- Add 30-40% space budget for translations
 89- Use flexbox/grid that adapts to content
 90- Test with longest language (usually German)
 91- Avoid fixed widths on text containers
 92
 93```jsx
 94// ❌ Bad: Assumes short English text
 95<button className="w-24">Submit</button>
 96
 97// ✅ Good: Adapts to content
 98<button className="px-4 py-2">Submit</button>
 99```
100
101**RTL (Right-to-Left) support**:
102```css
103/* Use logical properties */
104margin-inline-start: 1rem; /* Not margin-left */
105padding-inline: 1rem; /* Not padding-left/right */
106border-inline-end: 1px solid; /* Not border-right */
107
108/* Or use dir attribute */
109[dir="rtl"] .arrow { transform: scaleX(-1); }
110```
111
112**Character set support**:
113- Use UTF-8 encoding everywhere
114- Test with Chinese/Japanese/Korean (CJK) characters
115- Test with emoji (they can be 2-4 bytes)
116- Handle different scripts (Latin, Cyrillic, Arabic, etc.)
117
118**Date/Time formatting**:
119```javascript
120// ✅ Use Intl API for proper formatting
121new Intl.DateTimeFormat('en-US').format(date); // 1/15/2024
122new Intl.DateTimeFormat('de-DE').format(date); // 15.1.2024
123
124new Intl.NumberFormat('en-US', { 
125  style: 'currency', 
126  currency: 'USD' 
127}).format(1234.56); // $1,234.56
128```
129
130**Pluralization**:
131```javascript
132// ❌ Bad: Assumes English pluralization
133`${count} item${count !== 1 ? 's' : ''}`
134
135// ✅ Good: Use proper i18n library
136t('items', { count }) // Handles complex plural rules
137```
138
139### Error Handling
140
141**Network errors**:
142- Show clear error messages
143- Provide retry button
144- Explain what happened
145- Offer offline mode (if applicable)
146- Handle timeout scenarios
147
148```jsx
149// Error states with recovery
150{error && (
151  <ErrorMessage>
152    <p>Failed to load data. {error.message}</p>
153    <button onClick={retry}>Try again</button>
154  </ErrorMessage>
155)}
156```
157
158**Form validation errors**:
159- Inline errors near fields
160- Clear, specific messages
161- Suggest corrections
162- Don't block submission unnecessarily
163- Preserve user input on error
164
165**API errors**:
166- Handle each status code appropriately
167  - 400: Show validation errors
168  - 401: Redirect to login
169  - 403: Show permission error
170  - 404: Show not found state
171  - 429: Show rate limit message
172  - 500: Show generic error, offer support
173
174**Graceful degradation**:
175- Core functionality works without JavaScript
176- Images have alt text
177- Progressive enhancement
178- Fallbacks for unsupported features
179
180### Edge Cases & Boundary Conditions
181
182**Empty states**:
183- No items in list
184- No search results
185- No notifications
186- No data to display
187- Provide clear next action
188
189**Loading states**:
190- Initial load
191- Pagination load
192- Refresh
193- Show what's loading ("Loading your projects...")
194- Time estimates for long operations
195
196**Large datasets**:
197- Pagination or virtual scrolling
198- Search/filter capabilities
199- Performance optimization
200- Don't load all 10,000 items at once
201
202**Concurrent operations**:
203- Prevent double-submission (disable button while loading)
204- Handle race conditions
205- Optimistic updates with rollback
206- Conflict resolution
207
208**Permission states**:
209- No permission to view
210- No permission to edit
211- Read-only mode
212- Clear explanation of why
213
214**Browser compatibility**:
215- Polyfills for modern features
216- Fallbacks for unsupported CSS
217- Feature detection (not browser detection)
218- Test in target browsers
219
220### Input Validation & Sanitization
221
222**Client-side validation**:
223- Required fields
224- Format validation (email, phone, URL)
225- Length limits
226- Pattern matching
227- Custom validation rules
228
229**Server-side validation** (always):
230- Never trust client-side only
231- Validate and sanitize all inputs
232- Protect against injection attacks
233- Rate limiting
234
235**Constraint handling**:
236```html
237<!-- Set clear constraints -->
238<input 
239  type="text"
240  maxlength="100"
241  pattern="[A-Za-z0-9]+"
242  required
243  aria-describedby="username-hint"
244/>
245<small id="username-hint">
246  Letters and numbers only, up to 100 characters
247</small>
248```
249
250### Accessibility Resilience
251
252**Keyboard navigation**:
253- All functionality accessible via keyboard
254- Logical tab order
255- Focus management in modals
256- Skip links for long content
257
258**Screen reader support**:
259- Proper ARIA labels
260- Announce dynamic changes (live regions)
261- Descriptive alt text
262- Semantic HTML
263
264**Motion sensitivity**:
265```css
266@media (prefers-reduced-motion: reduce) {
267  * {
268    animation-duration: 0.01ms !important;
269    animation-iteration-count: 1 !important;
270    transition-duration: 0.01ms !important;
271  }
272}
273```
274
275**High contrast mode**:
276- Test in Windows high contrast mode
277- Don't rely only on color
278- Provide alternative visual cues
279
280### Performance Resilience
281
282**Slow connections**:
283- Progressive image loading
284- Skeleton screens
285- Optimistic UI updates
286- Offline support (service workers)
287
288**Memory leaks**:
289- Clean up event listeners
290- Cancel subscriptions
291- Clear timers/intervals
292- Abort pending requests on unmount
293
294**Throttling & Debouncing**:
295```javascript
296// Debounce search input
297const debouncedSearch = debounce(handleSearch, 300);
298
299// Throttle scroll handler
300const throttledScroll = throttle(handleScroll, 100);
301```
302
303## Testing Strategies
304
305**Manual testing**:
306- Test with extreme data (very long, very short, empty)
307- Test in different languages
308- Test offline
309- Test slow connection (throttle to 3G)
310- Test with screen reader
311- Test keyboard-only navigation
312- Test on old browsers
313
314**Automated testing**:
315- Unit tests for edge cases
316- Integration tests for error scenarios
317- E2E tests for critical paths
318- Visual regression tests
319- Accessibility tests (axe, WAVE)
320
321**IMPORTANT**: Hardening is about expecting the unexpected. Real users will do things you never imagined.
322
323**NEVER**:
324- Assume perfect input (validate everything)
325- Ignore internationalization (design for global)
326- Leave error messages generic ("Error occurred")
327- Forget offline scenarios
328- Trust client-side validation alone
329- Use fixed widths for text
330- Assume English-length text
331- Block entire interface when one component errors
332
333## Verify Hardening
334
335Test thoroughly with edge cases:
336
337- **Long text**: Try names with 100+ characters
338- **Emoji**: Use emoji in all text fields
339- **RTL**: Test with Arabic or Hebrew
340- **CJK**: Test with Chinese/Japanese/Korean
341- **Network issues**: Disable internet, throttle connection
342- **Large datasets**: Test with 1000+ items
343- **Concurrent actions**: Click submit 10 times rapidly
344- **Errors**: Force API errors, test all error states
345- **Empty**: Remove all data, test empty states
346
347When edge cases are covered, hand off to `/impeccable polish` for the final pass.