skills/glot-i18n/SKILL.md
Fix i18n issues in Next.js + next-intl projects using glot MCP server. Use when user needs to fix hardcoded text, missing translation keys, sync translations across locales, or detect untranslated values.
npx skillsauth add sukitly/glotctl glot-i18nInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill guides you through detecting and fixing internationalization (i18n) issues in Next.js projects using next-intl.
.glotrc.json configuration file (run glot init if missing)next-intl for translationsActivate this skill when:
IMPORTANT: Follow this order to minimize rework!
1. scan_overview → Understand the overall state
2. Fix hardcoded → Replace text with t() calls, add keys to primary locale
3. Fix primary_missing → Add missing keys to primary locale
4. Fix replica_lag → Sync keys to other locales
5. Fix untranslated → Translate values that are identical to primary locale
Why this order matters:
| Tool | Purpose | When to Use |
| ---------------------- | ------------------------------------- | ------------------------------------- |
| get_config | Get project configuration | First, to understand project setup |
| get_locales | List available locale files | To see which languages are configured |
| scan_overview | Get statistics of all issues | Always start here to understand scope |
| scan_hardcoded | List hardcoded text issues | When fixing hardcoded text |
| scan_primary_missing | List keys missing from primary locale | After fixing hardcoded issues |
| scan_replica_lag | List keys missing from other locales | After fixing primary_missing |
| scan_untranslated | List values identical to primary locale | After fixing replica_lag (or anytime) |
| add_translations | Add keys to locale files | When adding new translation keys |
Call: scan_overview
Parameters: { "project_root_path": "<project_path>" }
Check the hardcoded.total_count to understand scope.
Call: scan_hardcoded
Parameters: { "project_root_path": "<project_path>", "limit": 20 }
Each item contains:
file_path: The TSX/JSX fileline, col: Locationtext: The hardcoded text foundsource_line: The actual source code lineFollow key naming conventions:
Examples:
| Text | Suggested Key |
|------|---------------|
| "Submit" | common.submit or buttons.submit |
| "Welcome to our app" | homePage.hero.welcomeMessage |
| "Enter your email" | auth.emailPlaceholder |
| "Loading..." | common.loading |
Replace hardcoded text with t() calls:
Before:
<button>Submit</button>
<input placeholder="Enter email" />
<p>Welcome to our app</p>
After:
<button>{t("common.submit")}</button>
<input placeholder={t("auth.emailPlaceholder")} />
<p>{t("homePage.hero.welcomeMessage")}</p>
Ensure the component has useTranslations hook:
import { useTranslations } from "next-intl";
export function MyComponent() {
const t = useTranslations();
// ... or with namespace:
// const t = useTranslations("homePage");
return <p>{t("hero.welcomeMessage")}</p>;
}
Call: add_translations
Parameters: {
"project_root_path": "<project_path>",
"translations": [
{
"locale": "en",
"keys": {
"common.submit": "Submit",
"auth.emailPlaceholder": "Enter your email",
"homePage.hero.welcomeMessage": "Welcome to our app"
}
}
]
}
Nested keys (e.g., common.submit) are automatically expanded to nested JSON structure.
If pagination.has_more is true, continue with next offset:
Call: scan_hardcoded
Parameters: { "project_root_path": "<project_path>", "limit": 20, "offset": 20 }
After fixing hardcoded issues, some keys might be used in code but missing from locale files.
Call: scan_primary_missing
Parameters: { "project_root_path": "<project_path>" }
Each item shows:
key: The missing key namefile_path: Where it's usedline: Line numberFor each missing key, determine the appropriate translation value and add it:
Call: add_translations
Parameters: {
"project_root_path": "<project_path>",
"translations": [
{
"locale": "en",
"keys": {
"missingKey1": "Translation value 1",
"missingKey2": "Translation value 2"
}
}
]
}
Keys that exist in primary locale but missing in other locales.
Call: scan_replica_lag
Parameters: { "project_root_path": "<project_path>" }
Each item shows:
key: The key namevalue: Value in primary localeexists_in: Primary locale codemissing_in: Array of locales missing this keyOption A: Copy primary value (for same-language variants or as placeholder)
Call: add_translations
Parameters: {
"project_root_path": "<project_path>",
"translations": [
{ "locale": "de", "keys": { "common.submit": "Submit" } },
{ "locale": "fr", "keys": { "common.submit": "Submit" } }
]
}
Option B: Ask user for translations
If the user can provide translations, use their values. Otherwise, copy the primary value as a placeholder with a TODO comment in the code or a note to the user.
Values that are identical to the primary locale may indicate text was copied without being translated.
Call: scan_untranslated
Parameters: { "project_root_path": "<project_path>" }
Each item shows:
key: The translation keyvalue: The value (same in both locales)locale: The non-primary locale with the issueprimary_locale: The primary locale codeFor each untranslated key, provide the correct translation:
Call: add_translations
Parameters: {
"project_root_path": "<project_path>",
"translations": [
{ "locale": "de", "keys": { "common.submit": "Absenden" } },
{ "locale": "fr", "keys": { "common.submit": "Soumettre" } }
]
}
Note: Some values may intentionally be the same across locales (e.g., brand names, technical terms). Use your judgment or ask the user.
<area>.<section>.<element>
Examples:
common.buttons.submit - Shared UI elementsauth.login.title - Authentication pagesdashboard.sidebar.menuItem - Dashboard specificerrors.validation.required - Error messageswelcomeMessage not welcome-messageauth.loginButton not just loginPlurals (if using next-intl plural support):
{
"items": "{count, plural, =0 {No items} =1 {One item} other {# items}}"
}
Variables:
{
"greeting": "Hello, {name}!"
}
// Before
<h1>Welcome</h1>
// After
<h1>{t("page.welcome")}</h1>
// Before
<input placeholder="Search..." />
<img alt="User avatar" />
// After
<input placeholder={t("common.searchPlaceholder")} />
<img alt={t("common.userAvatar")} />
// Before
{
isLoading ? "Loading..." : "Submit";
}
// After
{
isLoading ? t("common.loading") : t("common.submit");
}
// Before
<p>{`Welcome, ${userName}`}</p>
// After (using next-intl variables)
<p>{t("greeting", { name: userName })}</p>
// In JSON: "greeting": "Welcome, {name}"
scan_overview again to verify progresshas_more field and continue if neededuseTranslations is imported in modified componentsRun glot init in the project root to create .glotrc.json
Check that messages_dir in config points to correct locale files directory
The text must contain at least one alphabetic character. Pure numbers/symbols are ignored.
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
A CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.