Geteilte Strings
So internationalisieren Sie Strings, die in mehreren Komponenten und files verwendet werden
Geteilte Strings sind Textwerte, die an mehreren Stellen in Ihrer Anwendung verwendet werden – etwa Navigationslabels, Formularhinweise oder Konfigurationsdaten. Anstatt die Übersetzungslogik überall zu duplizieren, verwenden Sie msg, um Strings für die Übersetzung zu markieren, und useMessages, um sie zu dekodieren.
Das Problem mit geteilten Inhalten
Betrachte diese Navigationskonfiguration, die in deiner App verwendet wird:
// navData.ts
export const navData = [
{
label: 'Startseite',
description: 'Die Startseite',
href: '/'
},
{
label: 'Über uns',
description: 'Informationen über das Unternehmen',
href: '/about'
}
];Um das zu internationalisieren, müssten Sie in der Regel:
- Es in eine Funktion umwandeln, die eine Übersetzungsfunktion entgegennimmt
- Alle Verwendungen so anpassen, dass die Funktion mit
taufgerufen wird - Die daraus entstehende Komplexität im gesamten Code verwalten
Das erzeugt Wartungsaufwand und macht den Code schwerer lesbar. Die Funktion msg löst das, indem sie es ermöglicht, Strings direkt im Code zur Übersetzung zu markieren und sie bei Bedarf zu decodieren.
Schnellstart
Verwenden Sie msg, um Strings zu markieren, und useMessages, um sie zu dekodieren:
// navData.ts - Zeichenketten für Übersetzung markieren
import { msg } from 'gt-react';
export const navData = [
{
label: msg('Startseite'),
description: msg('Die Startseite'),
href: '/'
},
{
label: msg('Über uns'),
description: msg('Informationen über das Unternehmen'),
href: '/about'
}
];// Komponenten-Verwendung – Markierte Strings dekodieren
import { useMessages } from 'gt-react';
import { navData } from './navData';
function Navigation() {
const m = useMessages();
return (
<nav>
{navData.map((item) => (
<a key={item.href} href={item.href} title={m(item.description)}>
{m(item.label)}
</a>
))}
</nav>
);
}Funktionsweise gemeinsamer Strings
Das System für gemeinsame Strings arbeitet in zwei Phasen:
- Markierungsphase:
msgkodiert Strings mit Übersetzungsmetadaten - Dekodierphase:
useMessagesdekodiert und übersetzt die Strings
// msg() kodiert den String mit Metadaten
const encoded = msg('Hello, world!');
console.log(encoded); // "Hello, world!:eyIkX2hhc2giOiJkMjA3MDliZGExNjNlZmM2In0="
// useMessages() dekodiert und übersetzt
const m = useMessages();
const translated = m(encoded); // "Hello, world!" in der Sprache des NutzersEncodierte Strings aus msg können nicht direkt verwendet werden – sie müssen mit useMessages decodiert werden.
Komponenten
Verwenden Sie den Hook useMessages:
import { useMessages } from 'gt-react';
const encodedString = msg('Hello, world!');
function MyComponent() {
const m = useMessages();
return <div>{m(encodedString)}</div>;
}Originaltexte mit decodeMsg abrufen
Manchmal müssen Sie auf den ursprünglichen Text ohne Übersetzung zugreifen, etwa für Logging, Debugging oder Vergleiche. Verwenden Sie decodeMsg, um den Originaltext zu extrahieren:
import { decodeMsg } from 'gt-react';
const encoded = msg('Hello, world!');
const original = decodeMsg(encoded); // „Hello, world!" (Original)
const translated = m(encoded); // „Hello, world!" (in der Sprache des Benutzers)
// Nützlich für Logging oder Debugging
console.log('Original-String:', decodeMsg(encoded));
console.log('Übersetzter String:', m(encoded));Anwendungsfälle für decodeMsg
- Entwicklung & Debugging: Originalstrings zur Fehlerbehebung protokollieren
- Fallback-Handhabung: Originaltext verwenden, wenn Übersetzungen fehlschlagen
- String-Vergleiche: Mit bekannten Originalwerten vergleichen
- Analytics: Nutzung des Originaltexts nachverfolgen
// Beispiel: Standardwert-Behandlung
function getDisplayText(encodedStr) {
const m = useMessages();
try {
return m(encodedStr);
} catch (error) {
console.warn('Übersetzung fehlgeschlagen, verwende Original:', decodeMsg(encodedStr));
return decodeMsg(encodedStr);
}
}Verwendung von Variablen
Für Zeichenketten mit dynamischem Inhalt verwenden Sie Platzhalter und übergeben Variablen:
// String mit Variablen markieren
const items = 100;
export const pricing = [
{
name: 'Basic',
price: 100,
description: msg('Der Basic-Tarif umfasst {items} Artikel', { items })
}
];// In Komponente verwenden
function PricingCard() {
const m = useMessages();
return (
<div>
<h3>{pricing[0].name}</h3>
<p>{m(pricing[0].description)}</p>
</div>
);
}ICU-Nachrichtenformat
Für fortgeschrittene Formatierung verwenden Sie die ICU-Syntax:
const count = 10;
const message = msg('{count, plural, =0 {Es sind keine Artikel} =1 {Es ist ein Artikel} other {Es sind {count} Artikel}} im Warenkorb', { count });Erfahren Sie in der Unicode-Dokumentation mehr über das ICU Message Format.
Beispiele
Navigationseinstellungen
// config/navigation.ts
import { msg } from 'gt-react';
export const mainNav = [
{
label: msg('Startseite'),
href: '/',
icon: 'home'
},
{
label: msg('Produkte'),
href: '/products',
icon: 'package'
},
{
label: msg('Über uns'),
href: '/about',
icon: 'info'
}
];
export const footerLinks = [
{
title: msg('Unternehmen'),
links: [
{ label: msg('Über uns'), href: '/about' },
{ label: msg('Karriere'), href: '/careers' },
{ label: msg('Kontakt'), href: '/contact' }
]
},
{
title: msg('Support'),
links: [
{ label: msg('Hilfe-Center'), href: '/help' },
{ label: msg('Dokumentation'), href: '/docs' },
{ label: msg('API-Referenz'), href: '/api' }
]
}
];// components/Navigation.tsx
import { useMessages } from 'gt-react';
import { mainNav } from '../config/navigation';
function Navigation() {
const m = useMessages();
return (
<nav>
{mainNav.map((item) => (
<a key={item.href} href={item.href}>
<Icon name={item.icon} />
{m(item.label)}
</a>
))}
</nav>
);
}Formularkonfiguration
// config/forms.ts
import { msg } from 'gt-react';
export const formMessages = {
placeholders: {
email: msg('Geben Sie Ihre E‑Mail-Adresse ein'),
password: msg('Geben Sie Ihr Passwort ein'),
message: msg('Geben Sie hier Ihre Nachricht ein …')
},
actions: {
send: msg('Nachricht senden'),
save: msg('Änderungen speichern'),
cancel: msg('Abbrechen')
},
validation: {
required: msg('Dieses Feld ist erforderlich'),
email: msg('Bitte geben Sie eine gültige E‑Mail-Adresse ein'),
minLength: msg('Mindestens {min} Zeichen erforderlich', { min: 8 }),
maxLength: msg('Darf {max} Zeichen nicht überschreiten', { max: 100 })
},
success: {
saved: msg('Änderungen erfolgreich gespeichert'),
sent: msg('Nachricht erfolgreich gesendet'),
updated: msg('Profil aktualisiert')
},
errors: {
network: msg('Netzwerkfehler – bitte erneut versuchen'),
server: msg('Serverfehler – bitte den Support kontaktieren'),
timeout: msg('Zeitüberschreitung – bitte erneut versuchen')
}
};// components/ContactForm.tsx
import { useMessages } from 'gt-react';
import { formMessages } from '../config/forms';
function ContactForm() {
const m = useMessages();
const [errors, setErrors] = useState({});
return (
<form>
<input
type="email"
placeholder={m(formMessages.placeholders.email)}
required
/>
{errors.email && <span>{m(formMessages.validation.email)}</span>}
<button type="submit">
{m(formMessages.actions.send)}
</button>
</form>
);
}Dynamische Inhaltserstellung
// utils/productData.ts
import { msg } from 'gt-react';
function mockProducts() {
return [
{ name: 'iPhone 15', company: 'Apple', category: 'Elektronik' },
{ name: 'Galaxy S24', company: 'Samsung', category: 'Elektronik' }
];
}
export function getProductData() {
const products = mockProducts();
return products.map(product => ({
...product,
description: msg('{name} ist ein Produkt aus dem Bereich {category} von {company}', {
name: product.name,
category: product.category,
company: product.company
})
}));
}// components/ProductList.tsx
import { useMessages } from 'gt-react';
import { getProductData } from '../utils/productData';
function ProductList() {
const m = useMessages();
const products = getProductData();
return (
<div>
{products.map(product => (
<div key={product.name}>
<h3>{product.name}</h3>
<p>{m(product.description)}</p>
</div>
))}
</div>
);
}Häufige Probleme
Encodierte Zeichenketten direkt verwenden
Verwenden Sie die Ausgabe von msg niemals direkt:
// ❌ Falsch - kodierter String wird direkt verwendet
const encoded = msg('Hello, world!');
return <div>{encoded}</div>; // Zeigt kodierten String, nicht die Übersetzung
// ✅ Richtig - String zuerst dekodieren
const encoded = msg('Hello, world!');
const m = useMessages();
return <div>{m(encoded)}</div>; // Zeigt die korrekte Übersetzung anDynamische Inhalte in msg()
Zeichenfolgen müssen zur Build‑Zeit bekannt sein:
// ❌ Falsch – dynamisches Template-Literal
const name = 'John';
const message = msg(`Hello, ${name}`); // Build-Time-Fehler
// ✅ Richtig – Variablen verwenden
const name = 'John';
const message = msg('Hello, {name}', { name });Das Dekodieren vergessen
Jeder msg-String muss dekodiert werden:
// ❌ Dekodierung fehlt
const config = {
title: msg('Dashboard'),
subtitle: msg('Willkommen zurück')
};
// Später in der Komponente – Dekodierung vergessen
return <h1>{config.title}</h1>; // Zeigt eine kodierte Zeichenkette
// ✅ Korrekt – beim Verwenden dekodieren
const m = useMessages();
return <h1>{m(config.title)}</h1>; // Zeigt den übersetzten TitelNächste Schritte
- Dictionaries Guide - Übersetzungen mit strukturierten Daten organisieren
- Languages Guide - Unterstützte Sprachen konfigurieren
- API Reference:
Wie ist diese Anleitung?