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, Formularmeldungen 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 gemeinsam genutzten Inhalten
Betrachten Sie diese Navigationskonfiguration, die in Ihrer gesamten App verwendet wird:
// navData.ts
export const navData = [
{
label: 'Startseite',
description: 'Startseite',
href: '/'
},
{
label: 'Über uns',
description: 'Informationen zum Unternehmen',
href: '/about'
}
];Um das zu internationalisieren, müssten Sie typischerweise:
- Es in eine Funktion umwandeln, die eine Übersetzungsfunktion entgegennimmt
- Jede Verwendung so anpassen, dass die Funktion mit
taufgerufen wird - Die entstehende Komplexität in Ihrer Codebasis verwalten
Das erzeugt Wartungsaufwand und macht Ihren Code schwerer lesbar. Die Funktion msg löst das, indem Sie Zeichenfolgen direkt im Code zur Übersetzung markieren und sie bei Bedarf dekodieren können.
Schnellstart
Verwende msg, um Zeichenketten zu markieren, und useMessages, um sie zu dekodieren:
// navData.ts - Zeichenketten für die Übersetzung markieren
import { msg } from 'gt-next';
export const navData = [
{
label: msg('Startseite'),
description: msg('Startseite'),
href: '/'
},
{
label: msg('Über uns'),
description: msg('Informationen zum Unternehmen'),
href: '/about'
}
];// Komponentenverwendung – Markierte Strings dekodieren
import { useMessages } from 'gt-next';
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:
msgcodiert Strings mit Übersetzungsmetadaten - Dekodierungsphase:
useMessagesodergetMessagesdekodieren und übersetzen die Strings
// msg() kodiert die Zeichenfolge mit Metadaten
const encoded = msg('Hallo, Welt!');
console.log(encoded); // "Hallo, Welt!:eyIkX2hhc2giOiJkMjA3MDliZGExNjNlZmM2In0="
// useMessages() dekodiert und übersetzt
const m = useMessages();
const translated = m(encoded); // „Hallo, Welt!“ in der Sprache des BenutzersKodierte Zeichenfolgen aus msg können nicht direkt verwendet werden – sie müssen mit useMessages oder getMessages decodiert werden.
Client- gegenüber Server-Nutzung
Client-Komponenten
Verwenden Sie den Hook useMessages:
import { useMessages } from 'gt-next';
const encodedString = msg('Hallo, Welt!');
function MyComponent() {
const m = useMessages();
return <div>{m(encodedString)}</div>;
}Server-Komponenten
Verwenden Sie die Funktion getMessages:
import { getMessages } from 'gt-next/server';
const encodedString = msg('Hallo, Welt!');
async function MyServerComponent() {
const m = await getMessages();
return <div>{m(encodedString)}</div>;
}Original-Strings mit decodeMsg abrufen
Manchmal müssen Sie auf den Original-String ohne Übersetzung zugreifen, etwa für Logging, Debugging oder Vergleiche. Verwenden Sie decodeMsg, um den Originaltext zu extrahieren:
import { decodeMsg } from 'gt-next';
const encoded = msg('Hallo, Welt!');
const original = decodeMsg(encoded); // „Hallo, Welt!“ (Original)
const translated = m(encoded); // „Hallo, Welt!“ (in der Sprache des/der Nutzer:in)
// Nützlich fürs Logging oder Debugging
console.log('Originalzeichenfolge:', decodeMsg(encoded));
console.log('Übersetzte Zeichenfolge:', m(encoded));Anwendungsfälle für decodeMsg
- Entwicklung & Debugging: Originalstrings zur Fehleranalyse protokollieren
- Standardwert‑Behandlung: Originaltext verwenden, wenn Übersetzungen fehlschlagen
- String‑Vergleiche: Mit bekannten Originalwerten vergleichen
- Analytics: Nutzung der Originalstrings nachverfolgen
// Beispiel: Fallback-Behandlung
function getDisplayText(encodedStr) {
const m = useMessages();
try {
return m(encodedStr);
} catch (error) {
console.warn('Übersetzung fehlgeschlagen, Original wird verwendet:', decodeMsg(encodedStr));
return decodeMsg(encodedStr);
}
}Verwendung von Variablen
Für Strings mit dynamischem Inhalt Platzhalter verwenden und Variablen übergeben:
// Zeichenkette mit Variablen markieren
const items = 100;
export const pricing = [
{
name: 'Basic',
price: 100,
description: msg('Der Basic‑Tarif umfasst {items} Einträge', { items })
}
];// Use in component
function PricingCard() {
const m = useMessages();
return (
<div>
<h3>{pricing[0].name}</h3>
<p>{m(pricing[0].description)}</p>
</div>
);
}ICU Message Format
Für fortgeschrittenes Formatieren verwenden Sie die ICU-Syntax:
const count = 10;
const message = msg('Im Warenkorb {count, plural, =0 {ist kein Artikel} =1 {ist ein Artikel} other {sind {count} Artikel}}', { count });Erfahren Sie mehr über das ICU Message Format in der Unicode-Dokumentation.
Beispiele
Navigationskonfiguration
// config/navigation.ts
import { msg } from 'gt-next';
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('Hilfecenter'), href: '/help' },
{ label: msg('Dokumentation'), href: '/docs' },
{ label: msg('API-Referenz'), href: '/api' }
]
}
];// components/Navigation.tsx
import { useMessages } from 'gt-next';
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-next';
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', { min: 8 }),
maxLength: msg('Darf nicht mehr als {max} Zeichen enthalten', { max: 100 })
},
success: {
saved: msg('Änderungen erfolgreich gespeichert'),
sent: msg('Nachricht erfolgreich gesendet'),
updated: msg('Profil aktualisiert')
},
errors: {
network: msg('Netzwerkfehler – bitte versuchen Sie es erneut'),
server: msg('Serverfehler – bitte wenden Sie sich an den Support'),
timeout: msg('Die Anfrage hat ein Zeitlimit überschritten – bitte versuchen Sie es erneut')
}
};// components/ContactForm.tsx
import { useMessages } from 'gt-next';
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-next';
function mockProducts() {
return [
{ name: 'iPhone 15', company: 'Apple', category: 'Electronics' },
{ name: 'Galaxy S24', company: 'Samsung', category: 'Electronics' }
];
}
export function getProductData() {
const products = mockProducts();
return products.map(product => ({
...product,
description: msg('{name} ist ein {category}-Produkt von {company}', {
name: product.name,
category: product.category,
company: product.company
})
}));
}// components/ProductList.tsx
import { useMessages } from 'gt-next';
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
Encoded Strings direkt verwenden
Verwenden Sie die Ausgabe von msg niemals direkt:
// ❌ Falsch – verschlüsselten String direkt verwendet
const encoded = msg('Hello, world!');
return <div>{encoded}</div>; // Zeigt den verschlüsselten String, nicht die Übersetzung
// ✅ Richtig – den String zuerst entschlüsseln
const encoded = msg('Hello, world!');
const m = useMessages();
return <div>{m(encoded)}</div>; // Zeigt die korrekte ÜbersetzungDynamische Inhalte in msg()
Strings müssen zur Buildzeit bekannt sein:
// ❌ Falsch – dynamisches Template-Literal
const name = 'John';
const message = msg(`Hallo, ${name}`); // Buildzeitfehler
// ✅ Richtig – Variablen verwenden
const name = 'John';
const message = msg('Hallo, {name}', { name });Vergessen zu decodieren
Jeder msg-String muss decodiert 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 kodierte Zeichenfolge
// ✅ Korrekt – beim Verwenden dekodieren
const m = useMessages();
return <h1>{m(config.title)}</h1>; // Zeigt übersetzten TitelNächste Schritte
- Leitfaden zu Dictionaries – Übersetzungen mit strukturierten Daten organisieren
- Leitfaden zu Sprachen – Unterstützte Sprachen konfigurieren
- API Reference:
Wie ist diese Anleitung?