Skip to main content

Basic Usage

Quick start with init​

The simplest way to use sheets-translate-to-json is the init method, which reads all sheets and writes JSON files in one call.

import { SheetManager } from 'sheets-translate-to-json';

const manager = new SheetManager(
process.env.PRIVATE_KEY,
process.env.CLIENT_EMAIL,
process.env.SHEET_ID
);

await manager.init('./translations');

This will:

  1. Connect to your Google Sheet
  2. Read all sheets and merge their data by language
  3. Create one JSON file per language in ./translations/ (e.g., en.json, fr.json, es.json)

Select specific sheets​

If your spreadsheet has multiple tabs and you only want certain ones:

await manager.init('./translations', ['Homepage', 'Settings']);

Only the sheets named "Homepage" and "Settings" will be processed, and their data merged.

Separate read and write​

For more control, use read and write separately:

const manager = new SheetManager(privateKey, clientEmail, sheetId);

// Read data from the first sheet
const data = await manager.read();

// Optionally transform the data here...

// Write to disk
manager.write(data, './translations');

Read by sheet name​

const data = await manager.readByName('Homepage');
manager.write(data, './translations');

Read all sheets individually​

const allData = await manager.readAllSheets();

// allData is { [sheetName]: SheetData }
for (const [sheetName, data] of Object.entries(allData)) {
console.log(`Sheet "${sheetName}" has ${Object.keys(data).length} languages`);
}

List available sheets​

const sheetNames = await manager.listSheets();
console.log(sheetNames); // ['Homepage', 'Settings', 'Emails']

Output structure​

Given a spreadsheet with this data:

keyenfr
helloHelloBonjour
nav.homeHomeAccueil
nav.aboutAboutA propos

The generated en.json will be:

{
"hello": "Hello",
"nav": {
"home": "Home",
"about": "About"
}
}

Dot-notation keys are automatically expanded into nested objects.

Running your script​

# JavaScript
node your-script.js

# TypeScript (with ts-node)
npx ts-node your-script.ts

# TypeScript (with tsx)
npx tsx your-script.ts

Result​

After running your script, a translations/ folder is created with the generated JSON files:

Folder with JSON files

Example JSON output

Two-way sync​

The SDK supports two-way synchronization between your local JSON files and Google Sheets. This is useful when translations are edited both locally and in the spreadsheet.

Push local changes to Google Sheets​

Use push to upload your local JSON files back to Google Sheets. Nested objects are flattened back to dot-notation automatically.

// Push to the default sheet
await manager.push('./translations');

// Push to a specific sheet (creates it if it doesn't exist)
await manager.push('./translations', 'Homepage');

Read local files back into SheetData​

Use readLocal to read your JSON files from disk back into the SheetData format, without any network call.

const data = manager.readLocal('./translations');
// data is the same shape as what read() returns

Full two-way sync​

Use sync to synchronize both directions at once. The method compares local and remote data and reconciles them based on the chosen strategy.

// Default merge strategy: combines both sides, prefers local on conflicts
const result = await manager.sync('./translations');

console.log(result);
// {
// added: { local: 3, remote: 5 },
// updated: { local: 1, remote: 2 },
// languages: ['en', 'fr', 'es']
// }

Sync strategies​

// Local wins: your local files override remote on conflicts
await manager.sync('./translations', { strategy: 'local' });

// Remote wins: the spreadsheet overrides local on conflicts
await manager.sync('./translations', { strategy: 'remote' });

// Merge (default): combines both, prefers local on conflicts,
// fills in missing values from both sides
await manager.sync('./translations', { strategy: 'merge' });

Sync with a specific sheet​

await manager.sync('./translations', {
sheetName: 'Homepage',
createSheet: true, // create the sheet if it doesn't exist
strategy: 'local',
});