npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gstranslate

v1.2.1

Published

Simple translation management tool for small and growing projects based on Google Spreadsheets

Readme

gstranslate

Manage your translation in google spreadsheet

Demo

Why?

  • Existing solutions is expansive and their free tier includes only up to 1000 translation keys.
  • Google Spreadsheet is comfortable enough to edit with many people in team, with great permission system, which allows to give permission for editors to edit only specified range. This is good place to have a discussion about translations and leave remarks. And it is free :p.

Get started

  1. You creates a Google Spreadsheets;
  2. Make your spreadsheet to be accessible for read by direct link;
  3. run npx gstranslate -p PageName --key ... and it generates you json files per each language column in your google spreadsheet.

Usage

Recommended way to use gstranslate is to add command to your package.json/scripts

  • npx gstranslate -p Pages -p Components -p Errors

Environment

You need to add environment variable GSTRANSLATE_KEY to your environment. You may use .env file for example - gstranslate loads it while starts. (Do not commit .env to repository)

  • GSTRANSLATE_KEY - could be found in url string for example: https://docs.google.com/spreadsheets/d/F9F6WG19ga2BdsDhKrEOXnf6le2_hJfrJK_0fDAHn2L/edit#gid=71625432

CLI options

  • --pages|-p - allow to pass pages list (Required)
  • --key - allow to pass google spreadsheet key, alternative for GSTRANSLATE_KEY. (Required) Do not commit key to repository
  • --out-dir|-o - allow to change output directory (Default: ./locals)
  • --pretty-print - use for pretty print output json (Default: false)
  • --delay - sets delay between requests to pages in milliseconds (Default: 50)

Google Spreadsheet

Google spread sheet should have defined format

Pagination

Maintain all translations on one page may be not so good idea - we recommend you to group your translations in different pages. f.e. General, Components, Pages, etc...

Header Line

Header line - is the first line on each page. WARNING It should always be a comment (starts with #) to solve next 2 issues:

  • Header line should not be part of final translations;
  • Composite Keys from previous page should not have effect to the next one.

Key column

The first column contains keys which could be used in your code. Please name Key column starting with # symbol f.e. # KEY, that soles some issues.

Your translation keys could be named as you wish, but we recommend to give it dot-separated name. For example:

  • MyComponent.myField.title
  • MyComponent.myField.placeholder

Language columns

The next to Key column should be one or more language columns. First line of each column should contains a language code which will be used as file name for generated translations (ex: en.json). You could use something like en,sv or en_US, sv_FI or any other format you wish.

default language column - is language column next to Key column. Content of this cell will be used if translation in one of next columns is not specified. That helps to avoid duplication of translations in cases when translation for all languages should be the same.

if you actually want to keep translation for some language empty - you should use special keyword: <EMPTY>, but in our experience it is rarely case.

Comments

Each line(row) starts with # symbol will be ignored

@PATH (Composite key)

@PATH= is special directive allow to make keys shorter. Allow to avoid duplication, and make less changes in case you need to change keys.

When you specify @PATH=pages/index keys of next rows would be concatenated with this PATH until to next comment line.

We are using the same directive in webpack which translates to path to component.

For now it is the only one directive. If you have another ideas of using them please feel free to create an issue.

Example of table for google spreadsheet

The next table demonstrates how translations look like in google spreadsheet

# KEY | en | ru -----|----|---- some.kind.of.key | Default en translation | Русский перевод some.another.key | The same translation for en and ru | #some comment line | | one.more.key | One more english | Ещё один русский @PATH=pages/index | | composite.key | Composite key will look like pages/index/composite.key | composite.key2 | This will be pages/index/composite.key2 | <EMPTY>

Generated files

The above table will generate two files with next content:

en.json

{
  "some.kind.of.key": "Default en translation",
  "some.another.key": "The same translation for en and ru",
  "one.more.key": "One more english",
  "pages/index/composite.key": "Composite key will look like `pages/index/composite.key`",
  "pages/index/composite.key2": "This will be `pages/index/composite.key2`",
}

ru.json

{
  "some.kind.of.key": "Русский перевод",
  "some.another.key": "The same translation for en and ru",
  "one.more.key": "Ещё один русский",
  "pages/index/composite.key": "Composite key will look like `pages/index/composite.key`",
  "pages/index/composite.key2": ""
}

Environment variables (DEPRECATED)

You may create .env file in your project directory (do not commit it to repository) and specify next variables in format (KEY=VALUE):

  • TRANSLATION_KEY - is a google spreadsheet key (Required) [Deprecated]
  • TRANSLATION_PAGES - is comma-separated list of pages in google spreadsheet (Required) [Deprecated]
  • TRANSLATION_PRETTY - makes output format pretty-printed json (Default: false) [Deprecated]
  • TRANSLATION_DIR - directory for output translation files (Default: ./locales) [Deprecated]

Useful conditional formatting for google spreadsheet

We are using next conditional formatting rules in our spreadsheets

Comments

  • Range: A:C
  • Formula: =LEFT($A1) = "#"
  • Color: Light Green

@PATH

  • Range: A:C
  • Formula: =LEFT($A1;6) = "@PATH="
  • Color: Green

Duplicated translations in one row

  • Range: A:C
  • Formula: =AND(LEFT($A1) <> ""; AND($B1 = $C1; $B1 <> ""))
  • Color: Orange

Default translation missed

  • Range: A:C
  • Formula: =AND(LEFT($A1) <> ""; AND($B1 = ""; $C1 <> ""))
  • Color: Red

Contribution

If you would like to contribute - please do not make PR with breaking changes, and start with issue.

License

MIT