home / skills / ryokun6 / ryos / localize

localize skill

/.cursor/skills/localize

This skill helps you localize ryOS apps by extracting strings, replacing with translation keys, and syncing translations across languages.

npx playbooks add skill ryokun6/ryos --skill localize

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
2.6 KB
---
name: localize
description: Localize ryOS apps and components by extracting hardcoded strings, replacing with translation keys, and syncing across languages. Use when localizing an app, adding i18n support, translating UI text, or working with translation files.
---

# Localize App or Component

## Workflow Checklist

```
- [ ] 1. Extract hardcoded strings
- [ ] 2. Replace with t() calls in source files
- [ ] 3. Add English translations to en/translation.json
- [ ] 4. Sync translations across languages
- [ ] 5. Machine translate [TODO] keys
- [ ] 6. Validate coverage
```

## Step 1: Extract Hardcoded Strings

```bash
bun run scripts/extract-strings.ts --pattern [PATTERN]
```

## Step 2: Replace Strings with t() Calls

For each component:
1. Add import: `import { useTranslation } from "react-i18next";`
2. Add hook: `const { t } = useTranslation();`
3. Replace strings: `t("apps.[appName].category.key")`
4. Add `t` to dependency arrays for `useMemo`/`useCallback`

### Key Structure

```
apps.[appName].menu.*        # Menu labels
apps.[appName].dialogs.*     # Dialog titles/descriptions
apps.[appName].status.*      # Status messages
apps.[appName].ariaLabels.*  # Accessibility labels
apps.[appName].help.*        # Help items (auto-translated)
```

### Common Patterns

```tsx
// Basic
t("apps.ipod.menu.file")

// With variables
t("apps.ipod.status.trackCount", { count: 5 })

// Conditional
isPlaying ? t("pause") : t("play")

// With symbol prefix
`✓ ${t("apps.ipod.menu.shuffle")}`
```

## Step 3: Add English Translations

Add to `src/lib/locales/en/translation.json`:

```json
{
  "apps": {
    "ipod": {
      "menu": { "file": "File", "addSong": "Add Song..." },
      "dialogs": { "clearLibraryTitle": "Clear Library" },
      "status": { "shuffleOn": "Shuffle ON" }
    }
  }
}
```

## Step 4: Sync Across Languages

```bash
bun run scripts/sync-translations.ts --mark-untranslated
```

Adds missing keys to all language files, marked with `[TODO]`.

## Step 5: Machine Translate

```bash
bun run scripts/machine-translate.ts
```

Requires `GOOGLE_GENERATIVE_AI_API_KEY` env variable.

## Step 6: Validate

```bash
bun run scripts/find-untranslated-strings.ts
```

## Component Guidelines

| Component | What to translate |
|-----------|-------------------|
| Menu bars | All labels, items, submenus |
| Dialogs | Titles, descriptions, button labels |
| Status | `showStatus()` calls, toasts |
| Help items | Auto-translated via `useTranslatedHelpItems` |

## Notes

- Emoji/symbols (♪, ✓) can stay hardcoded
- Help items use pattern: `apps.[appName].help.[key].title/description`
- Include `t` in dependency arrays when used in `useMemo`/`useCallback`

Overview

This skill localizes ryOS apps and components by extracting hardcoded strings, replacing them with translation keys, and syncing translations across languages. It streamlines adding i18n support, managing translation files, and preparing keys for machine translation. Use it to ensure UI text, dialogs, menus, and status messages are language-ready and consistent.

How this skill works

The skill inspects source files to extract hardcoded strings and replaces them with t() calls following a predictable key structure (apps.[appName].category.key). It adds English entries to the master translation file, syncs missing keys across other language files with a TODO marker, and can trigger machine translation for untranslated keys. Validation tools report remaining untranslated strings and missing coverage.

When to use it

  • When adding i18n support to a new or existing ryOS app or component
  • Before shipping UI changes that introduce new user-facing text
  • When consolidating localization keys and ensuring consistent key structure
  • When preparing translation files for translators or machine translation
  • When validating that all visible strings are covered in translation files

Best practices

  • Follow the key hierarchy: apps.[appName].menu/dialogs/status/ariaLabels/help
  • Keep emoji and symbols hardcoded (e.g., ✓, ♪) and translate textual content only
  • Import useTranslation and add const { t } = useTranslation() in each component
  • Include t in useMemo/useCallback dependency arrays whenever used inside hooks
  • Run extraction, sync, and validation scripts as part of your localization workflow

Example use cases

  • Extract and replace hardcoded menu labels with t("apps.myApp.menu.file") and add entries to en/translation.json
  • Sync newly added keys across all language files and mark missing translations with [TODO]
  • Run machine translation to prefill untranslated entries before human review
  • Validate a component to find untranslated strings shown via showStatus() or toasts
  • Localize dialogs by replacing titles and descriptions and adding corresponding keys under apps.[appName].dialogs

FAQ

What string patterns are kept hardcoded?

Emoji and non-text symbols (for example ♪ or ✓) may remain hardcoded; all user-facing textual content should use translation keys.

How are missing translations marked?

Missing keys are added to each language file and prefixed or suffixed with a [TODO] marker so translators can find them easily.