This is a command-line tool designed for working with String Catalog (.xcstrings) files, such as adding and removing localized strings. It supports JSON5 and YAML formats for inputting translations.
We also provide a Custom GPT that can help you generate translations and output them in the form of an xcs command. Check it out here: xcstrings-cli Helper. (The configuration is in helpers/helper-config.md.)
-
Install xcstrings-cli using npm:
npm install -g xcstrings-cli
This will install the
xcscommand globally. -
Create a configuration file for your project by running:
xcs init
This will ask you some questions and create an
xcstrings-cli.yamlfile in the current directory.
Add a string:
# Add with key, comment, and default language string
xcs add --key greeting --comment "A greeting message." --text "Hello, World."
# Add with key, comment, and translations YAML via heredoc
xcs add \
--key greeting \
--comment "A greeting message." \
--strings << EOF
en: Hello, World.
ja: こんにちは、世界。
zh-Hans: 你好,世界。
EOF
# Or add translations JSON
xcs add \
--key greeting \
--comment "A greeting message." \
--strings << EOF
{
"en": "Hello, World.",
"ja": "こんにちは、世界。",
"zh-Hans": "你好,世界。"
}
EOF
# Start interactive mode to add translations using `$EDITOR` environment variable (e.g. `vim`)
xcs add -i
# Add translations via file
xcs add \
--key greeting \
--comment "A greeting message." \
--strings-format yaml \
--strings < translations.yaml
# Add multiple strings via heredoc
xcs add --strings << EOF
greeting:
translations:
en: Hello, World.
ja:
state: needs_review
value: こんにちは、世界。
zh-Hans: 你好,世界。
comment: A greeting message.
farewell:
translations:
en: Goodbye, World.
ja:
state: needs_review
value: さよなら、世界。
zh-Hans:
state: stale
value: さようなら、世界。
comment: A farewell message.
EOF
# Add with only key and comment
xcs add --key greeting --comment "A greeting message."Remove a string:
xcs remove --key greetingRemove all strings of specific languages:
xcs remove --languages ja zh-HansList supported languages:
If xcodeprojPaths is configured, this command lists languages from your Xcode project (knownRegions) and excludes Base. Otherwise, it lists languages appeared in the xcstrings file.
xcs languages
# en ja zh-HansList strings in the xcstrings file:
# List all strings
xcs strings
# helloWorld:
# en: "Hello, World."
# ja: "こんにちは、世界。"
# zh-Hans: "你好,世界。"
# goodbyeWorld:
# en: "Goodbye, World."
# ja: "さようなら、世界。"
# goodMorning:
# en: "Good morning."
# ja: "おはようございます。"
# ... etc.
# List strings filtered by key
xcs strings --key good*
# goodbyeWorld:
# ...
# goodMorning:
# ...
# List strings filtered by language
xcs strings --languages en
# helloWorld:
# en: "Hello, World."
# goodbyeWorld:
# en: "Goodbye, World."
# goodMorning:
# en: "Good morning."
# ... etc.
# List strings with custom format
xcs strings --format "[{{language}}] {{key}} => {{text}}"
# [en] helloWorld => "Hello, World."
# [ja] helloWorld => "こんにちは、世界。"
# [en] goodbyeWorld => "Goodbye, World."
# [ja] goodbyeWorld => "さようなら、世界。"
# ... etc.You can use xcs --help or xcs <sub-command> --help to see the list of commands and options.
Global options:
--config:string(Optional)- The custom config file path. If not specified,
xcswill look forxcstrings-cli.jsonorxcstrings-cli.json5in the current folder or its parent folders until the root.
- The custom config file path. If not specified,
--help, -h:boolean(Optional)- Show help.
--path:string(Optional)- The xcstrings file path. Defaults to
Localizable.xcstringsin the current directory, or to the firstxcstringsPathsentry in the config when present. - You can also specify the alias you set in the config file. (
xcstringsPathsentry withaliasfield)
- The xcstrings file path. Defaults to
--version, -v:boolean(Optional)- Show version.
Adds/updates one or more strings to the xcstrings file.
add command options:
--comment:string(Optional)- The comment for the string to add, intended for translators.
--interactive, -i:boolean(Optional)- Start interactive mode to add strings.
- This is useful when you don't want to record a huge command to your terminal history.
--key, -k:string(Required unless--stringscontains one or more keys)- The key of the string to add.
--language, -l:string(Optional)- The language of the string provided with
--text. - Ignored if
--textis not provided. - If not specified, it uses the source language defined as
sourceLanguagein the xcstrings file. - Validation follows
missingLanguagePolicy:skiprequires the language to be supported;includeallows any language.
- The language of the string provided with
--state:string(Optional, default:translated)- Values applied to single-key and multi-key adds:
translated,needs_review,new,stale. If omitted, strings default totranslated. - Multi-key payloads can also set per-language states with
{ state, value }; string shorthand is treated astranslated. - Available states:
translated,needs_review,new,stale
- Values applied to single-key and multi-key adds:
--strings:string(Optional)- Translation-including JSON or YAML for the key. Pass inline JSON, or provide the flag without a value to read it from stdin (heredoc/pipe).
- The format is determined by
--strings-format.
--strings-format:string(Optional, default:auto)- The format of the data provided with
--strings. Options are:auto: Auto-detect format based on content.yaml: YAML format.json: JSON format. JSON5 is also supported.
- The format of the data provided with
--text:string(Optional)- The string value for the language. If omitted, the key is created without a localization for the default language.
Removes strings from the xcstrings file based on the specified filter options.
remove command options:
--dry-run, -n:boolean(Optional, default:false)- If set to
true,xcswill only show what would be removed without actually removing anything.
- If set to
--key, -k:string(Optional iflanguagesis specified)- The key of the string to remove. If not specified, xcstrings-cli will remove all strings for the specified languages.
--languages, -l:string[](Optional ifkeyis specified)- The languages to remove. If not specified,
xcswill remove the string for all languages.
- The languages to remove. If not specified,
Lists strings in the xcstrings file, with optional filtering and formatting.
strings commands options:
--format:string(Optional)- Mustache template for per-localization output. Available variables:
{{language}},{{key}},{{text}}.
- Mustache template for per-localization output. Available variables:
--key,--key-glob:string(Optional)- Filter keys by glob pattern. This is the default key filter mode.
--key-regex:string(Optional)- Filter keys by regular expression.
--key-substring:string(Optional)- Filter keys by substring match.
--languages, -l:string[](Optional)- Include only the specified languages.
--text,--text-glob:string(Optional)- Filter translations by glob pattern. This is the default text filter mode.
--text-regex:string(Optional)- Filter translations by regular expression.
--text-substring:string(Optional)- Filter translations by substring match.
Put a config file named xcstrings-cli in the project root, using one of the following extensions:
.json: JSON format.json5: JSON5 format.yml.yaml: YAML format
Here is an example config file in JSON format:
{
"missingLanguagePolicy": "include",
"xcstringsPaths": [
"Shared/L10n/Localizable.xcstrings",
{
"alias": "utils",
"path": "packages/Utils/Sources/Utils/Resources/Localizable.xcstrings"
}
],
"xcodeprojPaths": [
"path/to/your/Project.xcodeproj"
]
}These are the settings you can specify in the config file:
- missingLanguagePolicy:
string(Optional, default:skip)- How to handle translations for languages that are not included in the
xcs languagesoutput when adding strings. Options are: skip: Only add translations for languages included in thexcs languagesoutput. (Default)include: Add translations even when they are not recognized by the Xcode project or xcs language list.
- How to handle translations for languages that are not included in the
- xcodeprojPaths:
string[](Optional)- Paths to Xcode project files (
.xcodeproj) used to detect supported languages. - If not specified,
xcswill only check the xcstrings file to detect supported languages.
- Paths to Xcode project files (
- xcstringsPaths:
(string | { alias: string; path: string })[](Optional)- Paths to xcstrings files used by
xcs. - If only one path is provided,
xcswill use it as the default xcstrings file. - If multiple paths are provided,
xcswill ask you to select an xcstrings file. - You can also specify an alias, and use it with the
--pathoption.
- Paths to xcstrings files used by
Suppose you have a xcstrings file and want to add Japanese and Simplified Chinese translations generated by LLM.
Firstly, list the strings missing those languages:
xcs strings --languages en --missing-languages ja zh-Hans
# closeAction:
# en: "Close"
# detailsAction:
# en: "Details"Then, copy the output and use it as a prompt for the LLM to generate translations. We offer xcstrings-cli Helper, a Custom GPT that can help you generate translations in the form of an xcs add command. The prompt could be like this:
closeAction:
en: "Close"
detailsAction:
en: "Details"
Languages: ja, zh-Hans
No comments needed.
Then the Custom GPT will generate YAML like this:
closeAction:
translations:
en: Close
ja: 閉じる
zh-Hans: 关闭
detailsAction:
translations:
en: Details
ja: 詳細
zh-Hans: 详情Finally, copy the generated YAML and run xcs add -i to add the translations to your xcstrings file via interactive mode.
Q: Strings are not being added for some languages. Why?
A: By default, xcs only adds translations for languages that are recognized in your Xcode project (knownRegions) or the xcstrings file. You can check which languages are recognized by running xcs languages.
If you want to add translations for languages not included in your Xcode project, you can change the missingLanguagePolicy in your config file to include.
MIT