Pre-commit i18n Check

VerifiedSafe

Fast, focused translation check for changed files, catching untranslated strings, missing locale keys, and locale sync issues before committing.

Sby Skills Guide Bot
DevelopmentIntermediate
7/22/2026
Claude Code
#i18n#localization#vue#pre-commit#code-review

Recommended for

Automated summary

Runs a fast i18n check over changed Vue files to surface untranslated strings, raw titles, and locale keys that are out of sync.

Strengths

  • Only inspects changed .vue files (tracked, staged, and untracked), keeping it fast in a monorepo
  • Four focused checks: hardcoded label/title/placeholder props, raw PascalCase titles, key sync across en/nl/fr, and missing locale infrastructure
  • Explicit skip list (i-lucide icons, routes, CSS classes, test files) that cuts down noise
  • Supports --scope <app> to narrow to one app and --fix to auto-correct its findings

Limitations

  • Tightly coupled to Nuxt/Vue with $t()/t() and to specific components (UFormField, CroutonTableHeader, CroutonFormRepeater), so it does not transfer to other stacks
  • Locale comparison is hardcoded to en/nl/fr; other languages are not covered
  • Heuristic scanning only covers changed files, so untranslated strings in untouched files go unnoticed
When to use it

Before committing changes to Vue components or locale files that may introduce untranslated UI text.

When not to use it

If your project isn't Nuxt/Vue using $t(), or you need a full repo-wide translation audit.

Security analysis

Safe
Quality score88/100

The skill runs only read-only git diff and grep commands to identify changed files, reads locale JSON files, and optionally performs targeted text replacements via Edit. No destructive commands, no network access, no exfiltration, no obfuscation, and no disabling of safety mechanisms. The allowed tools are used for legitimate code quality checks.

No concerns found

How this analysis is made

Examples

Pre-commit run
Run /i18n-check before I commit my booking form changes.
Scoped to one app
/i18n-check --scope bookings — only look at the bookings app, I'm about to commit locale keys.
Auto-fix findings
Run /i18n-check --fix on my uncommitted Vue files and tell me exactly what you changed.

name: i18n-check layer: stack description: Pre-commit i18n check. Scans changed files for untranslated strings, missing locale keys, and locale sync issues. Fast and focused — only checks what changed. Use before committing or as a review add-on. argument-hint: "[--scope <app> | --fix]" allowed-tools: Bash, Read, Grep, Glob, Edit, Agent

i18n Pre-Commit Check

Fast, focused translation check for changed files only. Catches the 4 most common i18n mistakes before they ship.

Modes

| Invocation | What it checks | |------------|---------------| | /i18n-check | All uncommitted changed .vue files + their locale files | | /i18n-check --scope <app> | Only files under apps/<app>/ | | /i18n-check --fix | Check + auto-fix all findings |

What It Catches

1. Hardcoded Labels (Most Common)

Scan changed .vue files for user-visible text NOT wrapped in $t() or t():

Must be translated:

  • label="..." on UFormField (should be :label="$t(...)")
  • title="..." on CroutonTableHeader (should be :title="$t(...)")
  • add-label="..." on CroutonFormRepeater (should be :add-label="$t(...)")
  • placeholder="..." on inputs (should be :placeholder="$t(...)")
  • dependent-label="..." on dependent field loaders
  • Static { label: 'Text', value: '...' } arrays in select options (should be computed with $t())
  • Raw text in <p>, <h1>-<h6>, <span> that isn't interpolation or a component
  • Button text content that isn't {{ t(...) }} or {{ $t(...) }}
  • Tab/navigation labels in JS arrays (e.g., { label: 'Scheduling', value: 'scheduling' })

Skip (not translatable):

  • CSS class strings, icon names (i-lucide-*)
  • Route paths, collection names, field names in name="..." attributes
  • Component names, event handlers
  • Boolean/number props
  • Dynamic :label already using $t() or t()
  • Comments, console.log(), error messages in catch blocks
  • Test files

2. Raw PascalCase/camelCase Titles

Detect table headers or page titles using raw collection names:

<!-- BAD: Raw collection name as title -->
title="BookingsLocations"
title="PagesPages"

<!-- GOOD: Translated or formatted -->
:title="$t('bookings.collections.locations.title')"
:title="useFormatCollections().collectionWithCapital('pagesPages')"

3. Locale Key Sync

For each app with changed locale files, or apps whose components were changed:

  • Compare key structure across en.json, nl.json, fr.json
  • Flag keys present in en but missing from nl or fr
  • Flag values in nl/fr that are identical to en (likely untranslated copy-paste)

4. Missing Locale Infrastructure

If a changed .vue file uses $t() or t() but the layer has no locale files, flag it.

Workflow

Step 1: Gather changed files

# Get all changed .vue files (staged + unstaged)
git diff --name-only --diff-filter=ACMR HEAD | grep '\.vue$'
git diff --name-only --cached --diff-filter=ACMR | grep '\.vue$'
# Also check untracked .vue files
git ls-files --others --exclude-standard | grep '\.vue$'

If --scope is set, filter to apps/<scope>/**.

Step 2: Scan templates for hardcoded text

For each changed .vue file, read it and check:

Pattern matching (in <template> section only):

# Hardcoded label props (should use :label with $t)
label="[A-Z].*"  on UFormField, CroutonFormReferenceSelect, etc.

# Hardcoded title props
title="[A-Z].*"  on CroutonTableHeader

# Static select option arrays in <script>
{ label: 'Text', value: '...' }  (not inside computed(() => ...))

# Tab/navigation items with static labels
{ label: 'Text', value: '...' }  in navigationItems or similar arrays

Step 3: Check locale files

Find the locale directory for each changed component's layer:

apps/{app}/layers/{layer}/i18n/locales/{en,nl,fr}.json

Read all three and compare:

  1. Flatten all keys to dot-notation
  2. Find keys in en missing from nl and fr
  3. Find values in nl/fr identical to en (possible untranslated)

Step 4: Report

If clean:

## i18n Check: clean ✅
Checked N file(s), no translation issues found.

If issues found:

## i18n Check: N issue(s) found

### Hardcoded Labels (X)
| File | Line | Text | Suggested Key |
|------|------|------|---------------|
| `path/to/File.vue` | 43 | `label="Location"` | `bookings.fields.location` |

### Raw Collection Titles (X)
| File | Line | Current | Fix |
|------|------|---------|-----|
| `path/to/List.vue` | 34 | `title="BookingsLocations"` | `:title="$t('bookings.collections.locations.title')"` |

### Missing Locale Keys (X)
| Key | Missing From |
|-----|-------------|
| `bookings.fields.slot` | nl, fr |

### Possibly Untranslated (X)
| Key | Value (same as en) |
|-----|-------------------|
| `bookings.fields.name` | "Name" (nl), "Name" (fr) |

Step 5: Auto-fix (if --fix)

When --fix is passed:

  1. Hardcoded labels → Replace label="Text" with :label="$t('suggested.key')"
  2. Raw titles → Replace with $t() or useFormatCollections()
  3. Static select arrays → Wrap in computed() with $t() calls
  4. Missing locale keys → Add to nl.json/fr.json with English placeholder
  5. Add useI18n() import if needed for computed select options

After fixing, show what was changed and suggest the user verify translations in nl.json/fr.json.

Key Naming Convention

When suggesting keys, follow this pattern:

{layer}.collections.{collection}.title    → Collection list titles
{layer}.fields.{fieldName}               → Form field labels
{layer}.actions.{actionName}             → Button/action labels
{layer}.tabs.{tabName}                   → Tab/navigation labels
{layer}.messages.{messageName}           → Helper text, toasts
{layer}.{enumGroup}.{value}              → Select option labels

Examples:

  • bookings.fields.location → "Location" field label
  • bookings.actions.addTimeSlot → "Add Time Slot" button
  • bookings.triggerTypes.booking_created → Select option

Integration with /commit

This check runs automatically as part of /commit when changed files include .vue files in an app with i18n configured. It runs AFTER /sync-docs and BEFORE the actual commit.

If issues are found:

  • With --fix: Fix and include fixes in the commit
  • Without --fix: Report findings and ask "Fix before committing? (y/n/skip)"

Rules

  1. Only check changed files — never scan the whole repo (use /i18n-audit for that)
  2. Suggest specific keys — don't just say "needs translation", propose the key path
  3. Don't flag internal strings — error messages in catch, console.log, dev-only text are fine
  4. Trust existing patterns — if a file already uses $t() consistently and one label is hardcoded, that's likely an oversight worth flagging
  5. Locale files are authoritative — if a key exists in the locale file, trust it's intentional

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/pre-commit-i18n-check-mrwak99k/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/pre-commit-i18n-check-mrwak99k' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/pre-commit-i18n-check-mrwak99k/download' --output '.skill-downloads/pre-commit-i18n-check-mrwak99k/SKILL.md.part' && mv '.skill-downloads/pre-commit-i18n-check-mrwak99k/SKILL.md.part' '.skill-downloads/pre-commit-i18n-check-mrwak99k/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

Tools declared by the author (check availability in your agent): Bash, Read, Grep, Glob, Edit, Agent

No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.

Claude Code
test -f '.skill-downloads/pre-commit-i18n-check-mrwak99k/SKILL.md' && test -s '.skill-downloads/pre-commit-i18n-check-mrwak99k/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/i18n-check' && cp -R '.skill-downloads/pre-commit-i18n-check-mrwak99k' '.claude/skills/i18n-check'

OpenSkills

OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.

Official OpenSkills installation
openskills install './.skill-downloads/pre-commit-i18n-check-mrwak99k'

openskills read 'pre-commit-i18n-check-mrwak99k'

Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.

For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.

openskills sync

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/pre-commit-i18n-check-mrwak99k/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills