diff --git a/docs/i18n.md b/docs/i18n.md
index 99f20d54a63..6f1a88b6e2e 100644
--- a/docs/i18n.md
+++ b/docs/i18n.md
@@ -84,3 +84,127 @@ the JSON to the repo.
# build the JSON.
NODE_APP_INSTANCE=[MY_APP] bin/build-locales
```
+
+## Setting up translations
+
+To set up a component to be translated there are two pieces of code to know
+about.
+
+### Jed
+
+We use [Jed](https://slexaxton.github.io/Jed/) as the API for providing
+`gettext` functions inside React components. An initialized `Jed` instance
+has all the `gettext` related functionality exposed as methods. There is a
+fancy chained API but we've stuck to a more traditional approach.
+
+Before we get into how to make use of these functions let's take a look at
+how the Jed instance is exposed to our components.
+
+### The Translation Provider
+
+The translation provider is used to pass down a Jed instance via context to
+components lower down in the component hierarchy. This part is already done
+for you in addons-frontend. So you should only need to worry
+about wrapping your components as detailed in the next section.
+
+## The translate component wrapper.
+
+The translate Higher Order Component is a helper that wraps any component
+and takes the Jed `i18n` instance from context and makes it available in
+the wrapped component's props.
+
+Here's an example of a basic component setup for translation:
+
+
+```javascript
+import React, { PropTypes } from 'react';
+import translate from 'core/i18n/translate';
+
+
+export class MyTranslatedComponent extends React.Component {
+ static propTypes = {
+ i18n: PropTypes.object.isRequired,
+ }
+
+ render() {
+ const { i18n } = this.props;
+ return (
+
+
{i18n.gettext('Something translated')}
+
+ );
+ }
+}
+
+export default translate()(MyTranslatedComponent);
+```
+
+That's pretty much all there is to it.
+
+## Using the Jed API
+
+Once you have `i18n` available to your component you can then use
+any of the Jed methods exposed on the `i18n` object.
+
+```javascript
+gettext = function ( key )
+dgettext = function ( domain, key )
+dcgettext = function ( domain, key, category )
+ngettext = function ( singular_key, plural_key, value )
+dngettext = function ( domain, singular_ley, plural_key, value )
+dcngettext = function ( domain, singular_key, plural_key, value, category )
+pgettext = function ( context, key )
+dpgettext = function ( domain, context, key )
+npgettext = function ( context, singular_key, plural_key, value )
+dnpgettext = function ( domain, context, singular_key, plural_key, value )
+dcnpgettext = function ( domain, context, singular_key, plural_key, value, category )
+sprintf = function ( string, substitutions)
+```
+
+### Using `sprintf`
+
+As you can see a sprintf function is also available. You can use this to
+provide substitutions in gettext wrapped strings.
+
+There are two flavours to this, numbered placeholders or named ones.
+
+Here's the numbered approach:
+
+```javascript
+i18n.sprintf(i18n.gettext('I like your %1$s %2$s.'), 'red', 'shirt'));
+```
+
+and here's the named arg approach:
+
+```javascript
+i18n.sprintf(i18n.gettext('I like your %(colour)s %(garment)s.'), { colour: 'red', garment: 'shirt' }));
+```
+
+Both of these approaches allow for translators to re-order the substitution
+vars.
+
+### Guidance on HTML in translations
+
+Generally we're looking to avoid having HTML in the middle of translation
+strings as much as possible.
+
+If you need HTML it's better to use substitutions to add the HTML than
+leave HTML in the translation. Take the following string as an example:
+
+```javascript
+i18n.gettext('Take a look at the documentation');
+```
+
+Using `sprintf` we can provide use start and end substitutions. This way
+there's no HTML in the extracted string.
+
+```javascript
+i18n.sprintf(i18n.gettext(
+ 'Take a look at the %(start_link)sdocumentation%(end_link)s'),
+ { start_link: '', end_link: '' });
+```
+
+You can also use DOMPurify to sanitize strings that may contain HTML
+following substitutions so that anything not explicitly allowed is removed.
+DOMpurify will also help protect against malformed HTML in case opening
+and closing tag substitutions vars get swapped around inadvertently.