---
name: Harden
slug: harden
category: Frontend
description: Harden strengthens interfaces against long text, RTL and i18n issues, loading and error states, and edge cases. Use it when making a UI production-ready with better validation, overflow handling, and graceful recovery.
github: "https://github.com/AkaraChen/aghub/tree/main/.agents/skills/harden"
language: TypeScript
stars: 264
forks: 17
install: "npx degit https://github.com/AkaraChen/aghub/tree/main/.agents/skills/harden ~/.claude/skills/harden"
installs_to: ~/.claude/skills/harden
source_path: .agents/skills/harden/SKILL.md
collection_size: 25
category_size: 600
collection_url: "https://dirskills.com/collections/AkaraChen/aghub"
added: 2026-09-02T05:20:02.227Z
last_synced: 2026-09-02T05:20:02.227Z
canonical_url: "https://dirskills.com/skills/harden"
---

# Harden

Harden strengthens interfaces against long text, RTL and i18n issues, loading and error states, and edge cases. Use it when making a UI production-ready with better validation, overflow handling, and graceful recovery.

**Install:**

```bash
npx degit https://github.com/AkaraChen/aghub/tree/main/.agents/skills/harden ~/.claude/skills/harden
```

## README

Strengthen interfaces against edge cases, errors, internationalization issues, and real-world usage scenarios that break idealized designs.

## Assess Hardening Needs

Identify weaknesses and edge cases:

1. **Test with extreme inputs**:
    - Very long text (names, descriptions, titles)
    - Very short text (empty, single character)
    - Special characters (emoji, RTL text, accents)
    - Large numbers (millions, billions)
    - Many items (1000+ list items, 50+ options)
    - No data (empty states)

2. **Test error scenarios**:
    - Network failures (offline, slow, timeout)
    - API errors (400, 401, 403, 404, 500)
    - Validation errors
    - Permission errors
    - Rate limiting
    - Concurrent operations

3. **Test internationalization**:
    - Long translations (German is often 30% longer than English)
    - RTL languages (Arabic, Hebrew)
    - Character sets (Chinese, Japanese, Korean, emoji)
    - Date/time formats
    - Number formats (1,000 vs 1.000)
    - Currency symbols

**CRITICAL**: Designs that only work with perfect data aren't production-ready. Harden against reality.

## Hardening Dimensions

Systematically improve resilience:

### Text Overflow & Wrapping

**Long text handling**:

```css
/* Single line with ellipsis */
.truncate {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Multi-line with clamp */
.line-clamp {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Allow wrapping */
.wrap {
	word-wrap: break-word;
	overflow-wrap: break-word;
	hyphens: auto;
}
```

**Flex/Grid overflow**:

```css
/* Prevent flex items from overflowing */
.flex-item {
	min-width: 0; /* Allow shrinking below content size */
	overflow: hidden;
}

/* Prevent grid items from overflowing */
.grid-item {
	min-width: 0;
	min-height: 0;
}
```

**Responsive text sizing**:

- Use `clamp()` for fluid typography
- Set minimum readable sizes (14px on mobile)
- Test text scaling (zoom to 200%)
- Ensure containers expand with text

### Internationalization (i18n)

**Text expansion**:

- Add 30-40% space budget for translations
- Use flexbox/grid that adapts to content
- Test with longest language (usually German)
- Avoid fixed widths on text containers

```jsx
// ❌ Bad: Assumes short English text
<button className="w-24">Submit</button>

// ✅ Good: Adapts to content
<button className="px-4 py-2">Submit</button>
```

**RTL (Right-to-Left) support**:

```css
/* Use logical properties */
margin-inline-start: 1rem; /* Not margin-left */
padding-inline: 1rem; /* Not padding-left/right */
border-inline-end: 1px solid; /* Not border-right */

/* Or use dir attribute */
[dir="rtl"] .arrow {
	transform: scaleX(-1);
}
```

**Character set support**:

- Use UTF-8 encoding everywhere
- Test with Chinese/Japanese/Korean (CJK) characters
- Test with emoji (they can be 2-4 bytes)
- Handle different scripts (Latin, Cyrillic, Arabic, etc.)

**Date/Time formatting**:

```javascript
// ✅ Use Intl API for proper formatting
new Intl.DateTimeFormat("en-US").format(date); // 1/15/2024
new Intl.DateTimeFormat("de-DE").format(date); // 15.1.2024

new Intl.NumberFormat("en-US", {
	style: "currency",
	currency: "USD",
}).format(1234.56); // $1,234.56
```

**Pluralization**:

```javascript
// ❌ Bad: Assumes English pluralization
`${count} item${count !== 1 ? "s" : ""}`;

// ✅ Good: Use proper i18n library
t("items", { count }); // Handles complex plural rules
```

### Error Handling

**Network errors**:

- Show clear error messages
- Provide retry button
- Explain what happened
- Offer offline mode (if applicable)
- Handle timeout scenarios

```jsx
// Error states with recovery
{
	error && (
		<ErrorMessage>
			<p>Failed to load data. {error.message}</p>
			<button onClick={retry}>Try again</button>
		</ErrorMessage>
	);
}
```

**Form validation errors**:

- Inline errors near fields
- Clear, specific messages
- Suggest corrections
- Don't block submission unnecessarily
- Preserve user input on error

**API errors**:

- Handle each status code appropriately
    - 400: Show validation errors
    - 401: Redirect to login
    - 403: Show permission error
    - 404: Show not found state
    - 429: Show rate limit message
    - 500: Show generic error, offer support

**Graceful degradation**:

- Core functionality works without JavaScript
- Images have alt text
- Progressive enhancement
- Fallbacks for unsupported features

### Edge Cases & Boundary Conditions

**Empty states**:

- No items in list
- No search results
- No notifications
- No data to display
- Provide clear next action

**Loading states**:

- Initial load
- Pagination load
- Refresh
- Show what's loading ("Loading your projects...")
- Time estimates for long operations

**Large datasets**:

- Pagination or virtual scrolling
- Search/filter capabilities
- Performance optimization
- Don't load all 10,000 items at once

**Concurrent operations**:

- Prevent double-submission (disable button while loading)
- Handle race conditions
- Optimistic updates with rollback
- Conflict resolution

**Permission states**:

- No permission to view
- No permission to edit
- Read-only mode
- Clear explanation of why

**Browser compatibility**:

- Polyfills for modern features
- Fallbacks for unsupported CSS
- Feature detection (not browser detection)
- Test in target browsers

### Input Validation & Sanitization

**Client-side validation**:

- Required fields
- Format validation (email, phone, URL)
- Length limits
- Pattern matching
- Custom validation rules

**Server-side validation** (always):

- Never trust client-side only
- Validate and sanitize all inputs
- Protect against injection attacks
- Rate limiting

**Constraint handling**:

```html
<!-- Set clear constraints -->
<input
	type="text"
	maxlength="100"
	pattern="[A-Za-z0-9]+"
	required
	aria-describedby="username-hint"
/>
<small id="username-hint">
	Letters and numbers only, up to 100 characters
</small>
```

### Accessibility Resilience

**Keyboard navigation**:

- All functionality accessible via keyboard
- Logical tab order
- Focus management in modals
- Skip links for long content

**Screen reader support**:

- Proper ARIA labels
- Announce dynamic changes (live regions)
- Descriptive alt text
- Semantic HTML

**Motion sensitivity**:

```css
@media (prefers-reduced-motion: reduce) {
	* {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
}
```

**High contrast mode**:

- Test in Windows high contrast mode
- Don't rely only on color
- Provide alternative visual cues

### Performance Resilience

**Slow connections**:

- Progressive image loading
- Skeleton screens
- Optimistic UI updates
- Offline support (service workers)

**Memory leaks**:

- Clean up event listeners
- Cancel subscriptions
- Clear timers/intervals
- Abort pending requests on unmount

**Throttling & Debouncing**:

```javascript
// Debounce search input
const debouncedSearch = debounce(handleSearch, 300);

// Throttle scroll handler
const throttledScroll = throttle(handleScroll, 100);
```

## Testing Strategies

**Manual testing**:

- Test with extreme data (very long, very short, empty)
- Test in different languages
- Test offline
- Test slow connection (throttle to 3G)
- Test with screen reader
- Test keyboard-only navigation
- Test on old browsers

**Automated testing**:

- Unit tests for edge cases
- Integration tests for error scenarios
- E2E tests for critical paths
- Visual regression tests
- Accessibility tests (axe, WAVE)

**IMPORTANT**: Hardening is about expecting the unexpected. Real users will do things you never imagined.

**NEVER**:

- Assume perfect input (validate everything)
- Ignore internationalization (design for global)
- Leave error messages generic ("Error occurred")
- Forget offline scenarios
- Trust client-side validation alone
- Use fixed widths for text
- Assume English-length text
- Block entire interface when one component errors

## Verify Hardening

Test thoroughly with edge cases:

- **Long text**: Try names with 100+ characters
- **Emoji**: Use emoji in all text fields
- **RTL**: Test with Arabic or Hebrew
- **CJK**: Test with Chinese/Japanese/Korean
- **Network issues**: Disable internet, throttle connection
- **Large datasets**: Test with 1000+ items
- **Concurrent actions**: Click submit 10 times rapidly
- **Errors**: Force API errors, test all error states
- **Empty**: Remove all data, test empty states

Remember: You're hardening for production reality, not demo perfection. Expect users to input weird data, lose connection mid-flow, and use your product in unexpected ways. Build resilience into every component.
