Skip to content
Back to skills

Pf I18n Audit

ASecurity

Audit PatternFly React code for i18n readiness — hardcoded user-facing strings, concatenation anti-patterns, locale-dependent formatting, and RTL-unsafe CSS. Use when reviewing code for global deployment or auditing i18n compliance.

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 21, 2026
designrustgoreactapidocumentation

Works with

  • api

Security analysis

A100/100

Pro scans all 14 files and shows the line behind each finding

Scanned September 21, 2026

npx -y skills add rh-uxd/ai-helpers --skill pf-i18n-audit --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Pf I18n Audit?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Pf I18n Audit
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rh-uxd-pf-i18n-audit/badge)](https://www.skillsdirectory.com/skills/rh-uxd-pf-i18n-audit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: pf-i18n-audit
description: Audit PatternFly React code for i18n readiness — hardcoded user-facing strings, concatenation anti-patterns, locale-dependent formatting, and RTL-unsafe CSS. Use when reviewing code for global deployment or auditing i18n compliance.
---

# PF i18n Audit

Audit PatternFly React components for internationalization readiness. All Red Hat products ship globally — OpenShift, HCC, and Ansible all require comprehensive i18n. This skill finds hardcoded strings, unsafe formatting, and RTL layout issues before they become translation bugs.

## PatternFly API documentation

If PatternFly documentation tools are available, use them to verify component text props and layout behavior before flagging. Without documentation available, rely on the anti-pattern rules and tables in this skill.

## Input

The user provides a directory, file path, or set of components to audit. Default to the current working directory. Limit scope to `.tsx`, `.jsx`, `.ts`, and `.css`/`.scss` files.

## What to audit

### 1. Hardcoded user-facing strings

Flag string literals rendered in UI components that should be externalized for translation.

**Flag these:**
- String literals in PF text surfaces: `Title`, `Content`, `Alert` title, `EmptyState` titleText, `Label`, `Badge`, `Tooltip` content, `Button` children, `FormGroup` label, `HelperText`
- String literals in HTML text elements: `<h1>`, `<p>`, `<span>`, `<label>`, `<th>`, `<td>`
- Template literals that embed user-visible text: `` `Welcome, ${name}` ``
- Aria labels and accessibility text with hardcoded strings

**Do not flag (developer-facing strings):**
- Console logs, `console.error`, `console.warn`
- Test IDs and `data-testid` values
- CSS class names and style properties
- Import paths and module names
- Error codes and API endpoint paths
- Comments and JSDoc
- String literals used only as object keys or enum values
- Environment variable names

### 2. String concatenation anti-patterns

Flag string construction patterns that break in languages with different word order.

| Pattern | Problem | Fix |
|---------|---------|-----|
| `"Hello " + name + "!"` | Word order varies by language | Use ICU MessageFormat: `t('greeting', { name })` |
| `` `${count} items found` `` | Pluralization rules differ (Arabic has 6 forms) | Use plural-aware formatter: `t('items_found', { count })` |
| `"Created on " + date` | Date position varies by locale | Use a single translation key with placeholder |
| `label + ": " + value` | Colon, spacing, and order vary | Use a single key: `t('label_value', { label, value })` |

### 3. Locale-dependent formatting

Flag direct use of locale-sensitive APIs without i18n formatters.

| What | Anti-pattern | i18n-safe alternative |
|------|-------------|----------------------|
| **Dates** | `new Date().toLocaleDateString()` without locale arg, `.toISOString()` for display, manual `MM/DD/YYYY` formatting | `Intl.DateTimeFormat` or library (date-fns with locale) |
| **Numbers** | `.toFixed(2)` for currency, manual comma insertion, `Number.toString()` for display | `Intl.NumberFormat` with currency/unit options |
| **Currency** | `"$" + amount`, hardcoded currency symbol | `Intl.NumberFormat` with `style: 'currency'` |
| **Lists** | `items.join(", ")` | `Intl.ListFormat` |
| **Relative time** | `"5 minutes ago"`, manual time-ago strings | `Intl.RelativeTimeFormat` |

### 4. RTL-unsafe CSS patterns

Flag CSS that uses physical (LTR-biased) properties instead of logical equivalents. PF design tokens handle RTL internally — only flag custom CSS.

| Physical (flag) | Logical (correct) |
|----------------|-------------------|
| `margin-left` / `margin-right` | `margin-inline-start` / `margin-inline-end` |
| `padding-left` / `padding-right` | `padding-inline-start` / `padding-inline-end` |
| `text-align: left` / `right` | `text-align: start` / `end` |
| `float: left` / `right` | `float: inline-start` / `inline-end` |
| `left` / `right` (positioning) | `inset-inline-start` / `inset-inline-end` |
| `border-left` / `border-right` | `border-inline-start` / `border-inline-end` |

**Do not flag:**
- Physical properties on non-directional axes (`margin-top`, `padding-bottom`) — these are unaffected by RTL
- PF design token usage (`var(--pf-t--global--spacer--md)`) — tokens handle RTL internally
- `transform: translateX()` when used for animations, not layout positioning

### 5. Missing translation infrastructure

Check for signs that the project has no i18n setup:
- No `i18next`, `react-intl`, `react-i18next`, or equivalent in `package.json`
- No translation files (`*.json` in `locales/`, `translations/`, `i18n/`)
- No `t()`, `formatMessage()`, or `<Trans>` usage anywhere in the codebase

If no i18n infrastructure exists, report it as a top-level finding rather than flagging every individual string.

## Rules

- Distinguish user-facing from developer-facing strings — false positives on log messages and test IDs erode trust
- When no i18n framework is installed, recommend setup rather than flagging every string individually
- RTL findings apply only to custom CSS — PF6 components handle RTL internally
- `Intl.*` APIs are acceptable alternatives to full i18n libraries for formatting
- Single-character strings and numbers are not translation candidates

## Report format

```markdown
## i18n Audit: [directory or component]

### Infrastructure

[i18n framework detected / not detected — with setup recommendation if missing]

### Hardcoded Strings

| File | Line | String | Context | Recommendation |
|------|------|--------|---------|---------------|
| UserList.tsx | 23 | "No users found" | EmptyState titleText | Externalize to translation key |

### Concatenation Anti-patterns

| File | Line | Pattern | Fix |
|------|------|---------|-----|
| Dashboard.tsx | 45 | `` `${count} items` `` | Use plural-aware: `t('item_count', { count })` |

### Locale-dependent Formatting

| File | Line | API | Fix |
|------|------|-----|-----|
| OrderTable.tsx | 67 | `"$" + price` | `Intl.NumberFormat` with `style: 'currency'` |

### RTL-unsafe CSS

| File | Line | Property | Fix |
|------|------|----------|-----|
| sidebar.scss | 12 | `padding-left: 16px` | `padding-inline-start: 16px` |

### Summary

Strings: [N] hardcoded | Concatenation: [N] anti-patterns | Formatting: [N] issues | RTL: [N] unsafe
```

Do not fabricate file paths or line numbers — read the actual source files before reporting.

Files in this skill

  • SKILL.md6.3 KB
  • eval/cases/all-i18n-ready/I18nReady.tsx1.3 KB
  • eval/cases/all-i18n-ready/annotations.yaml305 B
  • eval/cases/all-i18n-ready/input.yaml133 B
  • eval/cases/concatenation-antipattern/Dashboard.tsx925 B
  • eval/cases/concatenation-antipattern/annotations.yaml480 B
  • eval/cases/concatenation-antipattern/input.yaml117 B
  • eval/cases/hardcoded-strings/UserList.tsx1.8 KB
  • eval/cases/hardcoded-strings/annotations.yaml343 B
  • eval/cases/hardcoded-strings/input.yaml130 B
  • eval/cases/rtl-unsafe-css/annotations.yaml466 B
  • eval/cases/rtl-unsafe-css/input.yaml122 B
  • eval/cases/rtl-unsafe-css/sidebar.scss363 B
  • eval/eval.yaml6.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.