Tác giả:
    Ngày tạo:2025-09-22Cập nhật lần cuối:2026-06-14

    Intlayer v8. Có gì mới?

    Chào mừng đến với Intlayer v8! Bản phát hành này tập trung vào nâng cao trải nghiệm nhà phát triển với phát hiện nội dung tự động, đảm bảo tính toàn vẹn dữ liệu bằng xác thực theo schema và cung cấp nhiều khả năng kiểm soát hơn đối với quản lý từ điển.

    www.youtube.com

    Mục lục


    Sự tiến hóa của nội dung phong phú: Markdown & HTML

    Intlayer v8 mang đến những cải tiến lớn về cách xử lý nội dung phong phú, giới thiệu nút HTML (không tồn tại trong v7) và hợp nhất API với nút Markdown (đã tồn tại trong v7 nhưng được nâng cao).

    API .use() hợp nhất

    Chúng tôi đã giới thiệu phương thức .use() cho cả nút Markdown và HTML. Phương thức này cho phép bạn tùy chỉnh các thẻ HTML hoặc các component được sử dụng trong quá trình render.

    • Thay thế component: Bạn có thể dễ dàng thay thế các thẻ HTML hoặc các component tùy chỉnh bằng các component framework của riêng bạn (ví dụ: thay thế <a> bằng NextLink hoặc <CustomCmp> bằng một component React).
    • An toàn kiểu dữ liệu (Type Safety): Tất cả các hàm cung cấp component đều được định kiểu đầy đủ, đảm bảo bạn nhận được các props chính xác.

    Hành vi render mặc định

    Trong v7, nếu không có provider nào được xác định, các nút Markdown sẽ được render dưới dạng chuỗi thô, thường yêu cầu các thư viện bên ngoài để phân tích cú pháp.

    Trong v8, Intlayer bao gồm trình phân tích cú pháp Markdown nội bộ của riêng mình. Theo mặc định, các nút Markdown hiện được render trực tiếp dưới dạng HTML mà không cần bất kỳ thư viện bên ngoài nào.

    Các tiện ích Renderer & Provider mới

    Chúng tôi đã giới thiệu các hàm renderer và component độc lập mới để cung cấp cho bạn nhiều quyền kiểm soát hơn bên ngoài luồng useIntlayer tiêu chuẩn.

    • Markdown: MarkdownRenderer, useMarkdownRenderer, renderMarkdown. (Lưu ý: MarkdownProvider đã tồn tại trong v7 nhưng hiện tích hợp với các công cụ mới này).
    • HTML: HTMLRenderer, useHTMLRenderer, renderHTML, HTMLProvider.

    Ví dụ: Công cụ render Markdown

    1. Sử dụng Thành phần (Component):

    tsx
    import { MarkdownRenderer } from "react-intlayer/markdown";<MarkdownRenderer  forceBlock={true}  components={{    h1: ({ children }) => <h1 className="text-2xl">{children}</h1>  }}>  {"# My Title"}</MarkdownRenderer>

    2. Sử dụng Hook:

    tsx
    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. Sử dụng Hàm tiện ích:

    tsx
    import { renderMarkdown } from "react-intlayer/markdown";const html = renderMarkdown("# My Title", {  forceBlock: true});

    Ví dụ: Công cụ render HTML

    1. Sử dụng Thành phần (Component):

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

    2. Sử dụng Hook:

    tsx
    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. Sử dụng Hàm tiện ích:

    tsx
    import { renderHTML } from "react-intlayer/html";const html = renderHTML("<p>Hello World</p>");

    Để biết thêm chi tiết, xem Tài liệu Nội dung HTMLTài liệu Markdown.


    Tệp Nội dung YAML & Markdown (v8.10.0)

    Giờ đây, bạn có thể khai báo nội dung trực tiếp bằng các phần mở rộng tệp .content.md.content.yaml. Điều này hoàn hảo cho nội dung dạng dài, blog, tài liệu và chính sách bảo mật.

    Các tệp này hoàn toàn có thể chỉnh sửa từ Visual Editor, mang lại quy trình làm việc hợp lý cho các thành viên không thuộc nhóm kỹ thuật.

    Để biết thêm chi tiết, xem Tài liệu Tệp Nội dung YAMLTài liệu Tệp Nội dung Markdown.


    Viết lại URL tùy chỉnh

    Intlayer v8 giới thiệu hỗ trợ cho Viết lại URL tùy chỉnh, cho phép bạn định nghĩa các đường dẫn theo ngôn ngữ (locale) khác với cấu trúc chuẩn /locale/path. Đây là một tính năng mạnh mẽ để cải thiện SEO địa phương và mang lại trải nghiệm người dùng tự nhiên hơn cho những người không nói tiếng Anh.

    Các cải tiến chính trong v8:

    • Bộ định dạng cho framework: Thêm nextjsRewrite, svelteKitRewrite, reactRouterRewrite, vueRouterRewrite, solidRouterRewrite, tanstackRouterRewrite, nuxtRewrite, và viteRewrite để cung cấp cú pháp mẫu đặc trưng cho từng router.
    • Hook useRewriteURL: một hook phía client mới tự động chỉnh sửa thanh địa chỉ thành URL địa phương "đẹp" mà không kích hoạt điều hướng của router.
    • Chuyển hướng SEO tự động: Các proxy tích hợp bây giờ tự động chuyển hướng người dùng từ các đường dẫn chuẩn được gõ thủ công (ví dụ: /fr/about) sang các phiên bản địa phương "đẹp" hơn của chúng (ví dụ: /fr/a-propos).

    Cấu hình ví dụ:

    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;

    Tính năng này được hỗ trợ sẵn (out-of-the-box) trong Next.jsVite thông qua các proxies của Intlayer, và có thể dễ dàng tích hợp vào các router khác như TanStack Router, React Router, Vue Router, SvelteKit, và Solid Router.

    Để biết thêm thông tin và hướng dẫn tích hợp, xem Tài liệu Viết lại URL tùy chỉnh.


    Giá trị insertion được cải tiến

    Trong v8, các giá trị insertion bây giờ có thể chấp nhận React elements (hoặc Vue nodes) bên cạnh chuỗi và số. Điều này cho phép bạn chèn các thành phần phong phú và tương tác trực tiếp vào các mẫu insertion của mình.

    Intlayer hiện xử lý mạnh mẽ các node React và Preact lồng nhau trong các insertions, đảm bảo các cấu trúc UI phức tạp được giữ nguyên và kết xuất đúng.

    Ví dụ:

    src/example.content.ts
    import { insert } from "intlayer";export default {  key: "my-key",  content: {    myInsertion: insert("Hi {{name}}"),  },};
    tsx
    import { useIntlayer } from "next-intlayer";const { myInsertion } = useIntlayer("my-key");return (  <div>    {myInsertion({      name: 2, // số      // hoặc      name: "John", // chuỗi      // hoặc      name: <span>John</span>, // phần tử React    })}  </div>);

    Quy tắc số nhiều Unicode CLDR (v8.8.0)

    Một helper nút plural mới đã được giới thiệu dựa trên các quy tắc số nhiều được định nghĩa bởi Dự án Unicode CLDR, giúp cải thiện hỗ trợ cho các ngôn ngữ phức tạp.

    src/openings.content.ts
    import { plural, t, type Dictionary } from "intlayer";const openingsContent = {  key: "total_openings",  content: {    totalOpenings: t({      vi: plural({        other: "{{count}} cơ hội",      }),      en: plural({        one: "{{count}} opening",        other: "{{count}} openings",      }),      fr: plural({        one: "{{count}} offre",        other: "{{count}} offres",      }),    }),  },} satisfies Dictionary;export default openingsContent;

    Sau đó, bạn có thể truyền số lượng một cách động trong component framework của mình:

    tsx
    import type { FC } from "react";import { useIntlayer } from "react-intlayer";const OpeningsComponent: FC<{ count: number }> = ({ count }) => {  const { totalOpenings } = useIntlayer("total_openings");  return (    <div>      {/* Trong tiếng Anh:                             */}      {/*  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>  );};

    Để biết thêm thông tin, xem Tài liệu Đa dạng hóa (Pluralization).


    Xác thực Schema Nội dung

    Intlayer v8 giới thiệu tính năng xác thực schema cho các dictionaries. Bây giờ bạn có thể định nghĩa các schema xác thực có thể tái sử dụng trong cấu hình của mình bằng Zod và áp dụng chúng cho các file nội dung. Điều này đảm bảo nội dung của bạn luôn tuân theo cấu trúc mong đợi, giúp phát hiện lỗi trong quá trình build.

    1. Định nghĩa Schema

    Định nghĩa các schema trong intlayer.config.ts:

    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. Áp dụng Schema cho các Dictionaries

    Tham chiếu khóa schema trong định nghĩa dictionary của bạn:

    src/example.content.ts
    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;

    Nếu nội dung không khớp với schema (ví dụ: title quá ngắn), quá trình build sẽ báo lỗi.


    TypeScript: Các bộ truy cập nguyên bản IntlayerNode

    Kiểu IntlayerNode đã được cập nhật để cho phép gọi trực tiếp các phương thức JavaScript nguyên bản (primitive) trên các nút nội dung. Điều này giúp bạn có thể tương tác trực tiếp với nội dung đã được bản địa hóa của mình như thể nó là một chuỗi, số, boolean hoặc mảng nguyên bản tiêu chuẩn.

    Được hỗ trợ trên React, Preact, Solid, Svelte, Vue và Angular.

    Ví dụ về Chuỗi (String)

    typescript
    content.placeholder; // Trả về IntlayerNode<string>content.placeholder.value; // Trả về stringcontent.placeholder.toString(); // Trả về stringcontent.placeholder.toLowerCase(); // Trả về stringString(content.placeholder); // Trả về stringcontent.placeholder.toUpperCase(); // Trả về chuỗi viết hoacontent.placeholder.replace("a", "b"); // Trả về chuỗi đã sửa đổi

    Ví dụ về Mảng (Array)

    typescript
    content.myArrayOfString             // Trả về IntlayerNode<Array<string>>content.myArrayOfString.find(...)   // Trả về phần tửcontent.myArrayOfString.join(', ')  // Trả về chuỗi được nối

    Phát hiện nội dung tự động nâng cao

    Trong v8, Intlayer tự động nhận diện thông minh cú pháp Markdown, thẻ HTML và các chèn biến trong các chuỗi nội dung của bạn. Điều này có nghĩa là bạn thường có thể bỏ qua các hàm trợ giúp như md(), html() hoặc insert().

    Hành vi này được bật theo mặc định. Bạn có thể tinh chỉnh việc phát hiện này toàn cục trong intlayer.config.ts hoặc cho từng dictionary.

    Kiểm soát chi tiết

    Bạn có thể bật hoặc tắt các loại chuyển đổi cụ thể:

    intlayer.config.ts
    export default {  dictionary: {    // contentAutoTransformation: false (mặc định)    contentAutoTransformation: {      markdown: true,      html: true,      insertion: false, // Vô hiệu hóa phát hiện tự động cho insertion    },  },};

    Hành vi v7 (Bao bọc thủ công):

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

    Hành vi v8 (Phát hiện tự động):

    src/example.content.ts
    export default {  key: "my-key",  contentAutoTransformation: true, // Có thể cũng được đặt bởi định nghĩa dictionary hoặc toàn cục trong intlayer.config.ts  content: {    myMarkdown: "## Xin chào Thế giới", // Tự động được phát hiện là Markdown    myHTML: "<p>Xin chào Thế giới</p>", // Tự động được phát hiện là HTML    myInsertion: "Chào {{name}}", // Tự động được phát hiện là Insertion  },};

    The underlying JSON result remains the same, preserving the rich type information needed for rendering:

    json
    {  "key": "my-key",  "content": {    "myMarkdown": {      "nodeType": "markdown",      "markdown": "## Xin chào Thế giới"    },    "myHTML": {      "nodeType": "html",      "html": "<p>Xin chào Thế giới</p>"    },    "myInsertion": {      "nodeType": "insertion",      "insertion": "Hi {{name}}"    }  }}

    Địa phương hóa: hook useIntl mới

    Một hook useIntl() mới hiện có sẵn trong React, Next.js và Vue. Nó cung cấp một đối tượng Intl liên kết với locale, tự động sử dụng ngôn ngữ hiện tại để định dạng số, ngày tháng và nhiều thứ khác, mà không cần phải truyền thủ công locale.

    tsx
    import { useIntl } from "next-intlayer";const intl = useIntl();const formattedPrice = new intl.NumberFormat({  style: "currency",  currency: "USD",}).format(123.45);

    Công cụ: Cải tiến Extension VSCode

    Phần mở rộng Intlayer cho VSCode nhận được các cập nhật lớn trong v8 nhằm hợp lý hóa quy trình làm việc về quốc tế hóa của bạn:

    • Thời gian khởi động: Cải thiện hiệu suất khi mở một dự án.
    • Bộ nhớ đệm: Tầng caching được nâng cấp để xác thực và gợi ý tự động gần như tức thì.
    • Phát hiện Khóa Không Sử dụng & Khóa Trùng Lặp: Các tính năng mới để tự động phát hiện khóa không sử dụngkhóa trùng lặp trong các từ điển của bạn, giúp giữ nội dung gọn gàng và hiệu quả.

    Công cụ: C++ Watcher & OXC-based LSP (v8.12.0)

    Intlayer v8.12.0 mang lại những cải tiến lớn cho trải nghiệm nhà phát triển:

    • Parcel Watcher: Trình theo dõi nội dung (content watcher) đã được di chuyển từ chokidar sang @parcel/watcher, tận dụng tính năng theo dõi tệp C++ gốc để cung cấp các bản cập nhật nhanh hơn và giảm đáng kể mức tiêu thụ bộ nhớ.
    • Language Server Protocol (LSP) mới: Một LSP hoàn toàn mới hiện đã sẵn sàng. Được xây dựng với phân tích cú pháp dựa trên OXC, nó giúp IDE và các tác nhân AI của bạn liên kết liền mạch các lệnh gọi useIntlayer('my-key') với các tệp .content tương ứng của chúng và ngược lại.

    Để biết thêm chi tiết, xem Tài liệu LSP.


    Tối ưu trình biên dịch

    Intlayer v8 bao gồm một lớp cache mới cho trình biên dịch Markdown và HTML. Điều này đảm bảo rằng các chuỗi nội dung giống hệt với cùng cấu hình chỉ được phân tích một lần, giảm đáng kể chi phí khi tái kết xuất hoặc khi sử dụng cùng nội dung ở nhiều nơi.

    babel.config.js
      const {  intlayerExtractBabelPlugin,  intlayerOptimizeBabelPlugin,  getExtractPluginOptions,  getOptimizePluginOptions,} = require('@intlayer/babel');module.exports = {  presets: ['next/babel'],  plugins: [    // Trích xuất nội dung từ components vào dictionaries    [intlayerExtractBabelPlugin, getExtractPluginOptions()],    // Tối ưu các imports bằng cách thay thế useIntlayer bằng import trực tiếp các dictionary    [intlayerOptimizeBabelPlugin, getOptimizePluginOptions()],  ],};

    Tối ưu hóa Build Thử nghiệm: Minify & Purge (v8.7.0)

    Intlayer v8.7.0 giới thiệu các tính năng build thử nghiệm mới trong intlayer.config.ts của bạn được thiết kế để tối ưu hóa bundle production của bạn:

    • Thu nhỏ từ điển (Dictionary Minification): Thu nhỏ các tệp từ điển để giảm kích thước.
    • Loại bỏ khóa không sử dụng (Unused Key Purging): Quét và loại bỏ các khóa dịch không sử dụng khỏi từ điển, đổi tên các khóa đang hoạt động thành các ký tự ngắn (ví dụ: "products" -> "a", "pricing" -> "b"). Điều này giúp giảm kích thước bundle lên tới 5%.
    • Vô hiệu hóa kiểm tra TypeScript: Tăng tốc độ build bằng cách vô hiệu hóa kiểm tra kiểu dữ liệu (typechecking) TypeScript trong bước biên dịch.
    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: {    /**     * Thu nhỏ các từ điển để giảm kích thước bundle.     */    minify: true,    /**     * Loại bỏ các khóa không sử dụng trong từ điển     */    purge: true,    /**     * Cho biết liệu quá trình build có nên kiểm tra các kiểu TypeScript hay không     */    checkTypes: false,  },};export default config;

    Tính linh hoạt: Chế độ import hợp nhất

    Thuộc tính boolean live đã bị đánh dấu là deprecated và được thay bằng thuộc tính importMode toàn diện hơn. Điều này cho phép xác định rõ ràng cách các dictionary nên được tải: theo kiểu tĩnh, động, hoặc qua đồng bộ trực tiếp.

    Các chế độ

    • static (Mặc định): Dictionary được đóng gói tại thời điểm build. Tối ưu cho hiệu năng.
    • dynamic: Dictionary được tải vào thời điểm runtime (ví dụ: thông qua fetch JSON hoặc suspense).
    • fetch: Dictionary được lấy từ CMS/Server vào thời điểm runtime và được đồng bộ.

    Di chuyển:

    Cấu hình v7 Cấu hình v8
    live: true importMode: 'fetch'
    live: false importMode: 'static' (hoặc 'dynamic')

    Lưu ý: Trong Intlayer v8, thuộc tính importMode đã được chuyển từ cấu hình build sang cấu hình dictionary trong intlayer.config.ts. Điều này cho phép bạn định nghĩa chế độ import mặc định cho tất cả các dictionary trong khi vẫn có thể ghi đè cho từng dictionary riêng lẻ.

    Ví dụ Cấu hình Toàn cục:

    intlayer.config.ts
    export default {  dictionary: {    importMode: "dynamic", // Mặc định toàn cục  },  // ...};

    Ví dụ Dictionary:

    src/example.content.ts
    export default {    key: 'my-key',    importMode: "fetch", // Ghi đè cấu hình toàn cục    content: { ... }}

    Kiểm soát vị trí Dictionary

    v8 giới thiệu thuộc tính location để quản lý rõ ràng nơi lưu trữ các dictionary và cách chúng đồng bộ hóa. Điều này đặc biệt hữu ích cho các luồng công việc hybrid liên quan đến cả file cục bộ và nội dung CMS từ xa.

    Tùy chọn

    • local: Từ điển chỉ tồn tại cục bộ. Nó sẽ không được đẩy lên CMS từ xa.
    • remote: Từ điển được quản lý từ xa. Khi đã được đẩy lên CMS, nó sẽ tách rời khỏi bản cục bộ. Từ điển từ xa sẽ được kéo từ CMS.
    • local_and_remote: Từ điển tồn tại ở cả hai nơi. Thay đổi cục bộ được đẩy lên, và thay đổi từ xa được kéo về (đồng bộ hóa).

    Ví dụ:

    src/example.content.ts
    export default {    key: 'my-key',    location: "local", // Giữ từ điển này chỉ ở cục bộ    content: { ... }}

    Phân tách Cấu hình Hệ thống

    Intlayer v8 tách cấu hình các nguồn nội dung khỏi các đường dẫn hệ thống nội bộ và đường dẫn đầu ra. Điều này làm gọn thuộc tính content và làm rõ những thiết lập nào dành cho quản lý bởi người dùng so với những thiết lập được quản lý bởi hệ thống Intlayer.

    Các thuộc tính sau đã được chuyển từ content sang thuộc tính system mới trong intlayer.config.ts:

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

    Hành vi v7:

    intlayer.config.ts
    export default {  content: {    contentDir: ["src"],    dictionariesDir: ".intlayer/dictionary", // Bị trộn với cấu hình nguồn  },};

    Hành vi v8:

    intlayer.config.ts
    export default {  content: {    contentDir: ["src"],  },  system: {    dictionariesDir: ".intlayer/dictionary", // Được tách riêng rõ ràng  },};

    Tách thư mục nội dung và mã nguồn

    Intlayer v8 tách cấu hình cho các tệp định nghĩa nội dung khỏi cấu hình cho chuyển đổi mã. Điều này cho phép việc theo dõi và quét chính xác hơn, cải thiện hiệu năng build.

    Trước đây, contentDir được sử dụng cho cả việc theo dõi các tệp .content.* và quét mã để tìm các lời gọi useIntlayer. Hiện nay:

    • contentDir: Dành riêng cho các tệp khai báo nội dung của bạn.
    • codeDir: Dành riêng cho mã ứng dụng của bạn cần chuyển đổi (ví dụ: pruning, optimization).

    Di chuyển:

    Nếu trước đây bạn đã thiết lập contentDir, Intlayer v8 sẽ sử dụng nó làm mặc định cho codeDir nhưng sẽ ghi một cảnh báo. Bạn nên định nghĩa rõ codeDir trong cấu hình của mình.

    Hành vi v7:

    intlayer.config.ts
    export default {  content: {    contentDir: ["src", "@packages/design-system"], // Được sử dụng cho cả content và code  },};

    Hành vi v8:

    intlayer.config.ts
    export default {  content: {    contentDir: ["src/content", "@packages/design-system"], // Chỉ theo dõi các file src/content/*.content.* ở đây và các file @packages/design-system/dist/*.content.*    codeDir: ["src", "@packages/design-system"], // Chỉ quét để biến đổi mã ở đây  },};

    Framework: Cải tiến cho Svelte

    Nội dung Markdown và HTML trong Svelte bây giờ tự động được phân tích cú pháp thành HTML khi được chuyển thành chuỗi. Điều này khiến việc sử dụng với cú pháp {@html} của Svelte dễ dàng hơn nhiều, vì bạn giờ có thể truyền trực tiếp node nội dung.


    Hỗ trợ Angular: Vite Bundler (v8.11.0)

    Đối với người dùng Angular, Intlayer hiện hỗ trợ nguyên bản trình đóng gói Vite thông qua một plugin esbuild tùy chỉnh mới, giúp tăng tốc thời gian phát triển và build.

    Để biết chi tiết về cấu hình, xem Tài liệu Môi trường Angular.


    Tạo Sitemap (v8.6.0)

    Intlayer hiện tự động tạo sitemap dựa trên các locale và chế độ định tuyến (routing mode) của bạn. Điều này đặc biệt hữu ích cho việc tối ưu hóa SEO trong các kiến trúc router như TanStack Router:

    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" },        });      },    },  },});

    Ghi chú nâng cấp từ v7

    Thay đổi cấu hình

    • live property: Thuộc tính live trong các dictionary đã bị xóa. Hãy sử dụng importMode: 'fetch' thay thế.
    • importMode: Thuộc tính build.importMode trong cấu hình đã bị đánh dấu là không còn được khuyến khích. Hãy sử dụng dictionary.importMode thay thế.
    • contentDircodeDir: contentDir hiện được dùng riêng cho các tệp nội dung. Một thuộc tính mới codeDir đã được thêm để chuyển đổi mã. Nếu codeDir không được thiết lập, Intlayer sẽ fallback về contentDir và ghi log một cảnh báo.
    • Xác thực Schema: Để sử dụng tính năng schema mới, đảm bảo bạn đã cài zod trong dự án của mình.

    Liên kết hữu ích