1. Help Center
  2. Phrase for developers
  3. Installing and setting up the Phrase In-Context Editor (ICE)

Integrating the In-Context Editor into any web framework

Learn how to integrate the In-Context Editor into a custom web framework or a technology not yet covered by one of our many adapters.

The In-Context Editor is available when you choose the Advanced plan or a higher plan.

While Phrase works great without the In-Context Editor, the editor offers you even more powerful tools for your localization workflow. For this reason, we recommend using the In-Context Editor whenever possible.


In order to use the In-Context Editor your application must:

  1. Be web-based. This includes websites, web applications, mobile sites, and so on.
  2. Have access to the internet. We recommend using the In-Context Editor on a web server that all of your translators can access. However, if you don’t want to set up a separate environment, you can run the editor on your local network, or even your local machine.
  3. Use a key-value localization file structure. The In-Context Editor only works with web sites that already have translatable strings extracted and a view layer that uses a key-value structure to render translations.


There are two main steps to integrating the In-Context Editor into your framework or technology stack:

  1. Expose the names of your keys to the view or template layer.
  2. Include a small JavaScript snippet that renders the editor.

For more detailed explanations, read the sections below.

Exposing key names

Typically, a view layer renders translations by passing the name of a translatable string (i.e., its key) to some sort of translation method or view helper. This simple PHP code example shows what most helper methods look like:

$translations = array(

  "page.headline" => "Some Headline",

  "page.link.label" => "I am a link",

  "page.link.hint" => "Click me"


function translate($keyName) {

  return $translations[$keyName];


In your template, you typically would then render the output of the translate() method instead of the actual translated string:

<h1><?php echo translate("page.headline"); ?></h1>

Phrase needs to know which keys to render translations for in your template. For this reason, you’ll need to expose key names instead of translations. Keys must be rendered in the following format for Phrase to recognize them:


For example, if you would have used the key page.headline in your template, you should instead render the string {{__phrase_page.headline__}}.

The easiest way to accomplish this is to modify your translate() helper method so as to exposes key names in the required format when needed, like this:

function translate($keyName) {

  if ($phraseModeEnabled) {

    return "";

  } else {

    return $translations[$keyName];



Depending on the framework you use, you can override the translation helpers in your code or create a wrapped version to use in your templates. If you need assistance, contact Phrase support.

To learn how to expose key names in your own setup, you can review the HTML source code of a demo application.

Escaping key names and special characters

Be sure to convert key names to a format that the Phrase parser can read. Characters in the following list need to be escaped when exposed to the In-Context Editor:

Character Escape sequence Example 
< [[[[[[html_open]]]]]]    {{__phrase__<key__}} becomes 




{{__phrase__key>__}} becomes {{__phrase__[[[[[[html_close]]]]]]key__}}

If you experience parsing issues with other characters when using the In-Context Editor, contact us for assistance.

JavaScript snippet

Besides exposing the keys, you’ll need to add the In-Context Editor itself to your site. To do so, you use a JavaScript snippet that includes all the code required to:

  • communicate with the Phrase API
  • render the user interface
  • provide login
  • and much more

Include the JavaScript snippet in your application layout and replace YOUR_PROJECT_ID with the ID for your project. You can find your project’s ID in your project settings, in the Translation Center.



    projectId: 'YOUR_PROJECT_ID'


  (function() {

    var phraseapp = document.createElement('script'); phraseapp.type = 'text/javascript'; phraseapp.async = true;

    phraseapp.src = ['https://', 'phraseapp.com/assets/in-context-editor/2.0/app.js?', new Date().getTime()].join('');

    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(phraseapp, s);



There are several configuration parameters you can adjust, but most users will be fine with the default settings.