lokalise-data-handling
Implement Lokalise translation data handling, PII management, and compliance patterns. Use when handling sensitive translation data, implementing data redaction, or ensuring compliance with privacy regulations for Lokalise integrations. Trigger with phrases like "lokalise data", "lokalise PII", "lokalise GDPR", "lokalise data retention", "lokalise privacy", "lokalise compliance".
Install
mkdir -p .claude/skills/lokalise-data-handling && curl -L -o skill.zip "https://mcp.directory/api/skills/download/8718" && unzip -o skill.zip -d .claude/skills/lokalise-data-handling && rm skill.zipInstalls to .claude/skills/lokalise-data-handling
About this skill
Lokalise Data Handling
Overview
Lokalise manages translation data through keys, translations, snapshots, and branches. This skill covers the translation data lifecycle (create, update, export), key metadata management (tags, descriptions, screenshots), translation snapshots for versioning, branch-based translation isolation, export format handling (JSON flat/nested, XLIFF, PO), character encoding (UTF-8 BOM handling), and plural form support across locales.
Prerequisites
@lokalise/node-apiSDK installed (npm install @lokalise/node-api)- API token with read/write access to the target project
- Understanding of i18n key naming conventions for your project
lokalise2CLI for bulk file operations (optional)
Instructions
1. Understand the Translation Data Lifecycle
Translation data in Lokalise follows this flow: Create keys (with platforms, tags, descriptions) -> Add base translations (source language) -> Translate (manually or via integrations) -> Review (proofread flag) -> Export (download to codebase).
Create keys with metadata that helps translators:
import { LokaliseApi } from "@lokalise/node-api";
const lokalise = new LokaliseApi({ apiKey: process.env.LOKALISE_API_TOKEN! });
// Create keys with rich metadata
await lokalise.keys().create({
project_id: projectId,
keys: [
{
key_name: {
ios: "welcome.title",
android: "welcome_title",
web: "welcome.title",
other: "welcome.title",
},
description: "Main heading on the welcome screen shown after signup",
platforms: ["web", "ios", "android"],
tags: ["onboarding", "v2.1"],
base_translations: [
{ language_iso: "en", translation: "Welcome to {{appName}}" },
],
is_plural: false,
is_hidden: false,
},
],
});
2. Manage Key Metadata
Tags, descriptions, and screenshots help translators understand context. Keep metadata current:
// Bulk update tags for release management
await lokalise.keys().bulk_update({
project_id: projectId,
keys: [
{ key_id: 12345, tags: ["release-3.0", "reviewed"] },
{ key_id: 12346, tags: ["release-3.0", "needs-review"] },
],
});
// Add a screenshot for visual context
await lokalise.screenshots().create({
project_id: projectId,
screenshots: [
{
data: base64EncodedImage, // Base64 JPEG/PNG, max 6 MB
title: "Welcome screen — mobile layout",
description: "Shows welcome.title and welcome.subtitle keys",
key_ids: [12345, 12346],
},
],
});
// Retrieve key with all metadata
const key = await lokalise.keys().get(keyId, {
project_id: projectId,
disable_references: 0, // include reference language info
});
console.log(key.key_name, key.tags, key.description);
3. Use Snapshots for Translation Versioning
Snapshots capture the entire project state at a point in time. Create them before bulk changes:
// Create a snapshot before a major update
const snapshot = await lokalise.snapshots().create({
project_id: projectId,
title: `Pre-release v3.0 — ${new Date().toISOString()}`,
});
console.log(`Snapshot created: ${snapshot.snapshot_id}`);
// List snapshots
const snapshots = await lokalise.snapshots().list({
project_id: projectId,
limit: 20,
});
snapshots.items.forEach((s) =>
console.log(`${s.snapshot_id}: ${s.title} (${s.created_at})`)
);
// Restore a snapshot (creates a NEW project with the snapshot data)
const restored = await lokalise.snapshots().restore(snapshotId, {
project_id: projectId,
});
console.log(`Restored to new project: ${restored.project_id}`);
Snapshots are immutable. Restoring creates a new project — it does not overwrite the current one.
4. Use Branches for Translation Isolation
Branches let you work on translations for a feature without affecting production strings:
// Create a feature branch
await lokalise.branches().create({
project_id: projectId,
name: "feature/checkout-redesign",
});
// List branches
const branches = await lokalise.branches().list({ project_id: projectId });
// Work on the branch — use the branch name in file operations
await lokalise.files().upload({
project_id: projectId,
data: base64FileContent,
filename: "en.json",
lang_iso: "en",
use_automations: true,
branch: "feature/checkout-redesign", // target the branch
});
// Merge branch back to main when translations are ready
await lokalise.branches().merge(branchId, {
project_id: projectId,
force_current: false, // false = conflict detection enabled
});
5. Handle Export Formats
Lokalise supports multiple export formats. Choose based on your stack:
// Download as flat JSON (React, Next.js, Vue)
const flatJson = await lokalise.files().download({
project_id: projectId,
format: "json",
original_filenames: false,
bundle_structure: "locales/%LANG_ISO%.json",
json_unescaped_slashes: true,
export_empty_as: "base", // use base language for untranslated
include_tags: ["release-3.0"],
filter_langs: ["en", "fr", "de", "ja"],
});
// Returns { bundle_url: "https://..." } — download the ZIP
// Download as nested JSON (common for namespaced i18n)
const nestedJson = await lokalise.files().download({
project_id: projectId,
format: "json",
original_filenames: false,
bundle_structure: "locales/%LANG_ISO%/%FILENAME%.json",
json_unescaped_slashes: true,
export_key_as: "key_name_dots_to_nested", // a.b.c → {a:{b:{c:"..."}}}
});
# Export as XLIFF 2.0 (for professional translation agencies)
lokalise2 file download \
--token "$LOKALISE_API_TOKEN" \
--project-id "$PROJECT_ID" \
--format xliff \
--dest ./translations/ \
--include-tags "release-3.0"
# Export as PO/POT (for gettext-based projects)
lokalise2 file download \
--token "$LOKALISE_API_TOKEN" \
--project-id "$PROJECT_ID" \
--format po \
--dest ./locales/ \
--export-empty-as base
6. Handle Character Encoding
All Lokalise exports use UTF-8. Watch for these encoding issues:
// Remove UTF-8 BOM if present (some editors add it)
function stripBOM(content: string): string {
return content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;
}
// Validate JSON translation files after download
import { readFileSync } from "fs";
function loadTranslations(filePath: string): Record<string, string> {
const raw = readFileSync(filePath, "utf-8");
const clean = stripBOM(raw);
try {
return JSON.parse(clean);
} catch (e) {
throw new Error(
`Invalid JSON in ${filePath}: ${(e as Error).message}. ` +
`Check for encoding issues or unescaped characters.`
);
}
}
When uploading files, always specify UTF-8 encoding. Lokalise auto-detects encoding but explicit is safer:
# Upload with explicit encoding
lokalise2 file upload \
--token "$LOKALISE_API_TOKEN" \
--project-id "$PROJECT_ID" \
--file ./locales/en.json \
--lang-iso en \
--convert-placeholders true
7. Handle Plural Forms
Lokalise uses CLDR plural rules. Different languages have different plural categories:
// Create a plural key
await lokalise.keys().create({
project_id: projectId,
keys: [
{
key_name: "items.count",
is_plural: true,
platforms: ["web"],
base_translations: [
{
language_iso: "en",
translation: JSON.stringify({
one: "{{count}} item",
other: "{{count}} items",
}),
},
],
},
],
});
Plural categories by language:
| Language | Categories | Example |
|---|---|---|
| English | one, other | 1 item / 2 items |
| French | one, many, other | 1 chose / 1000000 choses / 2 choses |
| Arabic | zero, one, two, few, many, other | 6 categories |
| Japanese | other | No plural distinction |
| Polish | one, few, many, other | 1 element / 2 elementy / 5 elementow |
In JSON exports, plural keys appear as objects:
{
"items.count": {
"one": "{{count}} item",
"other": "{{count}} items"
}
}
Ensure your i18n framework handles plural objects (i18next, react-intl, vue-i18n all support this natively).
Output
- Translation keys created with metadata (tags, descriptions, platforms)
- Snapshots capturing project state before bulk changes
- Branch-based workflow isolating feature translations from production
- Exported translation files in the target format (JSON/XLIFF/PO) with correct encoding
- Plural keys configured with CLDR-compliant category coverage
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Garbled characters in export | BOM or wrong encoding assumed | Strip BOM, ensure UTF-8 |
| Missing plural form | Language requires categories not provided | Check CLDR plural rules for target language |
| Branch merge conflict | Same key modified in both branches | Resolve via Lokalise UI or set force_current: true |
| Snapshot restore fails | Exceeded project limit on plan | Delete unused projects or upgrade plan |
| Empty translations in export | Key has no translation for language | Use export_empty_as: "base" to fall back to source |
| Upload overwrites existing | Default merge behavior is replace | Use replace_modified: false to preserve existing |
Examples
Upload a JSON Translation File
import { readFileSync } from "fs";
const fileContent = readFileSync("./locales/en.json", "utf-8");
const base64Content = Buffer.from(fileContent).toString("base64");
await lokalise.files().upload({
project_id: projectId,
data: base64Content,
filename: "en.json",
lang_iso: "en",
convert_placeholders: true,
detect_icu_plurals: true,
replace_modified: false, // preserve manual edits
tags_inserted_keys: ["auto-import"],
});
Export and Write to Disk
#!/bin/bash
# download-translations.sh
BUNDLE_URL=$(curl -s -X POST \
"https://api.lo
---
*Content truncated.*
More by jeremylongshore
View all skills by jeremylongshore →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
pdf-to-markdown
aliceisjustplaying
Convert entire PDF documents to clean, structured Markdown for full context loading. Use this skill when the user wants to extract ALL text from a PDF into context (not grep/search), when discussing or analyzing PDF content in full, when the user mentions "load the whole PDF", "bring the PDF into context", "read the entire PDF", or when partial extraction/grepping would miss important context. This is the preferred method for PDF text extraction over page-by-page or grep approaches.
Related MCP Servers
Browse all serversNekzus Utility Server offers modular TypeScript tools for datetime, cards, and schema conversion with stdio transport co
Build persistent semantic networks for enterprise & engineering data management. Enable data persistence and memory acro
Unlock seamless Figma to code: streamline Figma to HTML with Framelink MCP Server for fast, accurate design-to-code work
Integrate with Gemini CLI for large-scale file analysis, secure code execution, and advanced context control using Googl
Powerful MCP server for Slack with advanced API, message fetching, webhooks, and enterprise features. Robust Slack data
Claude Skills offers advanced GitHub search to find coding skills using semantic retrieval in bioinformatics and data an
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.