> ## 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.

# Truy cập thủ công

Ngoài [tạo link](/v3/the-basics/links), bạn cũng có thể chủ động thực hiện Inertia visit hoặc request bằng JavaScript. Việc này được thực hiện qua phương thức `router.visit()`.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.visit(url, {
    method: "get",
    data: {},
    replace: false,
    preserveState: false,
    preserveScroll: false,
    only: [],
    except: [],
    headers: {},
    errorBag: null,
    forceFormData: false,
    queryStringArrayFormat: "brackets",
    async: false,
    showProgress: true,
    fresh: false,
    reset: [],
    preserveUrl: false,
    prefetch: false,
    preserveErrors: false,
    viewTransition: false,
    component: null,
    pageProps: null,
    onCancelToken: (cancelToken) => {},
    onCancel: () => {},
    onBefore: (visit) => {},
    onStart: (visit) => {},
    onProgress: (progress) => {},
    onSuccess: (page) => {},
    onError: (errors) => {},
    onHttpException: (response) => {},
    onNetworkError: (error) => {},
    onFinish: (visit) => {},
    onPrefetching: () => {},
    onPrefetched: () => {},
  });
  ```

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

  router.visit(url, {
    method: "get",
    data: {},
    replace: false,
    preserveState: false,
    preserveScroll: false,
    only: [],
    except: [],
    headers: {},
    errorBag: null,
    forceFormData: false,
    queryStringArrayFormat: "brackets",
    async: false,
    showProgress: true,
    fresh: false,
    reset: [],
    preserveUrl: false,
    prefetch: false,
    preserveErrors: false,
    viewTransition: false,
    component: null,
    pageProps: null,
    onCancelToken: (cancelToken) => {},
    onCancel: () => {},
    onBefore: (visit) => {},
    onStart: (visit) => {},
    onProgress: (progress) => {},
    onSuccess: (page) => {},
    onError: (errors) => {},
    onHttpException: (response) => {},
    onNetworkError: (error) => {},
    onFinish: (visit) => {},
    onPrefetching: () => {},
    onPrefetched: () => {},
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.visit(url, {
    method: "get",
    data: {},
    replace: false,
    preserveState: false,
    preserveScroll: false,
    only: [],
    except: [],
    headers: {},
    errorBag: null,
    forceFormData: false,
    queryStringArrayFormat: "brackets",
    async: false,
    showProgress: true,
    fresh: false,
    reset: [],
    preserveUrl: false,
    prefetch: false,
    preserveErrors: false,
    viewTransition: false,
    component: null,
    pageProps: null,
    onCancelToken: (cancelToken) => {},
    onCancel: () => {},
    onBefore: (visit) => {},
    onStart: (visit) => {},
    onProgress: (progress) => {},
    onSuccess: (page) => {},
    onError: (errors) => {},
    onHttpException: (response) => {},
    onNetworkError: (error) => {},
    onFinish: (visit) => {},
    onPrefetching: () => {},
    onPrefetched: () => {},
  });
  ```
</CodeGroup>

Tuy nhiên, nhìn chung sẽ thuận tiện hơn khi sử dụng một trong các phương thức request rút gọn của Inertia. Những phương thức này hỗ trợ đầy đủ các tùy chọn giống `router.visit()`.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.get(url, data, options);
  router.post(url, data, options);
  router.put(url, data, options);
  router.patch(url, data, options);
  router.delete(url, options);
  router.reload(options); // Uses the current URL
  ```

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

  router.get(url, data, options);
  router.post(url, data, options);
  router.put(url, data, options);
  router.patch(url, data, options);
  router.delete(url, options);
  router.reload(options); // Uses the current URL
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.get(url, data, options);
  router.post(url, data, options);
  router.put(url, data, options);
  router.patch(url, data, options);
  router.delete(url, options);
  router.reload(options); // Uses the current URL
  ```
</CodeGroup>

Phương thức `reload()` là cách viết tắt tiện lợi, tự động truy cập lại trang hiện tại với cả `preserveState` và `preserveScroll` đều được đặt thành `true`, vì vậy rất phù hợp khi bạn chỉ muốn tải lại dữ liệu của trang hiện tại.

## Phương thức

Khi thực hiện truy cập thủ công, bạn có thể dùng tùy chọn `method` để đặt HTTP method của request thành `get`, `post`, `put`, `patch` hoặc `delete`. Method mặc định là `get`.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.visit(url, { method: "post" });
  ```

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

  router.visit(url, { method: "post" });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.visit(url, { method: "post" });
  ```
</CodeGroup>

Laravel không hỗ trợ tải file qua `put` hoặc `patch`. Thay vào đó, hãy gửi request bằng `post`, kèm field `_method` đặt thành `put` hoặc `patch`. Kỹ thuật này gọi là [form method spoofing](https://laravel.com/docs/routing#form-method-spoofing).

## Wayfinder

Khi sử dụng [Wayfinder](https://github.com/laravel/wayfinder), bạn có thể truyền object kết quả trực tiếp vào bất kỳ phương thức router nào. Router sẽ tự suy ra HTTP method và URL từ object Wayfinder.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";
  import { show } from "App/Http/Controllers/UserController";

  router.visit(show(1));
  router.post(store());
  router.delete(destroy(1));
  ```

  ```js React icon="react" theme={null}
  import { router } from "@inertiajs/react";
  import { show } from "App/Http/Controllers/UserController";

  router.visit(show(1));
  router.post(store());
  router.delete(destroy(1));
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";
  import { show } from "App/Http/Controllers/UserController";

  router.visit(show(1));
  router.post(store());
  router.delete(destroy(1));
  ```
</CodeGroup>

Nếu bạn vừa truyền Wayfinder object vừa chỉ định tùy chọn `method`, tùy chọn `method` sẽ được ưu tiên.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";
  import { update } from "App/Http/Controllers/UserController";

  router.visit(update(1), { method: "patch" });
  ```

  ```js React icon="react" theme={null}
  import { router } from "@inertiajs/react";
  import { update } from "App/Http/Controllers/UserController";

  router.visit(update(1), { method: "patch" });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";
  import { update } from "App/Http/Controllers/UserController";

  router.visit(update(1), { method: "patch" });
  ```
</CodeGroup>

## Dữ liệu

Bạn có thể dùng tùy chọn `data` để thêm dữ liệu vào request.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.visit("/users", {
    method: "post",
    data: {
      name: "John Doe",
      email: "john.doe@example.com",
    },
  });
  ```

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

  router.visit("/users", {
    method: "post",
    data: {
      name: "John Doe",
      email: "john.doe@example.com",
    },
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.visit("/users", {
    method: "post",
    data: {
      name: "John Doe",
      email: "john.doe@example.com",
    },
  });
  ```
</CodeGroup>

Để thuận tiện, các phương thức `get()`, `post()`, `put()` và `patch()` đều nhận `data` làm đối số thứ hai.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.post("/users", {
    name: "John Doe",
    email: "john.doe@example.com",
  });
  ```

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

  router.post("/users", {
    name: "John Doe",
    email: "john.doe@example.com",
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.post("/users", {
    name: "John Doe",
    email: "john.doe@example.com",
  });
  ```
</CodeGroup>

## Header tùy chỉnh

Tùy chọn `headers` cho phép bạn thêm header tùy chỉnh vào request.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.post("/users", data, {
    headers: {
      "Custom-Header": "value",
    },
  });
  ```

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

  router.post("/users", data, {
    headers: {
      "Custom-Header": "value",
    },
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.post("/users", data, {
    headers: {
      "Custom-Header": "value",
    },
  });
  ```
</CodeGroup>

Các header mà Inertia sử dụng nội bộ để truyền trạng thái của nó tới máy chủ có độ ưu tiên cao hơn và vì vậy không thể bị ghi đè.

## Tùy chọn visit toàn cục

Bạn có thể cấu hình callback `visitOptions` khi [khởi tạo ứng dụng Inertia](/v3/installation/client-side-setup#configuring-defaults) để thay đổi visit option trên toàn cục cho mọi request. Callback nhận target URL và các visit option hiện tại, rồi nên trả object chứa những option cần override.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { createApp, h } from "vue";
  import { createInertiaApp } from "@inertiajs/vue3";

  createInertiaApp({
    // ...
    defaults: {
      visitOptions: (href, options) => {
        return {
          headers: {
            ...options.headers,
            "X-Custom-Header": "value",
          },
        };
      },
    },
  });
  ```

  ```jsx React icon="react" theme={null}
  import { createInertiaApp } from "@inertiajs/react";
  import { createRoot } from "react-dom/client";

  createInertiaApp({
    // ...
    defaults: {
      visitOptions: (href, options) => {
        return {
          headers: {
            ...options.headers,
            "X-Custom-Header": "value",
          },
        };
      },
    },
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { createInertiaApp } from "@inertiajs/svelte";

  createInertiaApp({
    // ...
    defaults: {
      visitOptions: (href, options) => {
        return {
          headers: {
            ...options.headers,
            "X-Custom-Header": "value",
          },
        };
      },
    },
  });
  ```
</CodeGroup>

## Tải file lên

Khi thực hiện lần truy cập / request có chứa file, Inertia sẽ tự động chuyển dữ liệu request thành object `FormData`. Nếu muốn request luôn dùng object `FormData`, bạn có thể sử dụng tùy chọn `forceFormData`.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.post("/companies", data, {
    forceFormData: true,
  });
  ```

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

  router.post("/companies", data, {
    forceFormData: true,
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.post("/companies", data, {
    forceFormData: true,
  });
  ```
</CodeGroup>

Để biết thêm về upload file, hãy xem tài liệu riêng về [file uploads](/v3/the-basics/file-uploads).

## Lịch sử trình duyệt

Khi thực hiện các lần truy cập, Inertia tự động thêm một entry mới vào lịch sử trình duyệt. Tuy nhiên, bạn cũng có thể thay thế entry lịch sử hiện tại bằng cách đặt tùy chọn `replace` thành `true`.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.get("/users", { search: "John" }, { replace: true });
  ```

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

  router.get("/users", { search: "John" }, { replace: true });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.get("/users", { search: "John" }, { replace: true });
  ```
</CodeGroup>

Các lần truy cập đến cùng một URL sẽ tự động đặt `replace` thành `true`.

## Client-side visits

Bạn có thể dùng `router.push` và `router.replace` để thực hiện client-side visit. Các phương thức này hữu ích khi muốn cập nhật history của trình duyệt mà không gửi request tới server.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.push({
    url: "/users",
    component: "Users",
    props: { search: "John" },
    clearHistory: false,
    encryptHistory: false,
    preserveScroll: false,
    preserveState: false,
    errorBag: null,
    onSuccess: (page) => {},
    onError: (errors) => {},
    onFinish: (visit) => {},
  });
  ```

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

  router.push({
    url: "/users",
    component: "Users",
    props: { search: "John" },
    clearHistory: false,
    encryptHistory: false,
    preserveScroll: false,
    preserveState: false,
    errorBag: null,
    onSuccess: (page) => {},
    onError: (errors) => {},
    onFinish: (visit) => {},
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.push({
    url: "/users",
    component: "Users",
    props: { search: "John" },
    clearHistory: false,
    encryptHistory: false,
    preserveScroll: false,
    preserveState: false,
    errorBag: null,
    onSuccess: (page) => {},
    onError: (errors) => {},
    onFinish: (visit) => {},
  });
  ```
</CodeGroup>

Tất cả tham số đều tùy chọn. Mặc định, mọi tham số được truyền vào (trừ `errorBag`) sẽ được merge với page hiện tại. Điều này có nghĩa bạn chịu trách nhiệm override URL, component và props của page hiện tại.

Nếu cần truy cập props của page hiện tại, bạn có thể truyền function vào tùy chọn `props`. Function nhận props hiện tại (bao gồm mọi [once props](/v3/data-props/once-props)) và nên trả về props mới.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.push({ url: "/users", component: "Users" });

  router.replace({
    props: (currentProps) => ({ ...currentProps, search: "John" }),
  });
  ```

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

  router.push({ url: "/users", component: "Users" });

  router.replace({
    props: (currentProps) => ({ ...currentProps, search: "John" }),
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.push({ url: "/users", component: "Users" });

  router.replace({
    props: (currentProps) => ({ ...currentProps, search: "John" }),
  });
  ```
</CodeGroup>

Function cũng nhận [once props](/v3/data-props/once-props) làm đối số thứ hai. Điều này hữu ích khi muốn thay toàn bộ regular props nhưng vẫn giữ once props.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.replace({
    props: (currentProps, onceProps) => ({ ...onceProps, search: "John" }),
  });
  ```

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

  router.replace({
    props: (currentProps, onceProps) => ({ ...onceProps, search: "John" }),
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.replace({
    props: (currentProps, onceProps) => ({ ...onceProps, search: "John" }),
  });
  ```
</CodeGroup>

Tùy chọn `errorBag` cho phép chỉ định error bag dùng khi xử lý lỗi validation trong callback `onError`.

Hãy đảm bảo mọi route bạn push ở phía client cũng được định nghĩa ở phía máy chủ. Nếu người dùng refresh trang, máy chủ cần biết cách render trang đó.

<Warning>
  Một số trình duyệt giới hạn số lần gọi `history.pushState()` và
  `history.replaceState()` trong khoảng thời gian ngắn. Inertia
  bắt lỗi này và ghi ra console, nhưng state update sẽ bị
  mất. Tránh gọi `router.push()` hoặc `router.replace()` quá thường xuyên và
  cân nhắc debounce hoặc batch update trong các trường hợp tần suất cao.
</Warning>

### Prop helper

Inertia cung cấp ba phương thức helper để cập nhật page props mà không gửi request đến máy chủ. Đây là các cách viết tắt của `router.replace()` và tự động đặt `preserveScroll` cùng `preserveState` thành `true`.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  // Replace a prop value...
  router.replaceProp("user.name", "Jane Smith");

  // Append to an array prop...
  router.appendToProp("messages", { id: 4, text: "New message" });

  // Prepend to an array prop...
  router.prependToProp("tags", "urgent");
  ```

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

  // Replace a prop value...
  router.replaceProp("user.name", "Jane Smith");

  // Append to an array prop...
  router.appendToProp("messages", { id: 4, text: "New message" });

  // Prepend to an array prop...
  router.prependToProp("tags", "urgent");
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  // Replace a prop value...
  router.replaceProp("user.name", "Jane Smith");

  // Append to an array prop...
  router.appendToProp("messages", { id: 4, text: "New message" });

  // Prepend to an array prop...
  router.prependToProp("tags", "urgent");
  ```
</CodeGroup>

Cả ba phương thức đều hỗ trợ dot notation cho prop lồng nhau và có thể nhận callback function, trong đó đối số đầu tiên là giá trị hiện tại và đối số thứ hai là props của trang hiện tại.

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

  router.prependToProp('notifications', (current, props) => {
      return {
          id: Date.now(),
          message: `Hello ${props.user.name}`,
      }
  })
  ```

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

  router.prependToProp('notifications', (current, props) => {
      return {
          id: Date.now(),
          message: `Hello ${props.user.name}`,
      }
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.prependToProp('notifications', (current, props) => {
      return {
          id: Date.now(),
          message: `Hello ${props.user.name}`,
      }
  })
  ```
</CodeGroup>

## Giữ lại state

Mặc định, các lần truy cập lại cùng một trang sẽ tạo một instance page component mới. Điều này khiến các state cục bộ như input của form, vị trí cuộn và trạng thái focus bị mất.

Tuy nhiên, trong một số tình huống, cần giữ lại state của page component. Ví dụ, khi submit form, bạn cần giữ dữ liệu form nếu validation form thất bại ở phía máy chủ.

Vì lý do này, các phương thức `post`, `put`, `patch`, `delete` và `reload` đều đặt tùy chọn `preserveState` thành `true` theo mặc định.

Bạn có thể yêu cầu Inertia giữ state của component khi sử dụng phương thức `get` bằng cách đặt tùy chọn `preserveState` thành `true`.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.get("/users", { search: "John" }, { preserveState: true });
  ```

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

  router.get("/users", { search: "John" }, { preserveState: true });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.get("/users", { search: "John" }, { preserveState: true });
  ```
</CodeGroup>

Nếu chỉ muốn giữ state khi response có chứa lỗi validation, hãy đặt tùy chọn `preserveState` thành "errors".

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.get("/users", { search: "John" }, { preserveState: "errors" });
  ```

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

  router.get("/users", { search: "John" }, { preserveState: "errors" });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.get("/users", { search: "John" }, { preserveState: "errors" });
  ```
</CodeGroup>

Bạn cũng có thể đánh giá trì hoãn tùy chọn `preserveState` dựa trên response bằng cách cung cấp một callback.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.post("/users", data, {
    preserveState: (page) => page.props.someProp === "value",
  });
  ```

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

  router.post("/users", data, {
    preserveState: (page) => page.props.someProp === "value",
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.post("/users", data, {
    preserveState: (page) => page.props.someProp === "value",
  });
  ```
</CodeGroup>

## Giữ vị trí cuộn

Khi điều hướng giữa các page, Inertia mô phỏng hành vi mặc định của trình duyệt bằng cách tự động reset vị trí cuộn của document body (cũng như các [scroll region](/v3/advanced/scroll-management#scroll-regions) đã định nghĩa) về đầu trang.

Bạn có thể tắt hành vi này bằng cách đặt tùy chọn `preserveScroll` thành `true`.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.visit(url, { preserveScroll: true });
  ```

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

  router.visit(url, { preserveScroll: true });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.visit(url, { preserveScroll: true });
  ```
</CodeGroup>

Nếu chỉ muốn giữ vị trí cuộn khi response có lỗi validation, hãy đặt tùy chọn `preserveScroll` thành "errors".

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.visit(url, { preserveScroll: "errors" });
  ```

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

  router.visit(url, { preserveScroll: "errors" });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.visit(url, { preserveScroll: "errors" });
  ```
</CodeGroup>

Bạn cũng có thể đánh giá trì hoãn tùy chọn `preserveScroll` dựa trên response bằng cách cung cấp một callback.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.post("/users", data, {
    preserveScroll: (page) => page.props.someProp === "value",
  });
  ```

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

  router.post("/users", data, {
    preserveScroll: (page) => page.props.someProp === "value",
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.post("/users", data, {
    preserveScroll: (page) => page.props.someProp === "value",
  });
  ```
</CodeGroup>

Để biết thêm về tính năng này, xem tài liệu [scroll management](/v3/advanced/scroll-management).

## Tải lại một phần

Tùy chọn `only` cho phép bạn chỉ yêu cầu một tập con props (dữ liệu) từ máy chủ trong các lần truy cập tiếp theo đến cùng một trang, qua đó giúp ứng dụng hiệu quả hơn vì không cần truy xuất dữ liệu mà trang không có nhu cầu làm mới.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.get("/users", { search: "John" }, { only: ["users"] });
  ```

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

  router.get("/users", { search: "John" }, { only: ["users"] });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.get("/users", { search: "John" }, { only: ["users"] });
  ```
</CodeGroup>

Để biết thêm về tính năng này, xem tài liệu [partial reloads](/v3/data-props/partial-reloads).

## View Transition

Bạn có thể bật [View transitions](/v3/the-basics/view-transitions) cho một visit bằng cách đặt tùy chọn `viewTransition` thành `true`. Cơ chế này dùng View Transitions API của trình duyệt để animate quá trình chuyển trang.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.visit("/another-page", { viewTransition: true });
  ```

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

  router.visit("/another-page", { viewTransition: true });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.visit("/another-page", { viewTransition: true });
  ```
</CodeGroup>

## Hủy lần truy cập

Bạn có thể hủy toàn bộ visit đang chạy bằng phương thức `router.cancelAll()`. Mặc định, thao tác này hủy mọi request đồng bộ, bất đồng bộ và prefetch.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  // Cancel all in-flight requests...
  router.cancelAll();
  ```

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

  // Cancel all in-flight requests...
  router.cancelAll();
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  // Cancel all in-flight requests...
  router.cancelAll();
  ```
</CodeGroup>

Bạn có thể hủy chọn lọc từng loại request bằng cách truyền options object.

```js theme={null}
// Cancel only async requests (leaving sync and prefetch active)...
router.cancelAll({ sync: false, prefetch: false });

// Cancel only sync requests...
router.cancelAll({ async: false, prefetch: false });

// Cancel everything except prefetch requests...
router.cancelAll({ prefetch: false });
```

### Cancel token

Để kiểm soát chi tiết hơn, bạn có thể hủy từng visit bằng cancel token. Inertia tự động tạo cancel token và cung cấp nó qua callback `onCancelToken()` trước khi thực hiện visit.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.post("/users", data, {
    onCancelToken: (cancelToken) => (this.cancelToken = cancelToken),
  });

  // Cancel the visit...
  this.cancelToken.cancel();
  ```

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

  router.post("/users", data, {
    onCancelToken: (cancelToken) => (this.cancelToken = cancelToken),
  });

  // Cancel the visit...
  this.cancelToken.cancel();
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.post("/users", data, {
    onCancelToken: (cancelToken) => (this.cancelToken = cancelToken),
  });

  // Cancel the visit...
  this.cancelToken.cancel();
  ```
</CodeGroup>

Các event callback `onCancel()` và `onFinish()` sẽ được thực thi khi visit bị hủy.

## Callback sự kiện

Ngoài [global events](/v3/advanced/events) của Inertia, Inertia còn cung cấp nhiều event callback theo từng visit.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.post("/users", data, {
    onBefore: (visit) => {},
    onStart: (visit) => {},
    onProgress: (progress) => {},
    onSuccess: (page) => {},
    onError: (errors) => {},
    onHttpException: (response) => {},
    onNetworkError: (error) => {},
    onCancel: () => {},
    onFinish: (visit) => {},
    onPrefetching: () => {},
    onPrefetched: () => {},
  });
  ```

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

  router.post("/users", data, {
    onBefore: (visit) => {},
    onStart: (visit) => {},
    onProgress: (progress) => {},
    onSuccess: (page) => {},
    onError: (errors) => {},
    onHttpException: (response) => {},
    onNetworkError: (error) => {},
    onCancel: () => {},
    onFinish: (visit) => {},
    onPrefetching: () => {},
    onPrefetched: () => {},
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.post("/users", data, {
    onBefore: (visit) => {},
    onStart: (visit) => {},
    onProgress: (progress) => {},
    onSuccess: (page) => {},
    onError: (errors) => {},
    onHttpException: (response) => {},
    onNetworkError: (error) => {},
    onCancel: () => {},
    onFinish: (visit) => {},
    onPrefetching: () => {},
    onPrefetched: () => {},
  });
  ```
</CodeGroup>

Trả `false` từ callback `onBefore()` sẽ hủy visit. Trả `false` từ `onHttpException()` hoặc `onNetworkError()` sẽ ngăn [global event](/v3/advanced/events) tương ứng được phát và ngăn hành vi mặc định của nó.

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

  router.delete(`/users/${user.id}`, {
      onBefore: () => confirm('Are you sure you want to delete this user?'),
  })
  ```

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

  router.delete(`/users/${user.id}`, {
      onBefore: () => confirm('Are you sure you want to delete this user?'),
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.delete(`/users/${user.id}`, {
      onBefore: () => confirm('Are you sure you want to delete this user?'),
  })
  ```
</CodeGroup>

Bạn cũng có thể trả về promise từ các callback `onSuccess()` và `onError()`. Khi làm vậy, sự kiện "finish" sẽ được trì hoãn cho đến khi promise được resolve.

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

  router.post(url, {
      onSuccess: () => {
          return Promise.all([
              this.firstTask(),
              this.secondTask()
          ])
      },
      onFinish: visit => {
          // Not called until firstTask() and secondTask() have finished
      },
  })
  ```

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

  router.post(url, {
      onSuccess: () => {
          return Promise.all([
              this.firstTask(),
              this.secondTask()
          ])
      },
      onFinish: visit => {
          // Not called until firstTask() and secondTask() have finished
      },
  })
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from '@inertiajs/svelte'

  router.post(url, {
      onSuccess: () => {
          return Promise.all([
              this.firstTask(),
              this.secondTask()
          ])
      },
      onFinish: visit => {
          // Not called until firstTask() and secondTask() have finished
      },
  })
  ```
</CodeGroup>

***

## 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/manual-visits). 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.
