i18n-sheets
v1.0.1
Published
A powerful CLI tool for synchronizing internationalization (i18n) resources between Google Sheets and your TypeScript project
Downloads
419
Maintainers
Readme
i18n-sheets 📊
A powerful CLI tool for synchronizing internationalization (i18n) resources between Google Sheets and your TypeScript project. Streamline your translation workflow with automated cloning, uploading, and three-way merge synchronization.
🌟 Features
- 📥 Clone: Download translations from Google Sheets to local files
- 📤 Upload: Push local translations to Google Sheets
- 🔄 Sync: Intelligent three-way merge between local, remote, and anchor versions
- ⚙️ Configurable: Support for JSON, JS, and MJS configuration files
- 🎯 Force Mode: Skip sync checks when needed
- ✨ Auto-formatting: Prettier integration for consistent code style
- 🛡️ Type-safe: Full TypeScript support with proper type definitions
📦 Installation
npm install -g i18n-sheetsOr use locally in your project:
npm install --save-dev i18n-sheets🚀 Quick Start
- Create a configuration file in your project root:
// i18n-sheets.config.js
export default {
googleSheetId: 'your-google-sheet-id',
googleCredentials: {
clientEmail: '[email protected]',
privateKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n',
},
outputPath: './src/i18n/resources',
anchorOutputPath: './src/i18n/anchor',
remoteOutputPath: './src/i18n/remote'
};- Run your first sync:
i18n-sheets sync📋 Commands
clone - Download from Google Sheets
Download the latest translations from Google Sheets to your local files.
# Standard clone (runs sync first)
i18n-sheets clone
# Force clone (skip sync)
i18n-sheets clone -f
i18n-sheets clone --forceupload - Push to Google Sheets
Upload your local translations to Google Sheets.
# Standard upload (runs sync first)
i18n-sheets upload
# Force upload (skip sync)
i18n-sheets upload -f
i18n-sheets upload --forcesync - Three-way merge
Perform intelligent three-way merge between local, remote, and anchor versions.
i18n-sheets sync⚙️ Configuration
Create a configuration file in your project root. Supported formats:
i18n-sheets.config.js(ES modules)i18n-sheets.config.mjs(ES modules)i18n-sheets.config.json(JSON)
Configuration Options
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| googleSheetId | string | ✅ | Your Google Sheets document ID |
| googleCredentials | object | ✅ | Google service account credentials |
| googleCredentials.clientEmail | string | ✅ | Service account email |
| googleCredentials.privateKey | string | ✅ | Service account private key |
| outputPath | string | ✅ | Path for generated resource files |
| anchorOutputPath | string | ❌ | Path for anchor/backup files (default: .i18n-sheets/anchor) |
| remoteOutputPath | string | ❌ | Path for remote snapshot files (default: .i18n-sheets/remote) |
Example Configurations
JavaScript (ES Module)
// i18n-sheets.config.js
export default {
googleSheetId: '1ABC123def456GHI789jkl',
googleCredentials: {
clientEmail: '[email protected]',
privateKey: process.env.GOOGLE_PRIVATE_KEY,
},
outputPath: './src/i18n/resources',
anchorOutputPath: './src/i18n/anchor',
remoteOutputPath: './src/i18n/remote'
};JSON
{
"googleSheetId": "1ABC123def456GHI789jkl",
"googleCredentials": {
"clientEmail": "[email protected]",
"privateKey": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
},
"outputPath": "./src/i18n/resources",
"anchorOutputPath": "./src/i18n/anchor",
"remoteOutputPath": "./src/i18n/remote"
}🔄 Workflow
Standard Workflow
- Clone:
i18n-sheets clone- Downloads latest from Google Sheets - Edit: Make changes to your local translation files
- Upload:
i18n-sheets upload- Pushes changes to Google Sheets - Sync: Automatic three-way merge resolves conflicts
Force Mode
Use force flags to skip automatic sync when you're confident about overwriting:
# Skip sync, directly clone from sheets
i18n-sheets clone --force
# Skip sync, directly upload to sheets
i18n-sheets upload --force📁 File Structure
After running i18n-sheets, your project will have this structure:
your-project/
├── i18n-sheets.config.js # Configuration
├── src/i18n/
│ ├── resources/ # 📄 Current working files (OUTPUT_PATH)
│ │ ├── en.ts
│ │ ├── ko.ts
│ │ └── index.ts
│ ├── anchor/ # 📌 Anchor/backup versions (ANCHOR_OUTPUT_PATH)
│ │ ├── en_20250621.ts
│ │ └── ko_20250621.ts
│ └── remote/ # 🌐 Temporary remote snapshots (REMOTE_OUTPUT_PATH)
│ ├── en_20250621.ts
│ └── ko_20250621.tsDirectory Purposes:
resources/(OUTPUT_PATH): Contains your actual working translation files that you use in your applicationanchor/(ANCHOR_OUTPUT_PATH): Stores snapshot versions used as comparison baseline for three-way merge operationsremote/(REMOTE_OUTPUT_PATH): Temporarily holds remote data during sync process - these files are automatically removed after sync completion
🔧 Google Sheets Setup
Step 1: Create Google Cloud Project & Service Account
Create a Google Cloud Project
- Go to Google Cloud Console
- Click "New Project" and create a project
Enable Google Sheets API
- In your project, go to "APIs & Services" > "Library"
- Search for "Google Sheets API" and enable it
Create a Service Account
- Go to "APIs & Services" > "Credentials"
- Click "Create Credentials" > "Service Account"
- Fill in the service account name and click "Create"
Generate and Download Credentials
- After creating the service account, click on it
- Go to the "Keys" tab
- Click "Add Key" > "Create New Key" > "JSON"
- Download the JSON file
Extract Credentials from JSON
- Open the downloaded JSON file
- Find
client_email- this is your clientEmail - Find
private_key- this is your privateKey (keep the\ncharacters)
{ "client_email": "[email protected]", "private_key": "-----BEGIN PRIVATE KEY-----\nYour-Private-Key-Here\n-----END PRIVATE KEY-----\n" }
Step 2: Get Google Sheet ID
Open your Google Sheet
Copy the Sheet ID from URL
- The URL looks like:
https://docs.google.com/spreadsheets/d/[SHEET_ID]/edit - Copy the
[SHEET_ID]part (between/d/and/edit)
Example:
https://docs.google.com/spreadsheets/d/1ABC123def456GHI789jkl/edit#gid=0 ^^^^^^^^^^^^^^^^^^^^ This is your googleSheetId- The URL looks like:
Step 3: Share Sheet with Service Account
- Share your Google Sheet
- Open your Google Sheet
- Click the "Share" button
- Add the
client_emailfrom your service account JSON - Give it "Editor" permissions
Template Sheet Setup
Important: You must create a sheet named template in your Google Spreadsheet. This template sheet serves as the base template for creating resource sheets organized by domain.
Benefits of using a template sheet:
- Conditional Formatting: Pre-configure conditional formatting to highlight header areas or empty cells
- Consistent Structure: Ensures all domain-specific sheets follow the same format
- Visual Aids: Apply colors, borders, or other formatting to improve readability
Sheet Format
Your Google Sheet should follow this structure with depth-based columns:
| level_1 | level_2 | level_3 | translation_key | ko | en | ... | |---------|----------------|---------|-----------------|----|----|-----| | common | label | next | common.label.next | 다음 | Next | ... | | common | label | register | common.label.register | 등록 | Register | ... | | game_card | title | | game_card.title | 게임 카드 | Game Card | ... | | game_card | search_account | title | game_card.search_account.title | 계정 검색 | Search account | ... |
Column Structure:
level_1,level_2,level_3, etc.: Individual depth levels of the translation keytranslation_key: The combined key formed by joining all levels with dots (e.g.,common.label.next)ko,en, etc.: Language-specific translation values
Key Features:
- Keys are hierarchically organized by depth levels
- The
translation_keycolumn shows the final combined key - Language columns contain the actual translations
- Empty level columns are allowed for simpler key structures
🛠️ Development
# Install dependencies
npm install
# Build the project
npm run build
# Run locally
npm run dev
# Run tests (if available)
npm test📄 License
MIT License - see LICENSE file for details.
🤝 Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📞 Support
- 🐛 Report Issues
- 💬 Discussions
- 📧 Email: [email protected]
Made with ❤️ for the i18n community
