API-Dokumentation
Nexling übersetzt eine Website mit einem einzigen Script-Tag — ohne Änderungen am HTML. Wer tiefer gehen will, findet hier zusätzlich eine öffentliche REST-API, einen Export für die eigene Build-Pipeline und Webhooks.
Schnellstart
Fügen Sie diese eine Zeile in den <head> Ihrer Seite ein. Ersetzen Sie
YOUR-PROJECT-ID durch die Projekt-ID aus den Projekteinstellungen.
<script src="https://nexling.app/nl.js"
data-project="YOUR-PROJECT-ID"></script>
Mehr ist nicht nötig. Beim Laden der Seite passiert Folgendes:
- nl.js ermittelt die Sprache der Besucherin — erzwungene Sprache, zuletzt gewählte Sprache, Browsersprache, dann Standardsprache.
- Die Übersetzungen für diese Sprache werden geladen und im Speicher gehalten.
- Jeder Textknoten im DOM wird ersetzt, ebenso
placeholder,alt,titleundaria-label. - Ein
MutationObserverübersetzt auch später nachgeladene Inhalte — React, Vue und andere SPAs funktionieren ohne Zusatzkonfiguration.
Mit allen gängigen Optionen
<script src="https://nexling.app/nl.js"
data-project="YOUR-PROJECT-ID"
data-default-language="de-CH"
data-switcher="true"
data-position="bottom-right"></script>
Ausprobieren
Die öffentlichen Endpunkte benötigen keinen Schlüssel. Geben Sie Ihre Projekt-ID ein und sehen Sie die echte Antwort — die Abfrage läuft direkt aus Ihrem Browser.
Script-Attribute
Alles wird direkt am <script>-Tag konfiguriert.
| Attribut | Standard | Beschreibung |
|---|---|---|
data-project | — | Erforderlich. Die Projekt-ID aus den Projekteinstellungen. |
data-default-language | en | Sprache, in der die Seite geschrieben ist — die Ausgangssprache. |
data-current-language | — | Erzwingt eine Sprache und überschreibt die gespeicherte Auswahl. Nützlich, wenn Sie die Sprache serverseitig bestimmen. |
data-mode | auto | auto übersetzt die ganze Seite. manual übersetzt nur Elemente mit data-nl-Attributen. |
data-switcher | true | Blendet den Sprachumschalter aus, wenn auf false gesetzt. |
data-position | bottom-right | Position des Umschalters: bottom-right, bottom-left, top-right, top-left. |
data-switcher-target | — | CSS-Selektor. Rendert den Umschalter in Ihr eigenes Element statt schwebend über der Seite. |
data-api-url | https://nexling.app | Überschreibt die API-Basis-URL — nötig, wenn Sie nl.js über ein eigenes CDN ausliefern. |
data-debug | false | Schreibt ausführliche Meldungen in die Browser-Konsole. |
Element-Attribute
Im Automatikmodus brauchen Sie diese nicht. Sie sind dann sinnvoll, wenn Sie eine bestimmte Stelle über einen festen Schlüssel ansteuern oder einen Bereich schützen wollen.
<!-- Text content -->
<h1 data-nl="page_title">Willkommen</h1>
<!-- Attributes -->
<input data-nl-placeholder="search_hint" placeholder="Suchen…">
<img data-nl-alt="logo_alt" alt="Firmenlogo">
<a data-nl-title="home_tip" title="Zur Startseite">Home</a>
<button data-nl-label="close_btn" aria-label="Schliessen">×</button>
<!-- Raw HTML (use only with trusted content) -->
<div data-nl-html="rich_intro"><b>Hallo</b> Welt</div>
<!-- Never translate this subtree -->
<pre data-nl-skip>const x = "Speichern";</pre>
| Attribut | Wirkung |
|---|---|
data-nl | Textinhalt des Elements |
data-nl-html | innerHTML — nur mit vertrauenswürdigem Inhalt verwenden |
data-nl-placeholder | placeholder von Eingabefeldern |
data-nl-alt | alt von Bildern |
data-nl-title | title-Attribut |
data-nl-label | aria-label |
data-nl-skip | Schliesst das Element und alle Kindelemente von der Übersetzung aus |
data-nl-skip auf Codebeispiele, Benutzernamen, Bestellnummern
und alles, was wörtlich stehen bleiben muss. Ohne diesen Hinweis kann eine
KI-Übersetzung solche Werte verändern.
Die älteren data-lf-*-Attribute aus lf.js funktionieren weiterhin. Neue
Projekte sollten data-nl-* verwenden.
JavaScript-API
Nach dem Laden steht window.Nexling global zur Verfügung.
window.LocaleFlow bleibt als Alias erhalten.
// Switching
await Nexling.setLanguage('fr-CH');
Nexling.getLanguage(); // → 'fr-CH'
Nexling.getLanguages(); // → [{ code, name, isSource }, …]
// Keyed lookup
Nexling.t('save_button'); // → 'Speichern'
Nexling.t('greeting', { name: 'Ana' }); // → 'Hallo, Ana!'
// Re-applying
Nexling.refresh(); // re-apply current language, no refetch
Nexling.init(); // re-initialise (SPA route changes)
Nexling.restoreOriginal(); // put the original text back
Nexling.restoreToSource('de-CH');
// Events
Nexling.on('ready', () => console.log('translated'));
Nexling.on('langChanged', code => console.log('now', code));
Nexling.on('error', err => console.warn(err));
Nexling.off('ready', handler);
| Methode | Beschreibung |
|---|---|
setLanguage(code) | Wechselt die Sprache und übersetzt die Seite neu. Die Auswahl wird pro Projekt gespeichert. |
getLanguage() | Aktuell aktiver Sprachcode. |
getLanguages() | Alle für das Projekt konfigurierten Sprachen. |
t(key, vars?) | Übersetzung zu einem Schlüssel. vars ersetzt Platzhalter im Text. |
refresh() | Wendet die aktuelle Sprache erneut an, ohne neu zu laden. |
init() | Initialisiert neu — nach Routenwechseln in einer SPA. |
restoreOriginal() | Stellt sämtliche Originaltexte wieder her. |
restoreToSource(code) | Zurück zur Ausgangssprache, ohne API-Aufruf. |
on(event, fn) / off(event, fn) | Event-Listener registrieren beziehungsweise entfernen. |
Single-Page-Anwendungen
Der MutationObserver deckt die meisten Fälle bereits ab. Wenn Ihr Router
grosse Teile des DOM auf einmal austauscht, rufen Sie nach der Navigation
init() auf.
// React Router / Vue Router — re-scan after each navigation
router.afterEach(() => Nexling.init());
Events
| Event | Wird ausgelöst |
|---|---|
ready | Die erste Übersetzung ist abgeschlossen und die Seite vollständig sichtbar. |
langChanged | Die Sprache wurde gewechselt. Der Sprachcode wird übergeben. |
error | Übersetzungen konnten nicht geladen oder angewendet werden. |
REST-API
Diese Endpunkte liefert nl.js selbst an. Sie sind öffentlich, benötigen keinen Schlüssel und erlauben Cross-Origin-Zugriff — Sie können sie also direkt aus dem Browser aufrufen. Es werden ausschliesslich Übersetzungen ausgeliefert, keine Kontodaten.
Alle für das Projekt konfigurierten Sprachen, inklusive Kennzeichnung der Ausgangssprache.
curl https://nexling.app/MyApi/languages/YOUR-PROJECT-ID
[
{ "code": "de-CH", "name": "German (Switzerland)", "isSource": true },
{ "code": "fr-CH", "name": "French (Switzerland)", "isSource": false },
{ "code": "it-CH", "name": "Italian (Switzerland)", "isSource": false }
]
Flache Zuordnung von Schlüssel zu Übersetzung — passend, wenn Sie mit eigenen Schlüsseln arbeiten.
curl https://nexling.app/MyApi/translates/YOUR-PROJECT-ID/fr-CH
{
"save_button": "Enregistrer",
"learn_more": "En savoir plus"
}
Die angereicherte Fassung, die nl.js im Automatikmodus verwendet.
byKey funktioniert wie oben; byText ordnet den sichtbaren
Originaltext der Übersetzung zu und nennt zusätzlich den Elementtyp, damit gleiche
Wörter je nach Kontext unterschiedlich übersetzt werden können.
curl https://nexling.app/MyApi/map/YOUR-PROJECT-ID/fr-CH
{
"byKey": {
"learn_more": "En savoir plus"
},
"byText": {
"Mehr erfahren": { "value": "En savoir plus", "context": "a" }
}
}
byText enthält auch die Fassungen der übrigen Sprachen. Dadurch findet
eine französische Ausgangsseite dieselbe Übersetzung wie eine deutsche — Sie müssen
kein separates Projekt pro Ausgangssprache anlegen.
Export für CI/CD
Für Build-Pipelines gibt es einen Endpunkt mit Schlüssel, der Übersetzungen als Datei liefert. Erzeugen Sie den Schlüssel in den Projekteinstellungen — er wird nur einmal angezeigt und bei uns ausschliesslich als Hash gespeichert.
curl -H "X-Api-Key: nxl_your_key_here" \
https://nexling.app/api/export/json/fr-CH
curl -H "X-Api-Key: nxl_your_key_here" \
https://nexling.app/api/export/languages
Beispiel für einen Build-Schritt
# Pull the latest translations during a build
for LANG in de-CH fr-CH it-CH; do
curl -sf -H "X-Api-Key: $NEXLING_API_KEY" \
"https://nexling.app/api/export/json/$LANG" \
-o "locales/$LANG.json"
done
Webhooks
Nexling kann Ihren Server benachrichtigen, sobald sich Übersetzungen ändern — etwa um einen Rebuild anzustossen oder einen Cache zu leeren. Endpunkte verwalten Sie in den Projekteinstellungen.
| Event | Wird ausgelöst |
|---|---|
translation.completed | Eine Massenübersetzung per KI ist fertig. |
translation.updated | Übersetzungen wurden bearbeitet oder importiert. Schnelle Einzeländerungen werden zusammengefasst. |
terms.imported | Neue Texte kamen über Crawler, Autopilot oder Datei-Import hinzu. |
project.language.added | Dem Projekt wurde eine Sprache hinzugefügt. |
export.downloaded | Ein Export wurde heruntergeladen. |
Aufbau der Anfrage
POST /your-endpoint
X-Nexling-Event: translation.completed
X-Nexling-Signature: sha256=9f86d081884c7d65…
User-Agent: Nexling-Webhooks/1.0
{
"event": "translation.completed",
"projectId": "YOUR-PROJECT-ID",
"timestamp": "2026-09-07T14:22:31Z",
"data": {
"languageCode": "fr-CH",
"translatedCount": 128,
"totalTerms": 130,
"engine": "claude-haiku",
"coveragePercent": 98.5
}
}
Signatur prüfen
Jede Anfrage wird mit HMAC-SHA256 über den rohen Body signiert, mit dem Secret Ihres Endpunkts als Schlüssel. Prüfen Sie die Signatur, bevor Sie den Inhalt verarbeiten — sonst kann jede beliebige Person Ereignisse an Ihren Endpunkt senden.
const crypto = require('crypto');
function isFromNexling(rawBody, header, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody) // the raw body, before JSON.parse
.digest('hex');
// Constant-time compare — never use ===
return crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(header)
);
}
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var expected = "sha256=" + Convert.ToHexString(
hmac.ComputeHash(Encoding.UTF8.GetBytes(rawBody))).ToLowerInvariant();
var ok = CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(expected),
Encoding.UTF8.GetBytes(signatureHeader));
===.
Exportformate
Innerhalb der Anwendung lassen sich Übersetzungen pro Sprache in verschiedenen Formaten herunterladen. Programmatisch steht JSON über den oben beschriebenen CI/CD-Endpunkt zur Verfügung.
| Format | Typisch für |
|---|---|
| JSON | Web-Frontends, i18next, eigene Pipelines |
| PO | gettext — WordPress, Laravel, Python |
| XLIFF | Übersetzungsbüros und CAT-Werkzeuge |
| RESX | .NET-Anwendungen |
| strings.xml | Android |
| .strings | iOS und macOS |
| CSV | Tabellenkalkulation, manuelle Durchsicht |
Limits & Fehler
| Endpunkt | Limit | Gilt pro |
|---|---|---|
/MyApi/* | 60 Anfragen / Minute | IP-Adresse |
/api/export/* | 30 Anfragen / Minute | API-Schlüssel |
Wird ein Limit überschritten, antwortet die API so:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
{ "error": "Rate limit exceeded", "retryAfter": 60 }
Retry-After genannten Zeit einmal erneut versucht. Besucherinnen
sehen nie eine leere Seite — im schlechtesten Fall den Originaltext.
Weitere Statuscodes
| Code | Bedeutung |
|---|---|
400 | Projekt-ID ist keine gültige GUID. |
401 | X-Api-Key fehlt oder ist ungültig (nur CI/CD-Export). |
404 | Projekt oder Sprache nicht gefunden. |
429 | Limit erreicht — siehe Retry-After. |
Noch offene Fragen?
Schreiben Sie an info@nexling.ch — am besten mit Ihrer Projekt-ID, dann können wir direkt nachsehen.