Pose una domanda e ottieni un riassunto del documento facendo riferimento a questa pagina e al provider AI di tua scelta
Il contenuto di questa pagina è stato tradotto con un'IA.
Vedi l'ultima versione del contenuto originale in ingleseIf 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
Nuovo Intlayer v8 - Novità
Benvenuti in Intlayer v8! Questa release si concentra sul miglioramento della Developer Experience con il rilevamento automatico dei contenuti, sull'assicurare l'integrità dei dati tramite la validazione degli schemi e sul fornire un maggior controllo nella gestione dei dizionari.
Indice
Evoluzione dei contenuti ricchi: Markdown & HTML
Intlayer v8 apporta grandi miglioramenti nel modo in cui vengono gestiti i contenuti ricchi, introducendo i nodi HTML (che non esistevano nella v7) e unificando l'API con i nodi Markdown (che esistevano nella v7 ma sono stati potenziati).
L'API unificata .use()
Abbiamo introdotto il metodo .use() sia per i nodi Markdown che per quelli HTML. Questo metodo ti permette di personalizzare i tag HTML o i componenti utilizzati durante il rendering.
- Sostituzione dei componenti: Puoi facilmente sostituire i tag HTML o i componenti personalizzati con i tuoi componenti del framework (ad esempio, sostituire
<a>conNextLinko<CustomCmp>con un componente React). - Type Safety: Tutte le funzioni per fornire componenti sono completamente tipizzate, garantendo la ricezione delle prop corrette.
Comportamento di rendering predefinito
Nella v7, se non veniva definito alcun provider, i nodi Markdown venivano renderizzati come stringhe grezze, richiedendo spesso librerie esterne per il parsing.
Nella v8, Intlayer include il proprio parser Markdown interno. Per impostazione predefinita, i nodi Markdown vengono ora renderizzati direttamente come HTML senza necessità di librerie esterne.
Nuove utility Renderer & Provider
Abbiamo introdotto nuove funzioni di rendering e componenti standalone per offrirti maggiore controllo al di fuori del flusso standard useIntlayer.
- Markdown:
MarkdownRenderer,useMarkdownRenderer,renderMarkdown. (Nota:MarkdownProvideresisteva nella v7 ma ora si integra con questi nuovi strumenti). - HTML:
HTMLRenderer,useHTMLRenderer,renderHTML,HTMLProvider.
Esempi: Strumenti di rendering Markdown
1. Utilizzo del componente:
Copiare il codice nella clipboard
import { MarkdownRenderer } from "react-intlayer/markdown";<MarkdownRenderer forceBlock={true} components={{ h1: ({ children }) => <h1 className="text-2xl">{children}</h1> }}> {"# Il mio titolo"}</MarkdownRenderer>2. Utilizzo dell'hook:
Copiare il codice nella clipboard
import { useMarkdownRenderer } from "react-intlayer/markdown";const renderMarkdown = useMarkdownRenderer({ components: { h1: ({ children }) => <h1 className="text-red-500">{children}</h1> }});return <div>{renderMarkdown("# Il mio titolo")}</div>;3. Utilizzo della funzione utility:
Copiare il codice nella clipboard
import { renderMarkdown } from "react-intlayer/markdown";const html = renderMarkdown("# Il mio titolo", { forceBlock: true});Esempi: Strumenti di rendering HTML
1. Utilizzo del componente:
Copiare il codice nella clipboard
import { HTMLRenderer } from "react-intlayer/html";<HTMLRenderer components={{ p: ({ children }) => <p className="mb-4">{children}</p> }}> {"<p>Ciao Mondo</p>"}</HTMLRenderer>2. Utilizzo dell'hook:
Copiare il codice nella clipboard
import { useHTMLRenderer } from "react-intlayer/html";const renderHTML = useHTMLRenderer({ components: { strong: ({ children }) => <b className="font-bold">{children}</b> }});return <div>{renderHTML("<p>Ciao <strong>Mondo</strong></p>")}</div>;3. Utilizzo della funzione utility:
Copiare il codice nella clipboard
import { renderHTML } from "react-intlayer/html";const html = renderHTML("<p>Ciao Mondo</p>");Per maggiori dettagli, consulta la Documentazione dei contenuti HTML e la Documentazione Markdown.
File di contenuto YAML e Markdown (v8.10.0)
Ora puoi dichiarare i contenuti direttamente utilizzando le estensioni di file .content.md e .content.yaml. Questo è perfetto per contenuti di lunga forma, blog, documentazione e politiche sulla privacy.
Questi file sono completamente modificabili dall'Editor Visuale, fornendo un flusso di lavoro semplificato per i membri del team non tecnici.
Per maggiori dettagli, consulta la Documentazione sui file di contenuto YAML e la Documentazione sui file di contenuto Markdown.
Riscritture URL personalizzate
Intlayer v8 introduce il supporto per le Riscritture URL personalizzate, che ti permettono di definire percorsi specifici per ogni locale che differiscono dalla struttura standard /locale/path. Questa è una funzionalità potente per migliorare la SEO locale e offrire un'esperienza utente più naturale per i parlanti non inglesi.
Miglioramenti chiave nella v8:
- Formattatori per framework: nuovi
nextjsRewrite,svelteKitRewrite,reactRouterRewrite,vueRouterRewrite,solidRouterRewrite,tanstackRouterRewrite,nuxtRewriteeviteRewriteper fornire una sintassi di pattern idiomatica per ciascun router. useRewriteURLHook: Un nuovo hook lato client che corregge silenziosamente la barra degli indirizzi verso l'URL localizzato "più leggibile" senza attivare navigazioni del router.- Automatic SEO Redirects: Reindirizzamenti SEO automatici: i proxy integrati ora reindirizzano automaticamente gli utenti da percorsi canonici digitati manualmente (es.,
/fr/about) alle loro versioni localizzate più leggibili (es.,/fr/a-propos).
Esempio di configurazione:
Copiare il codice nella clipboard
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;Questa funzionalità è supportata nativamente in Next.js e Vite tramite i proxy di Intlayer, e può essere facilmente integrata in altri router come TanStack Router, React Router, Vue Router, SvelteKit e Solid Router.
Per maggiori informazioni e guide all'integrazione, vedi la documentazione su Custom URL Rewrites.
Valori di inserzione potenziati
Nella v8, i valori di inserzione possono ora accettare elementi React (o nodi Vue) oltre a stringhe e numeri. Questo ti permette di inserire componenti ricchi e interattivi direttamente nei tuoi template di inserzione.
Intlayer ora gestisce in modo robusto i nodi annidati di React e Preact all'interno delle inserzioni, assicurando che strutture UI complesse siano preservate e renderizzate correttamente.
Esempio:
Copiare il codice nella clipboard
import { insert } from "intlayer";export default { key: "my-key", content: { myInsertion: insert("Ciao {{name}}"), },};Copiare il codice nella clipboard
import { useIntlayer } from "next-intlayer";const { myInsertion } = useIntlayer("my-key");return ( <div> {myInsertion({ name: 2, // numero // oppure name: "John", // stringa // oppure name: <span>John</span>, // elemento React })} </div>);Regole di Pluralizzazione Unicode CLDR (v8.8.0)
È stato introdotto un nuovo helper per nodi plural basato sulle regole di pluralizzazione definite dal Progetto Unicode CLDR, migliorando il supporto per le lingue complesse.
Copiare il codice nella clipboard
import { plural, t, type Dictionary } from "intlayer";const openingsContent = { key: "total_openings", content: { totalOpenings: t({ en: plural({ one: "{{count}} opening", other: "{{count}} openings", }), fr: plural({ one: "{{count}} offre", other: "{{count}} offres", }), it: plural({ // Added Italian translation one: "{{count}} offerta", other: "{{count}} offerte", }), }), },} satisfies Dictionary;export default openingsContent;Puoi quindi passare il conteggio dinamicamente nel componente del tuo framework:
Copiare il codice nella clipboard
import type { FC } from "react";import { useIntlayer } from "react-intlayer";const OpeningsComponent: FC<{ count: number }> = ({ count }) => { const { totalOpenings } = useIntlayer("total_openings"); return ( <div> {/* In English: */} {/* count=0 → "0 openings" (other) */} {/* count=1 → "1 opening" (one) */} {/* count=2 → "2 openings" (other) */} {/* count=21 → "21 openings" (other) */} {/* In Italian: */} {/* count=0 → "0 offerte" (other) */} {/* count=1 → "1 offerta" (one) */} {/* count=2 → "2 offerte" (other) */} {/* count=21 → "21 offerte" (other) */} <p>{totalOpenings(count)}</p> </div> );};Per maggiori informazioni, consulta la Documentazione sulla Pluralizzazione.
Validazione dello schema di contenuto
Intlayer v8 introduce la validazione degli schemi per i dizionari. Ora puoi definire schemi di validazione riutilizzabili nella tua configurazione utilizzando Zod e applicarli ai tuoi file di contenuto. Questo garantisce che i tuoi contenuti rispettino sempre la struttura prevista, intercettando gli errori in fase di build.
1. Definire gli schemi
Definisci i tuoi schemi in intlayer.config.ts:
Copiare il codice nella clipboard
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. Applicare gli schemi ai dizionari
Fai riferimento alla chiave dello schema nella definizione del tuo dizionario:
Copiare il codice nella clipboard
import { type Dictionary } from "intlayer";const aboutPageMetaContent = { key: "about-page-meta", schema: "seo-metadata", // <-- content: { title: "Informazioni sulla nostra azienda - Scopri di più su di noi", description: "Scopri la missione, i valori e il team della nostra azienda.", },} satisfies Dictionary;export default aboutPageMetaContent;Se il contenuto non corrisponde allo schema (ad esempio, il titolo è troppo corto), il processo di build genererà un errore.
TypeScript: Accessori Primitivi IntlayerNode
Il tipo IntlayerNode è stato aggiornato per consentire di chiamare metodi JavaScript primitivi direttamente sui nodi di contenuto. Questo rende possibile interagire con il tuo contenuto localizzato direttamente come se fosse una stringa, un numero, un booleano o un array primitivo standard.
Supportato su React, Preact, Solid, Svelte, Vue e Angular.
Esempio Stringa
Copiare il codice nella clipboard
content.placeholder; // Restituisce IntlayerNode<string>content.placeholder.value; // Restituisce stringacontent.placeholder.toString(); // Restituisce stringacontent.placeholder.toLowerCase(); // Restituisce stringaString(content.placeholder); // Restituisce stringacontent.placeholder.toUpperCase(); // Restituisce stringa in maiuscolocontent.placeholder.replace("a", "b"); // Restituisce stringa modificataEsempio Array
Copiare il codice nella clipboard
content.myArrayOfString // Restituisce IntlayerNode<Array<string>>content.myArrayOfString.find(...) // Restituisce elementocontent.myArrayOfString.join(', ') // Restituisce stringa unitaRilevamento automatico del contenuto potenziato
Nella v8, Intlayer rileva in modo intelligente la sintassi Markdown, i tag HTML e le inserzioni di variabili nelle stringhe di contenuto. Questo significa che spesso puoi omettere funzioni helper come md(), html(), o insert().
Questo comportamento è abilitato per impostazione predefinita. Ora puoi perfezionare questo rilevamento globalmente nel tuo intlayer.config.ts o per singolo dizionario.
Controllo granulare
Puoi abilitare o disabilitare tipi specifici di trasformazioni:
Copiare il codice nella clipboard
export default { dictionary: { // contentAutoTransformation: false (default) contentAutoTransformation: { markdown: true, html: true, insertion: false, // Disabilita il rilevamento automatico delle inserzioni }, },};Comportamento v7 (Avvolgimento manuale):
Copiare il codice nella clipboard
import { md, insert } from "intlayer";export default { key: "my-key", content: { myMarkdown: md("## Hello World"), myInsertion: insert("Ciao {{name}}"), },};Comportamento v8 (Rilevamento automatico):
Copiare il codice nella clipboard
export default { key: "my-key", contentAutoTransformation: true, // Può anche essere impostato nella definizione del dizionario o globalmente in intlayer.config.ts content: { myMarkdown: "## Hello World", // Rilevato automaticamente come Markdown myHTML: "<p>Hello World</p>", // Rilevato automaticamente come HTML myInsertion: "Ciao {{name}}", // Rilevato automaticamente come Inserzione },};Il risultato JSON sottostante rimane lo stesso, preservando le ricche informazioni di tipo necessarie per il rendering:
Copiare il codice nella clipboard
{ "key": "my-key", "content": { "myMarkdown": { "nodeType": "markdown", "markdown": "## Hello World" }, "myHTML": { "nodeType": "html", "html": "<p>Hello World</p>" }, "myInsertion": { "nodeType": "insertion", "insertion": "Ciao {{name}}" } }}Localizzazione: nuovo hook useIntl
Un nuovo hook useIntl() è ora disponibile in React, Next.js e Vue. Fornisce un oggetto Intl legato alla locale che utilizza automaticamente la lingua corrente per formattare numeri, date e altro, senza bisogno di passare manualmente la locale.
Copiare il codice nella clipboard
import { useIntl } from "next-intlayer";const intl = useIntl();const formattedPrice = new intl.NumberFormat({ style: "currency", currency: "USD",}).format(123.45);Tooling: Miglioramenti dell'estensione VSCode
L'estensione Intlayer per VSCode riceve aggiornamenti importanti nella v8 per semplificare il tuo flusso di lavoro di internazionalizzazione:
- Tempo di avvio: Miglioramenti delle prestazioni all'apertura di un progetto.
- Caching: Layer di caching migliorato per validazione e autocompletamento quasi istantanei.
- Rilevamento chiavi inutilizzate e chiavi duplicate: Nuove funzionalità per rilevare automaticamente chiavi inutilizzate e chiavi duplicate nei tuoi dizionari, aiutandoti a mantenere i tuoi contenuti ordinati ed efficienti.
Tooling: C++ Watcher & LSP basato su OXC (v8.12.0)
Intlayer v8.12.0 apporta importanti miglioramenti alla developer experience:
- Parcel Watcher: Il watcher dei contenuti è stato migrato da
chokidara@parcel/watcher, sfruttando il file watching nativo in C++ per fornire aggiornamenti più rapidi e un consumo di memoria significativamente inferiore. - Nuovo Language Server Protocol (LSP): È ora disponibile un LSP completamente nuovo. Costruito con parsing basato su OXC, aiuta il tuo IDE e gli agenti AI a collegare senza soluzione di continuità le chiamate
useIntlayer('my-key')con i loro file.contentcorrispondenti, e viceversa.
Per maggiori dettagli, consulta la Documentazione LSP.
Ottimizzazioni del compilatore
Intlayer v8 include un nuovo layer di caching per il compilatore Markdown e HTML. Questo garantisce che stringhe di contenuto identiche con la stessa configurazione vengano analizzate solo una volta, riducendo significativamente l'overhead durante i re-render o quando lo stesso contenuto è utilizzato in più punti.
Copiare il codice nella clipboard
const { intlayerExtractBabelPlugin, intlayerOptimizeBabelPlugin, getExtractPluginOptions, getOptimizePluginOptions,} = require('@intlayer/babel');module.exports = { presets: ['next/babel'], plugins: [ // Estrai il contenuto dai componenti nei dizionari [intlayerExtractBabelPlugin, getExtractPluginOptions()], // Ottimizza le importazioni sostituendo useIntlayer con importazioni dirette dei dizionari [intlayerOptimizeBabelPlugin, getOptimizePluginOptions()], ],};Ottimizzazioni sperimentali della build: Minify & Purge (v8.7.0)
Intlayer v8.7.0 introduce nuove funzionalità di build sperimentali nel tuo intlayer.config.ts progettate per ottimizzare il tuo bundle di produzione:
- Minificazione del dizionario: Minifica i file del dizionario per ridurne le dimensioni.
- Pulizia delle chiavi inutilizzate: Scansiona e rimuove le chiavi di traduzione inutilizzate dai dizionari, rinominando le chiavi attive con caratteri brevi (es.
"products" -> "a","pricing" -> "b"). Questo riduce le dimensioni del bundle fino al 5%. - Disabilita i controlli TypeScript: Accelera le build disabilitando il controllo dei tipi TypeScript durante la fase di compilazione.
Copiare il codice nella clipboard
import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH], defaultLocale: Locales.ENGLISH, }, dictionary: { importMode: "dynamic", }, build: { /** * Minify the dictionaries to reduce the bundle size. */ minify: true, /** * Purge the unused keys in dictionaries */ purge: true, /** * Indicates if the build should check TypeScript types */ checkTypes: false, },};export default config;Flessibilità: Modalità di importazione unificata
La proprietà booleana live è stata deprecata a favore di una proprietà più completa, importMode. Questo consente di definire esplicitamente come devono essere caricati i dizionari: staticamente, dinamicamente o tramite sincronizzazione live.
Modalità
static(Predefinito): Il dizionario viene incluso nel bundle al momento della build. Ideale per le prestazioni.dynamic: Il dizionario viene caricato a runtime (es. tramite fetch JSON o suspense).fetch: Il dizionario viene recuperato dal CMS/Server a runtime e sincronizzato.
Migrazione:
Apri la tabella in una finestra modale per visualizzare tutti i dati in modo chiaro
| Configurazione v7 | Configurazione v8 |
|---|---|
live: true | importMode: 'fetch' |
live: false | importMode: 'static' (o 'dynamic') |
Nota: In Intlayer v8, la proprietà importMode è stata spostata dalla configurazione build alla configurazione dictionary in intlayer.config.ts. Questo ti permette di definire una modalità di importazione predefinita per tutti i tuoi dizionari, pur potendo sovrascrittore per singolo dizionario.
Esempio di configurazione globale:
Copiare il codice nella clipboard
export default { dictionary: { importMode: "dynamic", // Global default }, // ...};Esempio di dizionario:
Copiare il codice nella clipboard
export default { key: 'my-key', importMode: "fetch", // Overrides global config content: { ... }}Controllo della posizione del dizionario
La v8 introduce la proprietà location per gestire esplicitamente dove risiedono i dizionari e come si sincronizzano. Questo è particolarmente utile per workflow ibridi che coinvolgono sia file locali sia contenuti CMS remoti.
Opzioni
local: Il dizionario esiste solo localmente. Non verrà pushato sul CMS remoto.remote: Il dizionario è gestito remotamente. Una volta pushato sul CMS, verrà scollegato da quello locale. Il dizionario remoto sarà pullato dal CMS.local_and_remote: Il dizionario esiste in entrambi i luoghi. Le modifiche locali vengono pushate e le modifiche remote vengono pullate (sincronizzate).
Esempio:
Copiare il codice nella clipboard
export default { key: 'my-key', location: "local", // Mantieni questo dizionario solo locale content: { ... }}Separazione della Configurazione del Sistema
Intlayer v8 separa la configurazione delle sorgenti di contenuto dai percorsi interni di sistema e di output. Questo snellisce la proprietà content e rende chiaro quali impostazioni sono destinate alla gestione dall'utente e quali sono gestite dal sistema Intlayer.
Le seguenti proprietà sono state spostate da content a una nuova proprietà system in intlayer.config.ts:
dictionariesDirmoduleAugmentationDirunmergedDictionariesDirtypesDirmainDirconfigDircacheDiroutputFilesPatternWithPath
Comportamento v7:
Copiare il codice nella clipboard
export default { content: { contentDir: ["src"], dictionariesDir: ".intlayer/dictionary", // Mescolato con la configurazione sorgente },};Comportamento v8:
Copiare il codice nella clipboard
export default { content: { contentDir: ["src"], }, system: { dictionariesDir: ".intlayer/dictionary", // Separato chiaramente },};Separazione delle directory di contenuto e codice
Intlayer v8 separa la configurazione per i file di definizione dei contenuti dalla configurazione per la trasformazione del codice. Questo permette un watch e una scansione più precisi, migliorando le prestazioni della build.
In precedenza, contentDir veniva usato sia per il watch dei file .content.* sia per la scansione del codice per le chiamate useIntlayer. Ora:
contentDir: specificamente per i file di dichiarazione dei contenuti.codeDir: specificamente per il codice della tua applicazione che necessita di trasformazioni (es. pruning, ottimizzazione).
Migrazione:
Se in precedenza avevi impostato contentDir, Intlayer v8 lo userà anche come impostazione predefinita per codeDir, ma registrerà un avviso. Dovresti definire esplicitamente codeDir nella tua configurazione.
Comportamento v7:
Copiare il codice nella clipboard
export default { content: { contentDir: ["src", "@packages/design-system"], // Usato sia per il contenuto sia per il codice },};Comportamento v8:
Copiare il codice nella clipboard
export default { content: { contentDir: ["src/content", "@packages/design-system"], // Osserva solo i file src/content/*.content.* qui e i file @packages/design-system/dist/*.content.* codeDir: ["src", "@packages/design-system"], // Scansiona solo il codice per la trasformazione qui e i file @packages/design-system/src/*.content.* },};Framework: Miglioramenti per Svelte
Il contenuto Markdown e HTML in Svelte ora viene automaticamente convertito in HTML quando viene serializzato. Questo rende molto più semplice l'uso con la sintassi {@html} di Svelte, poiché ora puoi semplicemente passare direttamente il nodo di contenuto.
Supporto Angular: Vite Bundler (v8.11.0)
Per gli utenti Angular, Intlayer ora supporta nativamente il bundler Vite tramite un nuovo plugin esbuild personalizzato, accelerando i tempi di sviluppo e di build.
Per i dettagli sulla configurazione, consulta la Documentazione dell'ambiente Angular.
Generazione della Sitemap (v8.6.0)
Intlayer ora genera automaticamente le sitemap in base alle tue locali e alla modalità di routing. Questo è particolarmente utile per l'ottimizzazione SEO in architetture di router come TanStack Router:
Copiare il codice nella clipboard
import { createFileRoute } from "@tanstack/react-router";import { generateSitemap } from "intlayer";const SITE_URL = ( import.meta.env.VITE_SITE_URL ?? "http://localhost:3000").replace(/\/$/, "");export const Route = createFileRoute("/sitemap.xml")({ server: { handlers: { GET: async () => { const sitemap = generateSitemap( [ { path: "/", changefreq: "daily", priority: 1.0 }, { path: "/about", changefreq: "monthly", priority: 0.8 }, ], { siteUrl: SITE_URL } ); return new Response(sitemap, { headers: { "Content-Type": "application/xml" }, }); }, }, },});Note di migrazione dalla v7
Modifiche alla configurazione
- Proprietà
live: La proprietàlivenei dizionari è stata rimossa. UsaimportMode: 'fetch'al suo posto. - importMode: La proprietà
build.importModenella configurazione è stata deprecata. Usadictionary.importModeal suo posto. contentDirecodeDir:contentDirè ora specificamente per i file di contenuto. È stata aggiunta una nuova proprietàcodeDirper la trasformazione del codice. SecodeDirnon è impostato, Intlayer farà fallback sucontentDire registrerà un warning.- Validazione dello schema: Per usare la nuova funzionalità
schema, assicurati di averezodinstallato nel tuo progetto.