Browse files

Docusaurus documentation

Summary: An initial stab at our fbt OSS documentation.  Note that most of this is docusaurus bootstrap/boilerplate.  The documentation lives in the (you guessed it) `docs` folder.

Reviewed By: w1106c

Differential Revision: D13532528

fbshipit-source-id: 2796c97bace735fd2549dee011669632b80379b8
  • Loading branch information...
jrwats authored and facebook-github-bot committed Dec 22, 2018
1 parent 0489ea4 commit 92f1cd933bf27d8f16642ca4a65d94ab452cdf3f
@@ -0,0 +1,5 @@
# Code of Conduct

Facebook has adopted a Code of Conduct that we expect project participants to adhere to.
Please read the [full text](
so that you can understand what actions will and will not be tolerated.
@@ -0,0 +1,39 @@
# Contributing to **fbt**x
We want to make contributing to this project as easy and transparent as
## Our Development Process
We sync our internal repo with this github repo via regularly scheduled cron jobs. You can expect to see any updates we make internally show up here shortly after.
## Pull Requests
We actively welcome your pull requests.
1. Fork the repo and create your branch from `master`.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation.
4. Ensure the test suite passes.
5. Make sure your code lints.
6. If you haven't already, complete the Contributor License Agreement ("CLA").
## Contributor License Agreement ("CLA")
In order to accept your pull request, we need you to submit a CLA. You only need
to do this once to work on any of Facebook's open source projects.
Complete your CLA here: <>
## Issues
We use GitHub issues to track public bugs. Please ensure your description is
clear and has sufficient instructions to be able to reproduce the issue.
Facebook has a [bounty program]( for the safe
disclosure of security bugs. In those cases, please go through the process
outlined on that page and do not file a public issue.
## Coding Style
* 2 spaces for indentation rather than tabs
* 80 character line length
## License
By contributing to fbt, you agree that your contributions will be licensed
under the LICENSE file in the root directory of this source tree.
@@ -0,0 +1,47 @@
# fbt
FBT is an internationalization framework designed to be both intuitive and powerful, but also flexible and complete. It the following problems:
* Organizing your source text for translation
* Composing grammatically correct UI
* i18n-driven source-code bloat

## Examples
[See here](

## Requirements
* [node]()
* yarn
* babel

## Building fbt

## Installing __________
git clone;
cd fbt/demo-app;
yarn install;
yarn manifest;
yarn collect-fbts;
yarn translate-fbts;
yarn start;

## How fbt works
FBT works by transforming your `<fbt>` and `fbt(...)` constructs in
Babel plugins. These plugins serve to extact strings from source and
lookup translate payloads generated at build-time.

## Full documentation

## Join the __________ community
* Website:
* Facebook page:
* Slack:
See the CONTRIBUTING file for how to help out.

## License
fbt is MIT licensed, as found in the LICENSE file.
@@ -0,0 +1,55 @@
id: api_intro
title: The FBT API
sidebar_label: Introduction
The fbt framework has two (mostly) equivalent APIs: A declarative JSX-style `<fbt>` tag API and a "vanilla" or "functional" `fbt(...)` API that more closely resembles standard JavScript. In general, you can compose your translatable text in either format. As the following example illustrates, the child of the `<fbt>` shows up as the first argument to `fbt` and any attributes show up in the optional third argument parameter. The `desc` (text description) argument is the exception to this rule because it is a *required* parameter and attribute in `fbt(...)` and `<fbt>` respectively.

Let's start with a simple of example

## JSX `<fbt />` API
<fbt project="foo" desc="a simple example">
Hello, World!
### Required attributes
* `desc`: description of text to be translated

### Optional attributes
* **author** `string`: Text author
* **project** `string`: Project to which the text belongs
* **preserveWhitespace** `bool`: (Default: `false`)
FBT normally consolidates whitespace down to one space (`' '`).
Turn this off by setting this to `true`
* **subject** `IntlVariations.GENDER_*`: Pass an [implicit subject](implicit_params) gender to a partially formed text
* **common** `bool`: Use a "common" string repository
* **doNotExtract** `bool`: Informs [collection](collection) to skip this string (useful for tests/mocks)


## "Vanilla" `fbt(...)` API

fbt('Hello, World, 'a simple example', {project:"foo"})
#### Required arguments
1. Text to translate
2. Description of text to be translated
#### Optional parameters
3. Options object - same optional arguments as the `<fbt>` [attributes above](api_intro#optional-attributes)
## Docblock defaults
Defaults for the above optional attributes may be provided in the
doblock with the `@fbt` pragma. It uses a straight `JSON.parse` to
interpret this, so you'll have to make sure your object is parseable. (i.e. keys should be wrapped in `"double quotes"`)
* @fbt {"author": "me", "project": "awesome sauce"}
@@ -0,0 +1,69 @@
id: autoparam
title: Auto-parameterization
sidebar_label: Auto-parameterization

`<fbt>` will automatically wrap any non-fbt children in the top-level
`<fbt>` as though they were written with an `<fbt:param>` where it's
param `name` is the value of the child texts. It will pull any child
text into the parameter name, including those of recursive structures.
<span style="color:red"> **Note this is inherently not available to
the `fbt(...)` API** </span>

<fbt desc="auto-wrap example">
Go on an
<a href="#">
<span>awesome</span> vacation

When extracted for translation, the result is

"phrases": [
"hashToText": {
"6b034a8291e7e7a8241fe7b914106066": "Go on an {=awesome vacation}"
"desc": "auto-wrap example",
"hashToText": {
"e9b2d1a9d1ae7961c40dfac907d50d64": "{=awesome} vacation"
"desc": "In the phrase: \"Go on an {=awesome vacation}\"",
"hashToText": {
"63a89a77a42a9681b88086dc938ec5e3": "awesome"
"desc": "In the phrase: \"Go on an {=awesome} vacation\"",
"childParentMappings": {
"1": 0,
"2": 1

Notice the description for "vacation" is auto-generated with an `"In
the phrase: ..."` prefix. Additionally we use a convention of an `=`
prefix in the interpolation `{=awesome vacation}` to signal to the
translator that this exact word or phrase goes in the associated outer

Furthermore, we provide a mapping `{<childIndex>: <parentIndex>}` in
the collection output `childParentMappings`. At Facebook, we use
these to display all relevant inner and outer strings when translating
any given piece of text. We recommend you do the same in whatever
translation framework you use. Context is crucial for accurate
@@ -0,0 +1,83 @@
id: collection
title: Extracting FBTs
sidebar_label: Extracting translatable texts
We provide `collectFbts.js` as a utility for collecting strings. It expects a JSON input of:
<enumManifestPath>: [
<path1>, <path2>, ..., <pathN>
`enumManifestPath` doesnt not need to point to a valid enum manifest, but if you use a [shared enum](enums#shared-enums) it's required.

The enum-manifest should be a `"JSON.parseable"` mapping from all known enums in your app to their key/value pairs they respectively represent:
"EnumA": {
"keyA1": "valA1",
"keyAN": "valAN"
"EnumX": {
"keyX1": "valX1",
"keyXM": "valXM"
We've provdied `manifest.js` as an easy way to generate this manifest from a given source tree

`collectFbts.js` will output a JSON object in the following format:

"phrases": [
"hashToText": {
<hash>: <text>,
"line_beg": <beginning_line>,
"col_beg": <beginning_col>,
"line_end": <end_line>,
"col_end": <col_end>,
"type": "text"|"table",
"desc": <description>,
"project": <project>,
"jsfbt": string|{t: <table>, m: <metadata>},
childParentMapping: {
<childIdx>: <parentIdx>

`phrases` here represents all the *source* information we need to
process and produce an `fbt._(...)` callsite's final payload. When
combined with corresponding translations to each `hashToText` entry we
can produce the translated payloads `fbt._()` expects

When it comes to moving from source text to translations, what is most
pertinent is the `hashToText` payload containing all relevant texts
with their identifying hash. You can provide a custom hash module to
`collectFbts` if you so choose. It defaults to md5.

### A note on hashes

In the FBT framework, there are 2 main places we uses hashes for
identification: **text** and **fbt callsite**. The hashToText mapping
above represents the hash (using whichever algorithm was chosen in
`collectFbt`) of the **text** and its **description**. This is used
when *building* the translated payloads

The hash of the callsite (defaulting to `jenkins` hash) is used to
lookup the payload in `FbtTranslations`. This is basically the has of
the object you see in `jsfbt`.

See [Translating FBTs](translating) for getting your translations in
the right format.
@@ -0,0 +1,6 @@
id: doc4
title: API

The FBT API is comprised of a top-level `fbt(...)` call or `<fbt>...</fbt>` instance with a handful of fbt constructs that can be used to alter the text generated
Oops, something went wrong.

0 comments on commit 92f1cd9

Please sign in to comment.