Haz tu pregunta y obtén un resumen del documento referenciando esta página y el proveedor AI de tu elección
El contenido de esta página ha sido traducido con una IA.
Ver la última versión del contenido original en inglésIf you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Nuevo Intlayer v8 - ¿Qué hay de nuevo?
¡Bienvenido a Intlayer v8! Esta versión se centra en mejorar la experiencia del desarrollador con la detección automática de contenido, garantizar la integridad de los datos con la validación de esquemas y proporcionar más control sobre la gestión de diccionarios.
Tabla de contenidos
Evolución del Contenido Enriquecido: Markdown y HTML
Intlayer v8 aporta mejoras importantes en la forma en que se maneja el contenido enriquecido, introduciendo nodos HTML (que no existían en v7) y unificando la API con nodos Markdown (que existían en v7 pero han sido mejorados).
La API unificada .use()
Introdujimos el método .use() tanto para los nodos Markdown como para los HTML. Este método le permite personalizar las etiquetas HTML o los componentes utilizados durante el renderizado.
- Reemplazo de componentes: Puede reemplazar fácilmente etiquetas HTML o componentes personalizados con sus propios componentes de framework (por ejemplo, reemplazar
<a>conNextLinko<CustomCmp>con un componente React). - Seguridad de tipos: Todas las funciones para proporcionar componentes están completamente tipadas, lo que garantiza que reciba las props correctas.
Comportamiento de renderizado por defecto
En la v7, si no se definía ningún proveedor, los nodos Markdown se renderizaban como cadenas de texto planas, lo que a menudo requería bibliotecas externas para analizarlos.
En la v8, Intlayer incluye su propio analizador interno de Markdown. Por defecto, los nodos Markdown ahora se renderizan directamente como HTML sin necesidad de bibliotecas externas.
Nuevas utilidades de renderizado y proveedor
Hemos introducido nuevas funciones y componentes de renderizado independientes para darle más control fuera del flujo estándar de useIntlayer.
- Markdown:
MarkdownRenderer,useMarkdownRenderer,renderMarkdown. (Nota:MarkdownProviderexistía en v7 pero ahora se integra con estas nuevas herramientas). - HTML:
HTMLRenderer,useHTMLRenderer,renderHTML,HTMLProvider.
Ejemplos: Herramientas de renderizado de Markdown
1. Usando el componente:
Copiar el código al portapapeles
import { MarkdownRenderer } from "react-intlayer/markdown";<MarkdownRenderer forceBlock={true} components={{ h1: ({ children }) => <h1 className="text-2xl">{children}</h1> }}> {"# My Title"}</MarkdownRenderer>2. Usando el hook:
Copiar el código al portapapeles
import { useMarkdownRenderer } from "react-intlayer/markdown";const renderMarkdown = useMarkdownRenderer({ components: { h1: ({ children }) => <h1 className="text-red-500">{children}</h1> }});return <div>{renderMarkdown("# My Title")}</div>;3. Usando la función de utilidad:
Copiar el código al portapapeles
import { renderMarkdown } from "react-intlayer/markdown";const html = renderMarkdown("# My Title", { forceBlock: true});Ejemplos: Herramientas de renderizado HTML
1. Usando el componente:
Copiar el código al portapapeles
import { HTMLRenderer } from "react-intlayer/html";<HTMLRenderer components={{ p: ({ children }) => <p className="mb-4">{children}</p> }}> {"<p>Hello World</p>"}</HTMLRenderer>2. Usando el hook:
Copiar el código al portapapeles
import { useHTMLRenderer } from "react-intlayer/html";const renderHTML = useHTMLRenderer({ components: { strong: ({ children }) => <b className="font-bold">{children}</b> }});return <div>{renderHTML("<p>Hello <strong>World</strong></p>")}</div>;3. Usando la función de utilidad:
Copiar el código al portapapeles
import { renderHTML } from "react-intlayer/html";const html = renderHTML("<p>Hello World</p>");Para más detalles, consulte la Documentación de Contenido HTML y la Documentación de Markdown.
Reescrituras de URL personalizadas
Intlayer v8 introduce el soporte para Reescrituras de URL personalizadas, lo que le permite definir rutas específicas de locale que difieren de la estructura estándar /locale/path. Esta es una característica poderosa para mejorar el SEO local y proporcionar una experiencia de usuario más natural para los hablantes no ingleses.
Mejoras clave en la v8:
- Formateadores de framework: Nuevos
nextjsRewrite,svelteKitRewrite,reactRouterRewrite,vueRouterRewrite,solidRouterRewrite,tanstackRouterRewrite,nuxtRewriteyviteRewritepara proporcionar una sintaxis de patrón idiomática para cada enrutador. - Hook
useRewriteURL: Un nuevo hook del lado del cliente que corrige silenciosamente la barra de direcciones a la URL localizada "bonita" sin disparar navegaciones del enrutador. - Redirecciones SEO automáticas: Los proxies integrados ahora redirigen automáticamente a los usuarios de rutas canónicas escritas manualmente (por ejemplo,
/fr/about) a sus versiones localizadas más bonitas (por ejemplo,/fr/a-propos).
Ejemplo de configuración:
Copiar el código al portapapeles
import { Locales, type IntlayerConfig } from "intlayer";import { nextjsRewrite } from "intlayer/routing";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, }, routing: { mode: "prefix-no-default", rewrite: nextjsRewrite({ "/[locale]/about": { fr: "/[locale]/a-propos", es: "/[locale]/acerca-de", }, "/[locale]/products/[id]": { fr: "/[locale]/produits/[id]", es: "/[locale]/productos/[id]", }, }), },};export default config;Esta característica es compatible de forma nativa en Next.js y Vite a través de los proxies de Intlayer, y puede integrarse fácilmente en otros enrutadores como TanStack Router, React Router, Vue Router, SvelteKit y Solid Router.
Para más información y guías de integración, consulte la Documentación de Reescrituras de URL Personalizadas.
Valores de inserción mejorados
En la v8, los valores de inserción ahora pueden aceptar elementos React (o nodos Vue) además de cadenas y números. Esto le permite inyectar componentes enriquecidos e interactivos directamente en sus plantillas de inserción.
Intlayer ahora maneja de forma robusta los nodos anidados de React y Preact dentro de las inserciones, garantizando que las estructuras complejas de la interfaz de usuario se preserven y se rendericen correctamente.
Ejemplo:
Copiar el código al portapapeles
import { insert } from "intlayer";export default { key: "my-key", content: { myInsertion: insert("Hi {{name}}"), },};Copiar el código al portapapeles
import { useIntlayer } from "next-intlayer";const { myInsertion } = useIntlayer("my-key");return ( <div> {myInsertion({ name: 2, // número // o name: "John", // cadena // o name: <span>John</span>, // elemento React })} </div>);Validación del esquema de contenido
Intlayer v8 introduce la validación de esquemas para diccionarios. Ahora puede definir esquemas de validación reutilizables en su configuración utilizando Zod y aplicarlos a sus archivos de contenido. Esto garantiza que su contenido siempre se adhiera a la estructura esperada, detectando errores en el momento de la construcción.
1. Definir esquemas
Defina sus esquemas en intlayer.config.ts:
Copiar el código al portapapeles
import { z } from "zod";export default { schemas: { "seo-metadata": z.object({ title: z.string().min(50).max(60), description: z.string().min(150).max(160), }), },};2. Aplicar esquemas a los diccionarios
Haga referencia a la clave del esquema en la definición de su diccionario:
Copiar el código al portapapeles
import { type Dictionary } from "intlayer";const aboutPageMetaContent = { key: "about-page-meta", schema: "seo-metadata", // <-- content: { title: "About Our Company - Learn More About Us", description: "Discover our company's mission, values, and team.", },} satisfies Dictionary;export default aboutPageMetaContent;Si el contenido no coincide con el esquema (por ejemplo, el título es demasiado corto), el proceso de construcción arrojará un error.
Detección automática de contenido mejorada
En la v8, Intlayer detecta inteligentemente la sintaxis Markdown, las etiquetas HTML y las inserciones de variables en sus cadenas de contenido. Esto significa que a menudo puede omitir funciones auxiliares como md(), html() o insert().
Este comportamiento está habilitado por defecto. Ahora puede ajustar esta detección globalmente en su intlayer.config.ts o por diccionario.
Control granular
Puede habilitar o deshabilitar tipos específicos de transformaciones:
Copiar el código al portapapeles
export default { dictionary: { // contentAutoTransformation: false (predeterminado) contentAutoTransformation: { markdown: true, html: true, insertion: false, // Deshabilitar la detección automática de inserciones }, },};Comportamiento v7 (envoltura manual):
Copiar el código al portapapeles
import { md, insert } from "intlayer";export default { key: "my-key", content: { myMarkdown: md("## Hello World"), myInsertion: insert("Hi {{name}}"), },};Comportamiento v8 (detección automática):
Copiar el código al portapapeles
export default { key: "my-key", contentAutoTransformation: true, // También puede ser configurado por definición de diccionario o globalmente en intlayer.config.ts content: { myMarkdown: "## Hello World", // Detectado automáticamente como Markdown myHTML: "<p>Hello World</p>", // Detectado automáticamente como HTML myInsertion: "Hi {{name}}", // Detectado automáticamente como Inserción },};El resultado JSON subyacente sigue siendo el mismo, preservando la rica información de tipo necesaria para el renderizado:
Copiar el código al portapapeles
{ "key": "my-key", "content": { "myMarkdown": { "nodeType": "markdown", "markdown": "## Hello World" }, "myHTML": { "nodeType": "html", "html": "<p>Hello World</p>" }, "myInsertion": { "nodeType": "insertion", "insertion": "Hi {{name}}" } }}Localización: nuevo hook useIntl
Un nuevo hook useIntl() está ahora disponible en React, Next.js y Vue. Proporciona un objeto Intl vinculado al locale que utiliza automáticamente el idioma actual para formatear números, fechas y más, sin necesidad de pasar manualmente el locale.
Copiar el código al portapapeles
import { useIntl } from "next-intlayer";const intl = useIntl();const formattedPrice = new intl.NumberFormat({ style: "currency", currency: "USD",}).format(123.45);Herramientas: Mejoras en la extensión de VSCode
La extensión de Intlayer para VSCode recibe actualizaciones importantes en la v8 para agilizar su flujo de trabajo de internacionalización:
- Tiempo de inicio: Mejoras de rendimiento al abrir un proyecto.
- Almacenamiento en caché: Capa de caché mejorada para una validación y un autocompletado casi instantáneos.
- Detección de claves no utilizadas y duplicadas: Nuevas funciones para detectar automáticamente claves no utilizadas y claves duplicadas en sus diccionarios, lo que le ayuda a mantener su contenido limpio y eficiente.
Optimizaciones del compilador
Intlayer v8 incluye una nueva capa de almacenamiento en caché para el compilador de Markdown y HTML. Esto garantiza que las cadenas de contenido idénticas con la misma configuración solo se analicen una vez, lo que reduce significativamente la sobrecarga durante los re-renderizados o cuando se utiliza el mismo contenido en varios lugares.
Copiar el código al portapapeles
const { intlayerExtractBabelPlugin, intlayerOptimizeBabelPlugin, getExtractPluginOptions, getOptimizePluginOptions,} = require('@intlayer/babel');module.exports = { presets: ['next/babel'], plugins: [ // Extraer contenido de los componentes a los diccionarios [intlayerExtractBabelPlugin, getExtractPluginOptions()], // Optimizar las importaciones reemplazando useIntlayer con importaciones directas de diccionarios [intlayerOptimizeBabelPlugin, getOptimizePluginOptions()], ],};Flexibilidad: Modo de Importación Unificado
La propiedad booleana live ha sido marcada como obsoleta en favor de una propiedad importMode más completa. Esto permite una definición explícita de cómo deben cargarse los diccionarios: de forma estática, dinámica o mediante sincronización en vivo.
Modos
static(Por defecto): El diccionario se incluye en el bundle en el momento de la construcción. Es el mejor para el rendimiento.dynamic: El diccionario se carga en runtime (por ejemplo, mediante fetch JSON o suspense).fetch: El diccionario se obtiene del CMS/Servidor en runtime y se sincroniza.
Migración:
Abrir la tabla en una ventana flotante para ver todo el contenido claramente
| Config v7 | Config v8 |
|---|---|
live: true | importMode: 'fetch' |
live: false | importMode: 'static' (o 'dynamic') |
Nota: En Intlayer v8, la propiedad importMode se ha movido de la configuración de build a la configuración de dictionary en intlayer.config.ts. Esto le permite definir un modo de importación por defecto para todos sus diccionarios, pudiendo sobrescribirlo para cada uno de ellos individualmente.
Ejemplo de configuración global:
Copiar el código al portapapeles
export default { dictionary: { importMode: "dynamic", // Valor global por defecto }, // ...};Ejemplo de diccionario:
Copiar el código al portapapeles
export default { key: 'my-key', importMode: "fetch", // Sobrescribe la configuración global content: { ... }}Control de ubicación del diccionario
La v8 introduce la propiedad location para gestionar explícitamente dónde residen los diccionarios y cómo se sincronizan. Esto es especialmente útil para flujos de trabajo híbridos que implican tanto archivos locales como contenido remoto de un CMS.
Opciones
local: El diccionario solo existe localmente. No se enviará al CMS remoto.remote: El diccionario se gestiona de forma remota. Una vez enviado al CMS, se desvinculará del local. El diccionario remoto se extraerá del CMS.local_and_remote: El diccionario existe en ambos lugares. Los cambios locales se envían y los cambios remotos se extraen (sincronizados).
Ejemplo:
Copiar el código al portapapeles
export default { key: 'my-key', location: "local", // Mantener este diccionario solo local content: { ... }}Separación de la configuración del sistema
Intlayer v8 separa la configuración de las fuentes de contenido de las rutas internas del sistema y de salida. Esto despeja la propiedad content y deja claro qué ajustes están destinados a la gestión por el usuario frente a los que gestiona el sistema Intlayer.
Las siguientes propiedades se han movido de content a una nueva propiedad system en intlayer.config.ts:
dictionariesDirmoduleAugmentationDirunmergedDictionariesDirtypesDirmainDirconfigDircacheDiroutputFilesPatternWithPath
Comportamiento v7:
Copiar el código al portapapeles
export default { content: { contentDir: ["src"], dictionariesDir: ".intlayer/dictionary", // Mezclado con la configuración de origen },};Comportamiento v8:
Copiar el código al portapapeles
export default { content: { contentDir: ["src"], }, system: { dictionariesDir: ".intlayer/dictionary", // Claramente separado },};Separación de directorios de contenido y código
Intlayer v8 separa la configuración para los archivos de definición de contenido de la configuración para la transformación de código. Esto permite una vigilancia y un escaneo más precisos, lo que mejora el rendimiento de la construcción.
Anteriormente, se utilizaba contentDir tanto para vigilar los archivos .content.* como para escanear el código en busca de llamadas a useIntlayer. Ahora:
contentDir: Específicamente para sus archivos de declaración de contenido.codeDir: Específicamente para el código de su aplicación que necesita transformación (por ejemplo, poda, optimización).
Migración:
Si anteriormente tenía configurado contentDir, Intlayer v8 lo utilizará también como valor por defecto para codeDir, pero registrará una advertencia. Debería definir explícitamente codeDir en su configuración.
Comportamiento v7:
Copiar el código al portapapeles
export default { content: { contentDir: ["src", "@packages/design-system"], // Se utiliza tanto para contenido como para código },};Comportamiento v8:
Copiar el código al portapapeles
export default { content: { contentDir: ["src/content", "@packages/design-system"], // Solo vigila aquí los archivos src/content/*.content.* y los archivos @packages/design-system/dist/*.content.* codeDir: ["src", "@packages/design-system"], // Solo escanea para transformación de código aquí y los archivos @packages/design-system/src/*.content.* },};Framework: Mejoras en Svelte
El contenido Markdown y HTML en Svelte ahora se analiza automáticamente a HTML cuando se convierte en cadena. Esto facilita mucho el uso con la sintaxis {@html} de Svelte, ya que ahora puede simplemente pasar el nodo de contenido directamente.
Notas de migración desde v7
Cambios en la configuración
- Propiedad
live: La propiedadliveen los diccionarios ha sido eliminada. UseimportMode: 'fetch'en su lugar. - importMode: La propiedad
build.importModeen la configuración ha sido obsoleta. Usedictionary.importModeen su lugar. contentDirycodeDir:contentDirahora es específicamente para archivos de contenido. Se ha añadido una nueva propiedadcodeDirpara la transformación del código. SicodeDirno está configurado, Intlayer recurrirá acontentDiry registrará una advertencia.- Validación del esquema: Para utilizar la nueva función
schema, asegúrese de tenerzodinstalado en su proyecto.