Yazar:
    Oluşturma:2025-09-22Son güncelleme:2026-06-14

    Yeni Intlayer v8 - Yenilikler

    Intlayer v8'e hoş geldiniz! Bu sürüm, otomatik içerik algılama ile geliştirici deneyimini iyileştirmeye, şema doğrulaması ile veri bütünlüğünü sağlamaya ve sözlük yönetimi üzerinde daha fazla kontrol sunmaya odaklanıyor.

    youtube.com

    İçindekiler

    Zengin İçerik Evrimi: Markdown ve HTML

    Intlayer v8, zengin içeriğin işlenme şeklinde büyük iyileştirmeler getirerek HTML düğümlerini (v7'de yoktu) tanıtıyor ve API'yi Markdown düğümleri (v7'de vardı ancak geliştirildi) ile birleştiriyor.

    Birleşik .use() API'si

    Hem Markdown hem de HTML düğümleri için .use() metodunu tanıttık. Bu metod, render sırasında kullanılan HTML etiketlerini veya bileşenlerini özelleştirmenize olanak tanır.

    • Bileşen Değiştirme: HTML etiketlerini veya özel bileşenleri kendi framework bileşenlerinizle kolayca değiştirebilirsiniz (örneğin, <a> etiketini NextLink ile veya <CustomCmp> etiketini bir React bileşeniyle değiştirebilirsiniz).
    • Tip Güvenliği: Bileşen sağlamak için kullanılan tüm fonksiyonlar tam tiplidir ve doğru prop'ları almanızı sağlar.

    Varsayılan Render Davranışı

    v7'de, bir sağlayıcı tanımlanmamışsa, Markdown düğümleri ham string'ler olarak render ediliyordu ve bunları ayrıştırmak için genellikle harici kütüphanelere ihtiyaç duyuluyordu.

    v8'de Intlayer kendi dahili Markdown ayrıştırıcısını içerir. Varsayılan olarak, Markdown düğümleri artık herhangi bir harici kütüphaneye ihtiyaç duymadan doğrudan HTML olarak render edilir.

    Yeni Renderer ve Provider Yardımcı Araçları

    Standart useIntlayer akışının dışında size daha fazla kontrol sağlamak için yeni bağımsız renderer fonksiyonları ve bileşenleri tanıttık.

    • Markdown: MarkdownRenderer, useMarkdownRenderer, renderMarkdown. (Not: MarkdownProvider v7'de vardı ancak artık bu yeni araçlarla entegre çalışıyor).
    • HTML: HTMLRenderer, useHTMLRenderer, renderHTML, HTMLProvider.

    Örnekler: Markdown Render Araçları

    1. Bileşeni Kullanma:

    tsx
    import { MarkdownRenderer } from "react-intlayer/markdown";
    
    <MarkdownRenderer
    forceBlock={true}
    components={{
      h1: ({ children }) => <h1 className="text-2xl">{children}</h1>
    }}
    >
    {"# Başlığım"}
    </MarkdownRenderer>
    

    2. Hook'u Kullanma:

    tsx
    import { useMarkdownRenderer } from "react-intlayer/markdown";
    
    const renderMarkdown = useMarkdownRenderer({
    components: {
      h1: ({ children }) => <h1 className="text-red-500">{children}</h1>
    }
    });
    
    return <div>{renderMarkdown("# Başlığım")}</div>;
    

    3. Yardımcı Fonksiyonu Kullanma:

    tsx
    import { renderMarkdown } from "react-intlayer/markdown";
    
    const html = renderMarkdown("# Başlığım", {
    forceBlock: true
    });
    

    1. Bileşeni Kullanma:

    vue
    <script setup>
    import { MarkdownRenderer } from "vue-intlayer/markdown";
    </script>
    
    <template>
    <MarkdownRenderer :forceBlock="true" content="# Başlığım" />
    </template>
    

    1. Bileşeni Kullanma:

    svelte
    <script>
    import { MarkdownRenderer } from "svelte-intlayer/markdown";
    </script>
    
    <MarkdownRenderer forceBlock={true} value="# Başlığım" />
    

    2. Hook'u Kullanma:

    svelte
    <script>
    import { useMarkdownRenderer } from "svelte-intlayer/markdown";
    const render = useMarkdownRenderer();
    </script>
    
    {@html render("# Başlığım")}
    

    3. Yardımcı Fonksiyonu Kullanma:

    svelte
    <script>
    import { renderMarkdown } from "svelte-intlayer/markdown";
    </script>
    
    {@html renderMarkdown("# Başlığım")}
    

    1. Servisi Kullanma:

    typescript
    import { Component } from "@angular/core";
    import { IntlayerMarkdownService } from "angular-intlayer";
    
    @Component({ ... })
    export class MyComponent {
    constructor(private markdownService: IntlayerMarkdownService) {}
    
    render(markdown: string) {
      return this.markdownService.renderMarkdown(markdown);
    }
    }
    

    1. Bileşeni Kullanma:

    tsx
    import { MarkdownRenderer } from "solid-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true}>
    {"# Başlığım"}
    </MarkdownRenderer>
    

    2. Hook'u Kullanma:

    tsx
    import { useMarkdownRenderer } from "solid-intlayer/markdown";
    
    const render = useMarkdownRenderer();
    
    return <div>{render("# Başlığım")}</div>;
    

    3. Yardımcı Fonksiyonu Kullanma:

    tsx
    import { renderMarkdown } from "solid-intlayer/markdown";
    
    return <div>{renderMarkdown("# Başlığım")}</div>;
    

    1. Bileşeni Kullanma:

    tsx
    import { MarkdownRenderer } from "preact-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true}>
    {"# Başlığım"}
    </MarkdownRenderer>
    

    2. Hook'u Kullanma:

    tsx
    import { useMarkdownRenderer } from "preact-intlayer/markdown";
    
    const render = useMarkdownRenderer();
    
    return <div>{render("# Başlığım")}</div>;
    

    3. Yardımcı Fonksiyonu Kullanma:

    tsx
    import { renderMarkdown } from "preact-intlayer/markdown";
    
    return <div>{renderMarkdown("# Başlığım")}</div>;
    

    Örnekler: HTML Render Araçları

    1. Bileşeni Kullanma:

    tsx
    import { HTMLRenderer } from "react-intlayer/html";
    
    <HTMLRenderer
    components={{
      p: ({ children }) => <p className="mb-4">{children}</p>
    }}
    >
    {"<p>Merhaba Dünya</p>"}
    </HTMLRenderer>
    

    2. Hook'u Kullanma:

    tsx
    import { useHTMLRenderer } from "react-intlayer/html";
    
    const renderHTML = useHTMLRenderer({
    components: {
      strong: ({ children }) => <b className="font-bold">{children}</b>
    }
    });
    
    return <div>{renderHTML("<p>Merhaba <strong>Dünya</strong></p>")}</div>;
    

    3. Yardımcı Fonksiyonu Kullanma:

    tsx
    import { renderHTML } from "react-intlayer/html";
    
    const html = renderHTML("<p>Merhaba Dünya</p>");
    

    1. Bileşeni Kullanma:

    vue
    <script setup>
    import { HTMLRenderer } from "vue-intlayer/html";
    </script>
    
    <template>
    <HTMLRenderer content="<p>Merhaba Dünya</p>" />
    </template>
    

    1. Bileşeni Kullanma:

    svelte
    <script>
    import { HTMLRenderer } from "svelte-intlayer/html";
    </script>
    
    <HTMLRenderer value="<p>Merhaba Dünya</p>" />
    

    2. Hook'u Kullanma:

    svelte
    <script>
    import { useHTMLRenderer } from "svelte-intlayer/html";
    const render = useHTMLRenderer();
    </script>
    
    {@html render("<p>Merhaba Dünya</p>")}
    

    3. Yardımcı Fonksiyonu Kullanma:

    svelte
    <script>
    import { renderHTML } from "svelte-intlayer/html";
    </script>
    
    {@html renderHTML("<p>Merhaba Dünya</p>")}
    

    1. Doğrudan Kullanım:

    Angular'da standart [innerHTML] binding'ini kullanabilirsiniz.

    html
    <div [innerHTML]="'<p>Merhaba Dünya</p>'"></div>
    

    1. Bileşeni Kullanma:

    tsx
    import { HTMLRenderer } from "solid-intlayer/html";
    
    <HTMLRenderer>
    {"<p>Merhaba Dünya</p>"}
    </HTMLRenderer>
    

    2. Hook'u Kullanma:

    tsx
    import { useHTMLRenderer } from "solid-intlayer/html";
    
    const render = useHTMLRenderer();
    
    return <div>{render("<p>Merhaba Dünya</p>")}</div>;
    

    3. Yardımcı Fonksiyonu Kullanma:

    tsx
    import { renderHTML } from "solid-intlayer/html";
    
    return <div>{renderHTML("<p>Merhaba Dünya</p>")}</div>;
    

    1. Bileşeni Kullanma:

    tsx
    import { HTMLRenderer } from "preact-intlayer/html";
    
    <HTMLRenderer>
    {"<p>Merhaba Dünya</p>"}
    </HTMLRenderer>
    

    2. Hook'u Kullanma:

    tsx
    import { useHTMLRenderer } from "preact-intlayer/html";
    
    const render = useHTMLRenderer();
    
    return <div>{render("<p>Merhaba Dünya</p>")}</div>;
    

    3. Yardımcı Fonksiyonu Kullanma:

    tsx
    import { renderHTML } from "preact-intlayer/html";
    
    return <div>{renderHTML("<p>Merhaba Dünya</p>")}</div>;
    

    Daha fazla ayrıntı için HTML İçerik Dokümantasyonu ve Markdown Dokümantasyonu sayfalarına bakın.

    YAML ve Markdown İçerik Dosyaları (v8.10.0)

    Artık doğrudan .content.md ve .content.yaml dosya uzantılarını kullanarak içerik tanımlayabilirsiniz. Bu, uzun biçimli içerikler, bloglar, dokümantasyonlar ve gizlilik politikaları için mükemmeldir.

    Bu dosyalar Görsel Editör (Visual Editor) üzerinden tamamen düzenlenebilir, böylece teknik olmayan ekip üyeleri için kolaylaştırılmış bir iş akışı sağlanır.

    Daha fazla ayrıntı için YAML İçerik Dosyaları Dokümantasyonu ve Markdown İçerik Dosyaları Dokümantasyonu sayfalarına bakın.

    Özel URL Yeniden Yazımları

    Intlayer v8, standart /locale/path yapısından farklı olan dile özgü yollar tanımlamanıza olanak tanıyan Özel URL Yeniden Yazımları desteğini getirir. Bu, yerel SEO'yu iyileştirmek ve İngilizce dışı kullanıcılar için daha doğal bir kullanıcı deneyimi sağlamak açısından güçlü bir özelliktir.

    v8'deki önemli geliştirmeler:

    • Framework Formatlayıcıları: Her router için idiomatik desen sözdizimi sağlamak amacıyla nextjsRewrite, svelteKitRewrite, reactRouterRewrite, vueRouterRewrite, solidRouterRewrite, tanstackRouterRewrite, nuxtRewrite ve viteRewrite eklendi.
    • useRewriteURL Hook: Yeni bir istemci tarafı hook'u; router navigasyonlarını tetiklemeden adres çubuğunu sessizce "güzel" yerelleştirilmiş URL'ye düzeltir.
    • Otomatik SEO Yönlendirmeleri: Yerleşik proxy'ler artık kullanıcıları elle girilmiş kanonik yollardan (örn. /fr/about) daha güzel yerelleştirilmiş sürümlerine (örn. /fr/a-propos) otomatik olarak yönlendirir.

    Örnek Yapılandırma:

    intlayer.config.ts
    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;
    
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { reactRouterRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    internationalization: {
      locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
      defaultLocale: Locales.ENGLISH,
    },
    routing: {
      mode: "prefix-all",
      rewrite: reactRouterRewrite({
        "/:locale/about": {
          fr: "/:locale/a-propos",
          es: "/:locale/acerca-de",
        },
        "/:locale/products/:id": {
          fr: "/:locale/produits/:id",
          es: "/:locale/productos/:id",
        },
      }),
    },
    };
    
    export default config;
    
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { viteRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    internationalization: {
      locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
      defaultLocale: Locales.ENGLISH,
    },
    routing: {
      mode: "prefix-all",
      rewrite: viteRewrite({
        "/:locale/about": {
          fr: "/:locale/a-propos",
          es: "/:locale/acerca-de",
        },
        "/:locale/products/:id": {
          fr: "/:locale/produits/:id",
          es: "/:locale/productos/:id",
        },
      }),
    },
    };
    
    export default config;
    
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { nuxtRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    internationalization: {
      locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
      defaultLocale: Locales.ENGLISH,
    },
    routing: {
      mode: "prefix-all",
      rewrite: nuxtRewrite({
        "/[locale]/about": {
          fr: "/[locale]/a-propos",
          es: "/[locale]/acerca-de",
        },
        "/[locale]/products/[id]": {
          fr: "/[locale]/produits/[id]",
          es: "/[locale]/productos/[id]",
        },
      }),
    },
    };
    
    export default config;
    
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { svelteKitRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    internationalization: {
      locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
      defaultLocale: Locales.ENGLISH,
    },
    routing: {
      mode: "prefix-all",
      rewrite: svelteKitRewrite({
        "/[locale]/about": {
          fr: "/[locale]/a-propos",
          es: "/[locale]/acerca-de",
        },
        "/[locale]/products/[id]": {
          fr: "/[locale]/produits/[id]",
          es: "/[locale]/productos/[id]",
        },
      }),
    },
    };
    
    export default config;
    

    Bu özellik, Intlayer proxy'leri aracılığıyla Next.js ve Vite'te varsayılan olarak desteklenir ve TanStack Router, React Router, Vue Router, SvelteKit ve Solid Router gibi diğer yönlendiricilere kolayca entegre edilebilir.

    Daha fazla bilgi ve entegrasyon kılavuzları için Özel URL Yeniden Yazma Dokümantasyonu sayfasına bakın.

    Geliştirilmiş Ekleme Değerleri

    v8'de, ekleme (insertion) değerleri artık string ve sayılara ek olarak React elementlerini (veya Vue düğümlerini) kabul edebilir. Bu, zengin, etkileşimli bileşenleri doğrudan ekleme şablonlarınıza enjekte etmenize olanak tanır.

    Intlayer artık eklemeler içinde iç içe geçmiş React ve Preact düğümlerini güvenilir bir şekilde işler; böylece karmaşık kullanıcı arayüzü yapıları korunur ve doğru şekilde render edilir.

    Örnek:

    src/example.content.ts
    import { insert } from "intlayer";
    
    export default {
      key: "my-key",
      content: {
        myInsertion: insert("Merhaba {{name}}"),
      },
    };
    
    tsx
    import { useIntlayer } from "next-intlayer";
    
    const { myInsertion } = useIntlayer("my-key");
    
    return (
    <div>
      {myInsertion({
        name: 2, // sayı
        // veya
        name: "John", // metin
        // veya
        name: <span>John</span>, // React öğesi
      })}
    </div>
    );
    
    tsx
    import { useIntlayer } from "react-intlayer";
    
    const { myInsertion } = useIntlayer("my-key");
    
    return (
    <div>
      {myInsertion({
        name: 2, // sayı
        // veya
        name: "John", // metin
        // veya
        name: <span>John</span>, // React öğesi
      })}
    </div>
    );
    
    vue
    <script setup>
    import { h } from "vue";
    import { useIntlayer } from "vue-intlayer";
    
    const { myInsertion } = useIntlayer("my-key");
    </script>
    
    <template>
    <div>
      <component
        :is="myInsertion({
          name: 2,
          // veya
          name: 'John',
          // veya
          name: h('span', 'John'),
        })"
      />
    </div>
    </template>
    
    tsx
    import { useIntlayer } from "preact-intlayer";
    
    const { myInsertion } = useIntlayer("my-key");
    
    return (
    <div>
      {myInsertion({
        name: 2, // sayı
        // veya
        name: "John", // dize
        // veya
        name: <span>John</span>, // Preact öğesi
      })}
    </div>
    );
    
    tsx
    import { useIntlayer } from "solid-intlayer";
    
    const { myInsertion } = useIntlayer("my-key");
    
    return (
    <div>
      {myInsertion({
        name: 2, // sayı
        // veya
        name: "John", // dize
        // veya
        name: <span>John</span>, // Solid öğesi
      })}
    </div>
    );
    
    svelte
    <script>
    import { useIntlayer } from "svelte-intlayer";
    
    const { myInsertion } = useIntlayer("my-key");
    </script>
    
    <div>
    {myInsertion({
      name: 2, // sayı
      // veya
      name: "John", // string
    })}
    </div>
    
    typescript
    import { Component } from "@angular/core";
    import { useIntlayer } from "angular-intlayer";
    
    @Component({
    selector: "app-insertion-example",
    template: `
      <div>
        {{ content().myInsertion({
          name: 'John'
        }) }}
      </div>
    `,
    })
    export class InsertionExampleComponent {
    content = useIntlayer("my-key");
    }
    

    Unicode CLDR Çoğul Kuralları (v8.8.0)

    Karmaşık diller için desteği artıran, Unicode CLDR Projesi tarafından tanımlanan çoğul kurallarına dayalı yeni bir plural düğüm yardımcısı (helper) tanıtıldı.

    src/openings.content.ts
    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",
          }),
        }),
      },
    } satisfies Dictionary;
    
    export default openingsContent;
    

    Daha sonra framework bileşeninizde sayıyı dinamik olarak geçirebilirsiniz:

    tsx
    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)           */}
          <p>{totalOpenings(count)}</p>
        </div>
      );
    };
    

    Daha fazla bilgi için Çoğullaştırma Dokümantasyonu sayfasına bakın.

    İçerik Şeması Doğrulama

    Intlayer v8, sözlükler için şema doğrulamasını tanıtır. Artık yapılandırmanızda Zod kullanarak yeniden kullanılabilir doğrulama şemaları tanımlayabilir ve bunları içerik dosyalarınıza uygulayabilirsiniz. Bu, içeriğinizin her zaman beklenen yapıya uygun olmasını sağlar ve hataları build zamanında yakalar.

    1. Şemaları Tanımlayın

    Şemalarınızı intlayer.config.ts içinde tanımlayın:

    intlayer.config.ts
    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. Şemaları Sözlüklere Uygulayın

    Sözlük tanımınızda şema anahtarına başvurun:

    src/example.content.ts
    import { type Dictionary } from "intlayer";
    
    const aboutPageMetaContent = {
      key: "about-page-meta",
      schema: "seo-metadata", // <-- şema anahtarı
      content: {
        title: "Şirketimiz Hakkında - Bizim Hakkımızda Daha Fazla Bilgi Edinin",
        description: "Şirketimizin misyonunu, değerlerini ve ekibini keşfedin.",
      },
    } satisfies Dictionary;
    
    export default aboutPageMetaContent;
    

    Eğer içerik şemayla eşleşmezse (ör. başlık çok kısaysa), build süreci bir hata verecektir.

    TypeScript: IntlayerNode İlkel Erişimcileri (Primitive Accessors)

    IntlayerNode tipi, ilkel JavaScript metotlarının doğrudan içerik düğümleri üzerinde çağrılmasına izin verecek şekilde güncellendi. Bu, yerelleştirilmiş içeriğinizle doğrudan standart bir string, number, boolean veya array ilkel tipiymiş gibi etkileşime girmenizi mümkün kılar.

    React, Preact, Solid, Svelte, Vue ve Angular genelinde desteklenir.

    String Örneği

    typescript
    content.placeholder; // IntlayerNode<string> döner
    content.placeholder.value; // string döner
    content.placeholder.toString(); // string döner
    content.placeholder.toLowerCase(); // string döner
    String(content.placeholder); // string döner
    content.placeholder.toUpperCase(); // Büyük harfe dönüştürülmüş string döner
    content.placeholder.replace("a", "b"); // Değiştirilmiş string döner
    

    Array Örneği

    typescript
    content.myArrayOfString             // IntlayerNode<Array<string>> döner
    content.myArrayOfString.find(...)   // Eleman döner
    content.myArrayOfString.join(', ')  // Birleştirilmiş string döner
    

    Geliştirilmiş Otomatik İçerik Algılama

    v8'de Intlayer, içerik dizelerinizde Markdown sözdizimini, HTML etiketlerini ve değişken yerleştirmelerini akıllıca algılar. Bu, genellikle md(), html() veya insert() gibi yardımcı fonksiyonları atlamanıza olanak tanır.

    Bu davranış varsayılan olarak etkindir. Bu algılamayı artık küresel olarak intlayer.config.ts içinde veya her bir sözlük düzeyinde ince ayar yapabilirsiniz.

    Daha Ayrıntılı Kontrol

    Belirli dönüşüm türlerini etkinleştirebilir veya devre dışı bırakabilirsiniz:

    intlayer.config.ts
    export default {
      dictionary: {
        // contentAutoTransformation: false (varsayılan)
        contentAutoTransformation: {
          markdown: true,
          html: true,
          insertion: false, // Otomatik yerleştirme algılamasını devre dışı bırak
        },
      },
    };
    

    v7 davranışı (Manuel sarmalama):

    src/example.content.ts
    import { md, insert } from "intlayer";
    
    export default {
      key: "my-key",
      content: {
        myMarkdown: md("## Hello World"),
        myInsertion: insert("Merhaba {{name}}"),
      },
    };
    

    v8 davranışı (Otomatik algılama):

    src/example.content.ts
    export default {
      key: "my-key",
      contentAutoTransformation: true, // Sözlük tanımında veya intlayer.config.ts'de global olarak da ayarlanabilir
      content: {
        myMarkdown: "## Hello World", // Otomatik olarak Markdown olarak algılanır
        myHTML: "<p>Hello World</p>", // Otomatik olarak HTML olarak algılanır
        myInsertion: "Merhaba {{name}}", // Otomatik olarak Ekleme (Insertion) olarak algılanır
      },
    };
    

    Aşağıdaki JSON sonucu aynı kalır ve render için gereken zengin tip bilgisini korur:

    json
    {
      "key": "my-key",
      "content": {
        "myMarkdown": {
          "nodeType": "markdown",
          "markdown": "## Hello World"
        },
        "myHTML": {
          "nodeType": "html",
          "html": "<p>Hello World</p>"
        },
        "myInsertion": {
          "nodeType": "insertion",
          "insertion": "Hi {{name}}"
        }
      }
    }
    

    Yerelleştirme: yeni useIntl hook'u

    React, Next.js ve Vue için yeni bir useIntl() hook'u artık kullanılabilir. Bu, sayıları, tarihleri ve daha fazlasını biçimlendirirken geçerli dili otomatik olarak kullanan locale-bağlı bir Intl nesnesi sağlar; locale'yi elle geçirmeye gerek yoktur.

    tsx
    import { useIntl } from "next-intlayer";
    
    const intl = useIntl();
    
    const formattedPrice = new intl.NumberFormat({
    style: "currency",
    currency: "USD",
    }).format(123.45);
    
    tsx
    import { useIntl } from "react-intlayer";
    
    const intl = useIntl();
    
    const formattedPrice = new intl.NumberFormat({
    style: "currency",
    currency: "USD",
    }).format(123.45);
    
    vue
    <script setup>
    import { useIntl } from "vue-intlayer";
    
    const intl = useIntl();
    
    const formattedPrice = new intl.NumberFormat({
    style: "currency",
    currency: "USD",
    }).format(123.45);
    </script>
    
    tsx
    import { useIntl } from "preact-intlayer";
    
    const intl = useIntl();
    
    const formattedPrice = new intl.NumberFormat({
    style: "currency",
    currency: "USD",
    }).format(123.45);
    
    tsx
    import { useIntl } from "solid-intlayer";
    
    const intl = useIntl();
    
    const formattedPrice = new intl.NumberFormat({
    style: "currency",
    currency: "USD",
    }).format(123.45);
    
    svelte
    <script>
    import { useIntl } from "svelte-intlayer";
    
    const intl = useIntl();
    
    const formattedPrice = new intl.NumberFormat({
      style: "currency",
      currency: "USD",
    }).format(123.45);
    </script>
    
    typescript
    import { Component, computed } from "@angular/core";
    import { useIntl } from "angular-intlayer";
    
    @Component({
    selector: "app-intl-example",
    template: `<div>{{ formattedPrice() }}</div>`,
    })
    export class IntlExampleComponent {
    intl = useIntl();
    
    formattedPrice = computed(() =>
      new (this.intl().NumberFormat)({
        style: "currency",
        currency: "USD",
      }).format(123.45)
    );
    }
    

    Araçlar: VSCode Uzantısı Geliştirmeleri

    Intlayer VSCode uzantısı, uluslararasılaştırma iş akışınızı kolaylaştırmak için v8'de önemli güncellemeler alıyor:

    • Başlangıç Süresi: Bir proje açılırken performans iyileştirmeleri.
    • Önbellekleme: Neredeyse anlık doğrulama ve otomatik tamamlama için geliştirilmiş önbellekleme katmanı.
    • Kullanılmayan Anahtarlar & Çoğaltılmış Anahtarların Tespiti: Sözlüklerinizdeki kullanılmayan anahtarları ve çoğaltılmış anahtarları otomatik olarak tespit eden yeni özellikler; içeriğinizi temiz ve verimli tutmanıza yardımcı olur.

    Araçlar: C++ Watcher ve OXC Tabanlı LSP (v8.12.0)

    Intlayer v8.12.0, geliştirici deneyimine büyük iyileştirmeler getiriyor:

    • Parcel Watcher: İçerik izleyici (content watcher), daha hızlı güncellemeler sağlamak ve bellek tüketimini önemli ölçüde azaltmak için yerel C++ dosya izlemeden yararlanan @parcel/watcher paketine chokidar'dan taşındı.
    • Yeni Language Server Protocol (LSP): Yepyeni bir LSP artık kullanılabilir. OXC tabanlı ayrıştırma ile oluşturulan bu protokol, IDE'nizin ve yapay zeka ajanlarınızın useIntlayer('my-key') çağrılarını ilgili .content dosyalarıyla ve tersi şekilde sorunsuz bir şekilde ilişkilendirmesine yardımcı olur.

    Daha fazla ayrıntı için LSP Dokümantasyonu sayfasına bakın.

    Derleyici Optimizasyonları

    Intlayer v8, Markdown ve HTML derleyicisi için yeni bir önbellekleme katmanı içerir. Bu, aynı yapılandırmaya sahip özdeş içerik dizelerinin yalnızca bir kez ayrıştırılmasını sağlar; bu da yeniden render'lar sırasında veya aynı içeriğin birden çok yerde kullanılması durumunda genel yükü önemli ölçüde azaltır.

    babel.config.js
    const {
    intlayerExtractBabelPlugin,
    intlayerOptimizeBabelPlugin,
    getExtractPluginOptions,
    getOptimizePluginOptions,
    } = require('@intlayer/babel');
    
    module.exports = {
    presets: ['next/babel'],
    plugins: [
      // Bileşenlerden içeriği sözlüklere çıkar
      [intlayerExtractBabelPlugin, getExtractPluginOptions()],
      // useIntlayer'ı doğrudan sözlük importlarıyla değiştirerek importları optimize et
      [intlayerOptimizeBabelPlugin, getOptimizePluginOptions()],
    ],
    };
    
    vite.config.js
    import { defineConfig } from 'vite';
    import { intlayer, intlayerCompiler } from "vite-intlayer";
    
    export default defineConfig({
    plugins: [intlayer(), intlayerCompiler()],
    });
    

    Vue / Svelte için uygun derleyici paketini yüklemeniz gerekecek:

    bash
    # Vue için
    npm install @intlayer/vue-compiler
    
    bash
    # Svelte için
    npm install @intlayer/svelte-compiler
    

    Deneysel Build Optimizasyonları: Minify ve Purge (v8.7.0)

    Intlayer v8.7.0, üretim (production) bundle'ınızı optimize etmek için tasarlanmış, intlayer.config.ts dosyanızda kullanabileceğiniz yeni deneysel build özellikleri sunar:

    • Sözlük Minifikasyonu (Minification): Boyutu azaltmak için sözlük dosyalarını küçültür (minify eder).
    • Kullanılmayan Anahtarları Temizleme (Purging): Sözlüklerden kullanılmayan çeviri anahtarlarını tarar ve kaldırır, aktif anahtarları kısa karakterlere yeniden adlandırır (örneğin "products" -> "a", "pricing" -> "b"). Bu, bundle boyutunu %5'e kadar azaltır.
    • TypeScript Kontrollerini Devre Dışı Bırakma: Derleme adımı sırasında TypeScript tip kontrolünü (typechecking) devre dışı bırakarak build işlemlerini hızlandırır.
    intlayer.config.ts
    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;
    

    Esneklik: Birleştirilmiş İçe Aktarma Modu

    live boolean özelliği, daha kapsamlı olan importMode özelliği lehine kullanımdan kaldırıldı. Bu, sözlüklerin nasıl yükleneceğini açıkça tanımlamanıza olanak tanır: statik olarak, dinamik olarak veya canlı senkronizasyon ile.

    Modlar

    • static (Varsayılan): Sözlük build zamanında paketlenir. Performans için en iyisidir.
    • dynamic: Sözlük çalışma zamanında yüklenir (ör. JSON fetch veya suspense).
    • fetch: Sözlük çalışma zamanında CMS/Server'dan çekilir ve senkronize edilir.

    Geçiş:

    v7 Yapılandırmasıv8 Yapılandırması
    live: trueimportMode: 'fetch'
    live: falseimportMode: 'static' (veya 'dynamic')

    Not: Intlayer v8'de, importMode özelliği intlayer.config.ts içindeki build yapılandırmasından alınarak dictionary yapılandırmasına taşındı. Bu sayede tüm sözlükleriniz için varsayılan bir içe aktarma modu tanımlayabilir ve yine de sözlük bazında override yapabilirsiniz.

    Küresel Yapılandırma Örneği:

    intlayer.config.ts
    export default {
      dictionary: {
        importMode: "dynamic", // Küresel varsayılan
      },
      // ...
    };
    

    Sözlük Örneği:

    src/example.content.ts
    export default {
        key: 'my-key',
        importMode: "fetch", // Küresel yapılandırmayı geçersiz kılar
        content: { ... }
    }
    

    Sözlük Konumu Kontrolü

    v8, sözlüklerin nerede bulunduğunu ve nasıl senkronize edileceğini açıkça yönetmek için location özelliğini tanıtır. Bu, hem yerel dosyaları hem de uzak CMS içeriğini içeren hibrit iş akışları için özellikle kullanışlıdır.

    Seçenekler

    • local: Sözlük yalnızca yerelde bulunur. Uzak CMS'ye gönderilmeyecektir.
    • remote: Sözlük uzaktan yönetilir. CMS'ye gönderildikten sonra yereldekinden ayrılacaktır. Uzak sözlük CMS'den çekilecektir.
    • local_and_remote: Sözlük her iki yerde de bulunur. Yerel değişiklikler gönderilir ve uzak değişiklikler çekilir (senkronize edilir).

    Örnek:

    src/example.content.ts
    export default {
        key: 'my-key',
        location: "local", // Bu sözlüğü yalnızca yerelde tut
        content: { ... }
    }
    

    Sistem Yapılandırma Ayrımı

    Intlayer v8, içerik kaynaklarının yapılandırmasını dahili sistem ve çıktı yollarından ayırır. Bu, content özelliğini sadeleştirir ve hangi ayarların kullanıcı tarafından yönetilmek üzere, hangilerinin Intlayer sistemi tarafından yönetilmek üzere olduğunun net olmasını sağlar.

    Aşağıdaki özellikler content'ten alınarak intlayer.config.ts içindeki yeni system özelliğine taşındı:

    • dictionariesDir
    • moduleAugmentationDir
    • unmergedDictionariesDir
    • typesDir
    • mainDir
    • configDir
    • cacheDir
    • outputFilesPatternWithPath

    v7 davranışı:

    intlayer.config.ts
    export default {
      content: {
        contentDir: ["src"],
        dictionariesDir: ".intlayer/dictionary", // Kaynak yapılandırmasıyla karışık
      },
    };
    

    v8 davranışı:

    intlayer.config.ts
    export default {
      content: {
        contentDir: ["src"],
      },
      system: {
        dictionariesDir: ".intlayer/dictionary", // Net şekilde ayrıldı
      },
    };
    

    İçerik ve Kod Dizin Ayrımı

    Intlayer v8, içerik tanım dosyalarının yapılandırmasını kod dönüşümü yapılandırmasından ayırır. Bu, izleme ve tarama işlemlerinin daha hassas yapılmasını sağlayarak derleme performansını iyileştirir.

    Önceden contentDir, hem .content.* dosyalarını izlemek hem de kodu useIntlayer çağrıları için taramak amacıyla kullanılıyordu. Şimdi:

    • contentDir: İçerik bildirim dosyalarınız için özel olarak kullanılır.
    • codeDir: Dönüşüm gerektiren uygulama kodunuz için özel olarak kullanılır (ör. budama, optimizasyon).

    Geçiş:

    Önceden contentDir ayarlıysa, Intlayer v8 bunu varsayılan olarak codeDir için de kullanacaktır, ancak bir uyarı kaydı oluşturacaktır. Yapılandırmanızda codeDir'i açıkça tanımlamalısınız.

    v7 davranışı:

    intlayer.config.ts
    export default {
      content: {
        contentDir: ["src", "@packages/design-system"], // Hem içerik hem de kod için kullanıldı
      },
    };
    

    v8 davranışı:

    intlayer.config.ts
    export default {
      content: {
        contentDir: ["src/content", "@packages/design-system"], // Burada yalnızca src/content/*.content.* dosyaları ve @packages/design-system/dist/*.content.* dosyaları izlenir
        codeDir: ["src", "@packages/design-system"], // Burada yalnızca kod dönüşümü için tarama yapılır ve @packages/design-system/src/*.content.* dosyaları taranır
      },
    };
    

    Çerçeve: Svelte İyileştirmeleri

    Svelte'deki Markdown ve HTML içerikleri artık stringleştirildiklerinde otomatik olarak HTML'e parse edilir. Bu, Svelte'in {@html} sözdizimiyle kullanımı çok daha kolay hale getirir; artık içerik düğümünü doğrudan iletebilirsiniz.

    Angular Desteği: Vite Bundler (v8.11.0)

    Angular kullanıcıları için Intlayer, artık yeni bir özel esbuild eklentisi aracılığıyla Vite bundler'ı yerel olarak destekleyerek geliştirme ve derleme (build) sürelerini hızlandırıyor.

    Yapılandırma detayları için Angular Ortam Dokümantasyonu sayfasına bakın.

    Site Haritası (Sitemap) Oluşturma (v8.6.0)

    Intlayer artık dillerinize (locales) ve yönlendirme (routing) modunuza göre otomatik olarak site haritaları oluşturuyor. Bu, özellikle TanStack Router gibi yönlendirici mimarilerinde SEO optimizasyonu için son derece kullanışlıdır:

    src/routes/sitemap.xml.ts
    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" },
            });
          },
        },
      },
    });
    

    v7'den geçiş notları

    Yapılandırma Değişiklikleri

    • live özelliği: Sözlüklerdeki live özelliği kaldırıldı. Bunun yerine importMode: 'fetch' kullanın.
    • importMode: Yapılandırmadaki build.importMode özelliği kullanımdan kaldırıldı. Bunun yerine dictionary.importMode kullanın.
    • contentDir ve codeDir: contentDir artık özellikle içerik dosyaları içindir. Kod dönüşümü için yeni bir codeDir özelliği eklendi. Eğer codeDir ayarlanmazsa, Intlayer contentDir'e geri dönecek ve bir uyarı kaydedecektir.
    • Şema Doğrulama: Yeni schema özelliğini kullanmak için projenize zod'un yüklü olduğundan emin olun.

    Faydalı bağlantılar