LiveJS is an in-context JavaScript editor that lets your translators or copywriters edit your website texts and translations right on the webpage. All changes are shown in the browser and saved directly to Lokalise, not to your localization files or the database running your website. In other words, once your translators are done with the texts on your website, you would need to take care of how the changes will reach your localization files or database.
Again, this editor does not download or fetch any translations from Lokalise, its only purpose is to allow in-context editing and sync to Lokalise. However, there are some tips and tricks on how to update translations locally below.
Prerequisites
Your site is prepared for localization with localization files containing key/value pairs, i.e. in any localization file format
The project is properly set up in Lokalise
Site visitors are provided with local localization files (e.g. JSON, YML, PO) or translations from the database
Translators have accounts with Lokalise and are allowed to edit the target languages.
Getting started
Assuming you want to provide text editing access only to specific users, you need to decide at which point the Lokalise LiveJS plugin is included and initialized. There are several options for doing this, which can also be combined:
a dedicated translation environment (e.g. development or staging servers)
a certain GET parameter is supplied
a certain URL is visited
already authenticated users with a certain session variable set
Step 1. Include Lokalise LiveJS script at the end of your HTML
You need to include following script in your HTML just before the closing </body>
tag:
<script>
window.LOKALISE_CONFIG = {
projectId: "18302045592fa799a35d20.15846093",
locale: "en"
};
(function () {
var a = document.createElement("script");a.type = "text/javascript";a.async = !0;
a.src = ["https://app.lokalise.com/live-js/script.min.js?", (new Date).getTime()].join("");
document.body.appendChild(a)
})();
</script>
As mentioned above, do not include and initialize it for all of your website's visitors.
Step 2. Adjust Lokalise LiveJS script parameters
projectId
string (required)
The project ID (it must be already set up in Lokalise). You can find the project ID in Project settings.
locale
string (required)
Current locale that is being edited. It must match the language code in Lokalise.
plainKey
boolean (default false
)
Enable to convert plain key names into editable HTML elements. The key names must be wrapped (see plainKeyLeftWrapper
and plainKeyRightWrapper
parameters).
The default wrappers are {.
and .}
. If enabled, you can skip adding special data attributes to HTML elements.
plainKeyLeftWrapper
string (default {.
)
Unique key name prefix used to expose plain keys in a HTML code.
plainKeyRightWrapper
string (default .}
)
Unique key name suffix used to expose plain keys in a HTML code.
disableAdvancedHtml
boolean (default false
)
Enable editing of content-editable sections only (Bold, Italic, Headings, Paragraphs, Links and Lists will be still available in the dynamic toolbar).
onSave
function (optional, default: null
)
The callback function, which can be used to update your local database or files directly or by pulling strings from Lokalise.
The function arguments are:
updatedTranslations
array of translation objects (see below)
Successfully updated translations.
skippedTranslations
array of translation objects (see below)
Translations which were not updated, including errorMessage
, with a reason.
dismissedTranslations
array of translation objects (see below)
Translations which were canceled by a translator.
errorMessage
string
Error message (if any).
usePanelOffset
boolean
This parameter is usually set to true
. It means that the LiveJS panel will slide from the bottom of the page, slightly pushing the page's content to the top. However, if for some reason the bottom of your site is not visible (it might be hidden with some banner or overlay), set this parameter to false
.
Translation object
key (string) Lokalise translation key
translation (string) HTML\text
locale (string) Lokalise locale of translation
success (boolean) (optional) Flag indicating that translation was updated
skipped (boolean) (optional) Flag indicating that translation was skipped
errorMessage (null | string) (optional) Reason why translation was skipped
Usage example
window.LOKALISE_CONFIG = {
projectId: '98305045592fb799a15d20.15846093',
locale: 'en',
usePanelOffset: true,
onSave: function (updatedTranslations, skippedTranslations, dismissedTranslations, errorMessage) {
for (var i = 0; i < updatedTranslations.length; i++) {
$.ajax({
type: 'POST',
url: '/ajax/translations/update',
data: {
'key': updatedTranslations[i].key,
'translation': updatedTranslations[i].translation,
'locale': updatedTranslations[i].locale
},
success: function (response) {
console.info('Translation updated', response);
}
});
}
}
};
Step 3. Expose key names in HTML
The plugin needs to know which phrase on your website corresponds to which key, thus making it possible to save the changes to Lokalise once the translator finishes editing.
Depending on the plainKey
parameter you have set when initializing the snippet, you either need to wrap the translated text in any HTML element with the data-lokalise
attribute and set the data-key
attribute or just expose a wrapped key name.
Example for plainKey: false
<span data-lokalise data-key="index.hero.title">Translation platform for developers</span>
Example for plainKey: true
{.index.hero.title.}
If you are wrapping in HTML (if a plainKey
is false
), it is a good idea to make an automatic wrapper for your template engine. Here is an example for the Twig template engine:
$lokalise = new Twig_SimpleFilter('lokalise', function ($key) {
return '<span data-lokalise data-key="' . $key . '">' . __($key) . '</span>';
}, ['is_safe' => ['html']]);
$twig->addFilter($lokalise);
As you can see, this Twig filter is using the __()
function which simply returns the value of the key from a local .json
file:
global $locales;
$locales = json_decode(file_get_contents('locale/en.json'), true);
function __($key)
{
global $locales;
if ($locales[$key]) {
return $locales[$key];
}
return $key;
}
Use the filter in .twig
files:
<div class="col-md-12">
<h1 class="hero-text>
{{ "index.hero.title" | lokalise }}
</h1>
<p class="sub-text">
{{ "index.hero.subtitle" | lokalise }}
</p>
</div>
Translating placeholders, default values of input elements and aria labels
Some translations cannot be wrapped in a separate HTML tag, like placeholders, default values of input elements or aria labels. In order to translate them, add data-type-placeholder
, data-type-input
or data-type-aria-label
attributes respectively, to the element.
<input type="email" placeholder="john.doe@mail.com" data-lokalise data-key="form.email.placeholder" data-type-placeholder>
<input type="text" value="lokalise" data-lokalise data-key="default.selector" data-type-input>
<button aria-label="Close" data-lokalise data-type-aria-label data-key="aria.close.button">X</button>
The setup for dynamic websites using events (Angular JS, React, Vue etc.)
lokalise-update-elements
Dispatch this event in the case that new editable elements were loaded to the webpage. The Lokalise LiveJS script will search for them if editing mode is enabled. In the case that the configurable option syncTranslations
is enabled, it will also sync these translations with the latest ones from Lokalise.
document.dispatchEvent(new Event("lokalise-update-elements"));
lokalise-update-locale
Dispatch this event in order to update the locale of translations.
document.dispatchEvent(new CustomEvent("lokalise-update-locale", {"detail": "en_US"}));
lokalise-on-save
By listening to this event you achieve the same result as with the configurable callback function onSave
. Please note that the event detail is a Translation object.
document.addEventListener("lokalise-on-save", function(event) {
console.log(event.detail.updatedTranslations);
console.log(event.detail.skippedTranslations);
console.log(event.detail.dismissedTranslations);
console.log(event.detail.errorMessage);
});
lokalise-on-save-error
Listen for errors while saving translations. The event detail is a string with an error message.
document.addEventListener("lokalise-on-save-error", function(event) {
console.log(event.detail);
});
lokalise-on-dismiss
Listen for dismissed translations, which were cancelled by a translator.
document.addEventListener("lokalise-on-dismiss", function(event) {
console.log(event.detail);
});
lokalise-keys-parsed
Listen for plain keys to be replaced with editable elements. The event can be dispatched multiple times, when initializing and new HTML elements were added to the webpage (requires lokalise-update-elements
event).
document.addEventListener("lokalise-keys-parsed", function() {
console.log("Plain keys were parsed");
});
lokalise-keys-synced
Listen for keys to synchronize with Lokalise current translations. The event can be dispatched multiple times, when initializing and new HTML elements were added to the webpage. Keys can be synced only if the user is authenticated.
document.addEventListener("lokalise-keys-synced", function() {
console.log("Plain keys were synced");
});
lokalise-initialized
Listen for script to initialize. The event is dispatched when LiveJS has fully set itself up and parsed plain keys into editable elements.
This state does not require user authorization or key synchronization.
document.addEventListener("lokalise-initialized", function() {
console.log("LiveJs initialized");
});
lokalise-check-auth-state
Dispatch this event in the case of retrieving the current state of user authentications. LiveJs will dispatch lokalise-on-auth-state-change
as an answer.
document.dispatchEvent(new Event("lokalise-check-auth-state"));
lokalise-on-auth-state-change
Listen to this event to retrieve basic information about authentication. The event detail is an object:
// event.detail:
{
authenticated: true, // bool
user: {
name: "John Doe",
email: "john.doe@mail.com"
} // empty object if user is not logged in
}
document.addEventListener("lokalise-on-auth-state-change", function(event) {
console.log(event.detail);
});
Updating localization files (local translations)
If you're a frontend developer, you might be interested in our Vue i18n tutorial.
Once a translator is done editing a translation (and hits ⌘/Ctrl-S
to save), Lokalise LiveJS will automatically update the respective translation in Lokalise. In order to make changes visible to all visitors, you now need to update the local translation files. Depending on your initial localization setup, there are several options. These include:
Instantly update your localization files (local translations)
Use the callback function and update your local translation files (or your database) instantly after every translation is saved. For this option you need to implement the update on your back-end.
window.LOKALISE_CONFIG = {
projectId: '98305045592fb799a15d20.15846093',
locale: 'en',
onSave: function (updatedTranslations, skippedTranslations, dismissedTranslations, errorMessage) {
for (var i = 0; i < updatedTranslations.length; i++) {
$.ajax({
type: 'POST',
url: '/ajax/translations/update',
data: {
'key': updatedTranslations[i].key,
'translation': updatedTranslations[i].translation,
'locale': updatedTranslations[i].locale
},
success: function (response) {
console.info('Translation updated', response);
}
});
}
}
};
Use Lokalise API or CLI to generate translations at the build time
Some localization file formats, e.g. .po
or .yaml
, are not so easy to update. In this case, use the Lokalise exporter to get the files from Lokalise. You may still use the callback function to send a request to the Lokalise API, however the common practice is to provide your admins or translators with an explicit method of updating the translations. This could be a button on the admin panel in your back-end or a specific URL (e.g. your domain/translations/fetch).