Cadenas
Cómo internacionalizar cadenas de texto sin formato con useGT y getGT
La traducción de cadenas ofrece acceso directo a traducciones de texto sin JSX, ideal para atributos, propiedades de objetos y valores de texto sin formato. Usa useGT en componentes sincrónicos y getGT en componentes asincrónicos.
Uso sincrónico vs asincrónico
- Componentes sincrónicos: hook
useGTpara componentes de React - Componentes asincrónicos: función asíncrona
getGTpara componentes asincrónicos
Comenzar rápido
Componentes síncronos
import { useGT } from 'gt-next';
function MyComponent() {
const t = useGT();
return (
<input
placeholder={t('Introduce tu correo electrónico')}
title={t('Campo de correo electrónico')}
/>
);
}Componentes asincrónicos
import { getGT } from 'gt-next/server';
async function MyServerComponent() {
const t = await getGT();
return (
<input
placeholder={t('Introduce tu correo electrónico')}
title={t('Campo de correo electrónico')}
/>
);
}Cuándo usar la traducción de cadenas
La traducción de cadenas es ideal cuando necesitas texto plano en lugar de JSX:
Atributos de HTML
const t = useGT();
<input
placeholder={t('Buscar productos...')}
aria-label={t('Campo de búsqueda de productos')}
title={t('Escribe para buscar en nuestro catálogo')}
/>Propiedades de objetos
const t = useGT();
const user = {
name: 'John',
role: 'admin',
bio: t('Desarrollador de software con 5 años de experiencia en React'),
status: t('Disponible actualmente para proyectos')
};Configuración y constantes
const t = useGT();
const navigationItems = [
{ label: t('Inicio'), href: '/' },
{ label: t('Productos'), href: '/products' },
{ label: t('Contacto'), href: '/contact' }
];Cuándo usar <T> en su lugar
Usa el componente <T> para contenido JSX:
// ✅ Usa <T> para contenido JSX
<T><p>¡Bienvenido(a) a <strong>nuestra tienda</strong>!</p></T>
// ✅ Usa traducción de cadenas para texto sin formato
<input placeholder={t('Buscar productos')} />Uso de variables
Variables básicas
Sustituye los marcadores por valores dinámicos:
const t = useGT();
const itemCount = 5;
// String with placeholder
const message = t('Tienes {count} artículos en tu carrito', { count: itemCount });
// Resultado: "Tienes 5 artículos en tu carrito"Varias variables
const t = useGT();
const order = { id: 'ORD-123', total: 99.99, date: '2024-01-15' };
const confirmation = t(
'El pedido {orderId} por ${total} se efectuó el {date}',
{
orderId: order.id,
total: order.total,
date: order.date
}
);Formato de mensajes ICU
Para un formateo avanzado, usa la sintaxis de ICU:
const t = useGT();
translate('Hay {count, plural, =0 {ningún artículo} =1 {un artículo} other {{count} artículos}} en el carrito', { count: 10 });Obtén más información sobre ICU message format en la documentación de Unicode.
Ejemplos
Campos de formulario
import { useGT } from 'gt-next';
function ContactForm() {
const t = useGT();
return (
<form>
<input
type="email"
placeholder={t('Introduce tu correo electrónico')}
aria-label={t('Campo de correo electrónico')}
/>
<textarea
placeholder={t('Cuéntanos sobre tu proyecto...')}
aria-label={t('Descripción del proyecto')}
/>
<button type="submit">
{t('Enviar mensaje')}
</button>
</form>
);
}Menú de navegación
import { useGT } from 'gt-next';
function Navigation() {
const t = useGT();
const menuItems = [
{ label: t('Inicio'), href: '/', icon: 'home' },
{ label: t('Acerca de'), href: '/about', icon: 'info' },
{ label: t('Servicios'), href: '/services', icon: 'briefcase' },
{ label: t('Contacto'), href: '/contact', icon: 'mail' }
];
return (
<nav>
{menuItems.map((item) => (
<a key={item.href} href={item.href} title={item.label}>
<Icon name={item.icon} />
{item.label}
</a>
))}
</nav>
);
}Fábrica de contenido dinámico
/* eslint-disable */
// utils/productData.js
export function getProductMessages(t) {
return {
categories: [
{ id: 'electronics', name: t('Electrónica') },
{ id: 'clothing', name: t('Ropa') },
{ id: 'books', name: t('Libros') }
],
statusMessages: {
available: t('En stock y listo para enviar'),
backordered: t('Actualmente en pedido pendiente - se envía en 2-3 semanas'),
discontinued: t('Este artículo ha sido descontinuado')
},
errors: {
notFound: t('Producto no encontrado'),
outOfStock: t('Lo sentimos, este artículo no está disponible actualmente')
}
};
}
// components/ProductCard.jsx
import { useGT } from 'gt-next';
import { getProductMessages } from '../utils/productData';
function ProductCard({ product }) {
const t = useGT();
const messages = getProductMessages(t);
return (
<div>
<h3>{product.name}</h3>
<p>{messages.statusMessages[product.status]}</p>
<span>{messages.categories.find(c => c.id === product.categoryId)?.name}</span>
</div>
);
}Componente de servidor con metadatos
import { getGT } from 'gt-next/server';
export async function generateMetadata({ params }) {
const t = await getGT();
return {
title: t('Catálogo de productos: encuentra lo que necesitas'),
description: t('Explora nuestra amplia selección de productos de alta calidad'),
openGraph: {
title: t('Compra nuestros productos'),
description: t('Descubre ofertas increíbles en artículos mejor valorados')
}
};
}
export default async function ProductPage() {
const t = await getGT();
return (
<div>
<h1>{t('Productos destacados')}</h1>
<p>{t('Descubre nuestros artículos más recientes y populares')}</p>
</div>
);
}Problemas habituales
Contenido dinámico en tiempo de ejecución
Las cadenas deben conocerse en tiempo de compilación: no puedes traducir contenido dinámico.
// ❌ El contenido dinámico no funcionará
function MyComponent() {
const [userMessage, setUserMessage] = useState('');
const t = useGT();
return <p>{t(userMessage)}</p>; // Esto fallará
}
// ✅ Usa cadenas predefinidas
function MyComponent() {
const [messageType, setMessageType] = useState('welcome');
const t = useGT();
const messages = {
welcome: t('¡Bienvenido a nuestra app!'),
goodbye: t('¡Gracias por visitarnos!')
};
return <p>{messages[messageType]}</p>;
}Incumplimientos de las reglas de hooks
Sigue las reglas de los hooks de React al usar useGT:
// ❌ No llames a los hooks de forma condicional
function MyComponent({ showMessage }) {
if (showMessage) {
const t = useGT(); // Incumplimiento de las reglas de los hooks
return <p>{t('¡Hola!')}</p>;
}
return null;
}
// ✅ Llama siempre a los hooks en el nivel superior
function MyComponent({ showMessage }) {
const t = useGT();
if (showMessage) {
return <p>{t('¡Hola!')}</p>;
}
return null;
}Confusión entre lo síncrono y lo asíncrono
Usa la función adecuada para tu tipo de componente:
// ❌ Incorrecto: useGT en un componente asíncrono
export default async function AsyncComponent() {
const t = useGT(); // Esto no funcionará
return <p>{t('Hola')}</p>;
}
// ✅ Correcto: getGT en un componente asíncrono
export default async function AsyncComponent() {
const t = await getGT();
return <p>{t('Hola')}</p>;
}
// ✅ Correcto: useGT en un componente sincrónico
export default function SyncComponent() {
const t = useGT();
return <p>{t('Hola')}</p>;
}Para contenido realmente dinámico que requiere traducción en tiempo de ejecución, consulta la Guía de contenido dinámico.
Próximos pasos
- Guía de contenido dinámico - Gestiona traducciones en tiempo de ejecución
- Guía de cadenas compartidas - Organiza traducciones reutilizables
- Referencia de API:
¿Qué te parece esta guía?