> ## Documentation Index
> Fetch the complete documentation index at: https://inertiajs-vi.tuantq.online/llms.txt
> Use this file to discover all available pages before exploring further.

# Tiêu đề & Meta

Vì ứng dụng JavaScript dùng Inertia được render trong `<body>` của tài liệu, chúng không thể render markup vào `<head>` nằm ngoài scope. Để giải quyết, Inertia cung cấp component `<Head>` để đặt `<title>`, các thẻ `<meta>` và phần tử `<head>` khác của page.

Component `<Head>` chỉ thay thế các phần tử `<head>` không có trong root template phía máy chủ.

Component `<Head>` không có trong adapter Svelte vì Svelte đã cung cấp component `<svelte:head>` riêng.

## Component Head

Để thêm các phần tử `<head>` vào trang, hãy dùng component `<Head>`. Bên trong component này, bạn có thể đặt các phần tử muốn thêm vào `<head>` của tài liệu.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import { Head } from '@inertiajs/vue3'

  <Head>
      <title>Your page title</title>
      <meta name="description" content="Your page description">
  </Head>
  ```

  ```jsx React icon="react" theme={null}
  import { Head } from "@inertiajs/react";

  <Head>
    <title>Your page title</title>
    <meta name="description" content="Your page description" />
  </Head>;
  ```

  ```svelte Svelte icon="s" theme={null}
  <svelte:head>
      <title>Your page title</title>
      <meta name="description" content="Your page description" />
  </svelte:head>
  ```
</CodeGroup>

## Cú pháp rút gọn cho tiêu đề

Nếu chỉ cần thêm `<title>` vào `<head>` của tài liệu, bạn có thể truyền trực tiếp tiêu đề dưới dạng prop cho component `<Head>`.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import { Head } from '@inertiajs/vue3'

  <Head title="Your page title" />
  ```

  ```jsx React icon="react" theme={null}
  import { Head } from "@inertiajs/react";

  <Head title="Your page title" />;
  ```

  ```js Svelte icon="s" theme={null}
  // Not supported
  ```
</CodeGroup>

## Callback tiêu đề

Bạn có thể thay đổi `<title>` của trang trên toàn ứng dụng bằng callback `title` trong phương thức thiết lập `createInertiaApp`. Thông thường phương thức này được gọi trong file JavaScript chính của ứng dụng. Một trường hợp sử dụng phổ biến của callback tiêu đề là tự động thêm tên ứng dụng trước hoặc sau tiêu đề của từng trang.

```js theme={null}
createInertiaApp({
  title: (title) => `${title} - My App`,
  // ...
});
```

Callback cũng nhận [page object](/v3/the-basics/pages) hiện tại làm đối số thứ hai, có thể dùng để xây title từ props của page.

```js theme={null}
createInertiaApp({
  title: (title, page) => `${title} - ${page.props.appName}`,
  // ...
});
```

Sau khi định nghĩa callback `title`, callback sẽ tự động được gọi mỗi khi bạn thiết lập tiêu đề bằng component `<Head>`.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import { Head } from '@inertiajs/vue3'

  <Head title="Home">
  ```

  ```jsx React icon="react" theme={null}
  import { Head } from '@inertiajs/react'

  <Head title="Home">
  ```

  ```js Svelte icon="s" theme={null}
  // Not supported
  ```
</CodeGroup>

Trong ví dụ này, kết quả là thẻ `<title>` sau.

```html theme={null}
<title>Home - My App</title>
```

Callback `title` cũng sẽ được gọi khi bạn thiết lập tiêu đề bằng thẻ `<title>` bên trong component `<Head>`.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import { Head } from '@inertiajs/vue3'

  <Head>
      <title>Home</title>
  </Head>
  ```

  ```jsx React icon="react" theme={null}
  import { Head } from "@inertiajs/react";

  <Head>
    <title>Home</title>
  </Head>;
  ```

  ```js Svelte icon="s" theme={null}
  // Not supported
  ```
</CodeGroup>

## Nhiều instance Head

Bạn có thể có nhiều instance của component `<Head>` trong ứng dụng. Ví dụ, layout có thể thiết lập một số phần tử `<Head>` mặc định, sau đó từng trang riêng lẻ có thể ghi đè các giá trị mặc định đó.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  // Layout.vue import { Head } from '@inertiajs/vue3'

  <Head>
      <title>My app</title>
      <meta head-key="description" name="description" content="This is the default description" />
      <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
  </Head>

  // About.vue import { Head } from '@inertiajs/vue3'

  <Head>
      <title>About - My app</title>
      <meta head-key="description" name="description" content="This is a page specific description" />
  </Head>
  ```

  ```jsx React icon="react" theme={null}
  // Layout.js

  import { Head } from "@inertiajs/react";

  <Head>
    <title>My app</title>
    <meta
      head-key="description"
      name="description"
      content="This is the default description"
    />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
  </Head>;

  // About.js

  import { Head } from "@inertiajs/react";

  <Head>
    <title>About - My app</title>
    <meta
      head-key="description"
      name="description"
      content="This is a page specific description"
    />
  </Head>;
  ```

  ```js Svelte icon="s" theme={null}
  // Not supported
  ```
</CodeGroup>

Inertia chỉ render duy nhất một thẻ `<title>`; tuy nhiên, tất cả các thẻ khác sẽ được xếp chồng vì việc có nhiều instance của chúng là hợp lệ. Để tránh các thẻ trùng lặp trong `<head>`, bạn có thể dùng thuộc tính `head-key`, giúp đảm bảo mỗi thẻ chỉ được render một lần. Điều này được minh họa trong ví dụ trên với thẻ `<meta name="description">`.

Ví dụ code ở trên sẽ render HTML sau.

```html theme={null}
<head>
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
  <title>About - My app</title>
  <meta name="description" content="This is a page specific description" />
</head>
```

## Mở rộng Head

Khi xây dựng ứng dụng thực tế, đôi khi việc tạo một head component tùy chỉnh mở rộng component `<Head>` của Inertia sẽ hữu ích. Đây là nơi bạn có thể thiết lập các giá trị mặc định dùng toàn ứng dụng, chẳng hạn tự động nối tên ứng dụng vào tiêu đề trang.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  <!-- AppHead.vue -->

  <script setup>
  import { Head } from "@inertiajs/vue3";

  defineProps({ title: String });
  </script>

  <template>
    <Head :title="title ? `${title} - My App` : 'My App'">
      <slot />
    </Head>
  </template>
  ```

  ```jsx React icon="react" theme={null}
  // AppHead.js

  import { Head } from "@inertiajs/react";

  const Site = ({ title, children }) => {
    return (
      <Head>
        <title>{title ? `${title} - My App` : "My App"}</title>
        {children}
      </Head>
    );
  };

  export default Site;
  ```

  ```js Svelte icon="s" theme={null}
  // Not supported
  ```
</CodeGroup>

Sau khi tạo component tùy chỉnh, bạn chỉ cần bắt đầu sử dụng nó trong các trang.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  import AppHead from './AppHead'

  <AppHead title="About" />
  ```

  ```jsx React icon="react" theme={null}
  import AppHead from './AppHead'

  <AppHead title="About">
  ```

  ```js Svelte icon="s" theme={null}
  // Not supported
  ```
</CodeGroup>

## Head element phía server

Bạn có thể muốn đưa các head element mặc định như `<title>` hoặc `<meta>` vào root Blade template. Điều này tạo hai thách thức: tránh trùng lặp khi [SSR](/v3/advanced/server-side-rendering) hoạt động và đảm bảo component `<Head>` phía client có thể thay thế chúng khi điều hướng.

### SSR fallback

Blade component `<x-inertia::head>` nhận nội dung fallback qua slot. Nội dung này chỉ được render trong HTML ban đầu khi [SSR](/v3/advanced/server-side-rendering) không hoạt động. Khi SSR hoạt động, component `<Head>` đã cung cấp các phần tử này như một phần của server-rendered response nên fallback bị bỏ qua.

```blade resources/views/app.blade.php theme={null}
<head>
    @vite('resources/js/app.js')
    <x-inertia::head>
        <title>{{ config('app.name') }}</title>
        <meta name="description" content="My application description">
    </x-inertia::head>
</head>
```

### Thuộc tính `data-inertia`

Component `<Head>` phía client theo dõi các element nó quản lý bằng cách đánh dấu chúng với thuộc tính `data-inertia`. Mặc định nó để nguyên mọi tag khác trong Blade template. Vì chỉ có thể có một thẻ `<title>`, component `<Head>` luôn thay thế nó. Các element như `<meta>` và `<link>` có thể có nhiều instance, nên component cần cách nhận diện element nào mình phải quản lý.

Bạn có thể thêm thuộc tính `data-inertia` vào element trong Blade template để component `<Head>` tiếp quản chúng. Ở lần client-side navigation đầu tiên, nó sẽ khớp các element theo key rồi thay thế hoặc xóa khi cần.

```blade resources/views/app.blade.php theme={null}
<head>
    @vite('resources/js/app.js')
    <title>{{ config('app.name') }}</title>
    <meta data-inertia="description" name="description" content="My application description">
</head>
```

Giá trị `data-inertia` tương ứng với thuộc tính `head-key` trên các element `<Head>` phía client.

***

## Tài liệu chính thức

Bài dịch này được đối chiếu từ [tài liệu Inertia.js v3 chính thức](https://inertiajs.com/docs/v3/the-basics/title-and-meta). Nếu có khác biệt do phiên bản hoặc cập nhật mới, hãy ưu tiên tài liệu chính thức làm nguồn tham chiếu.
