Bỏ qua tới nội dung
Mục lục

React 18 và React 19

Cài @belvador/react cho ứng dụng React chạy trên trình duyệt (Vite, SPA), với cách nối riêng cho React 18 và React 19.

Bản Markdown
Trong bài này

Dùng @belvador/react cho ứng dụng React render trên trình duyệt — Vite, Create React App hoặc dạng SPA khác. Gói này có mọi thứ của @belvador/browser, cộng thêm error boundary và root hook của React 19. Ứng dụng Lovable và TanStack Start dùng TanStack Start.

Trước khi bắt đầu#

  • Một project có nền tảng React (Vite / SPA) và DSN của nó.

  • React 18 hoặc React 19. Kiểm tra bản đang dùng: npm ls react.

1. Cài đặt#

Terminal
npm install @belvador/react@0.6.1

2. Khởi tạo#

Tạo src/instrument.ts. File này khởi động Belvador:

src/instrument.ts
import { init } from "@belvador/react";init({  dsn: "https://<public-key>@ingest.belvador.dev/<project-id>",  release: import.meta.env.VITE_APP_VERSION, // your build or commit id  environment: import.meta.env.MODE,});

3. Import đầu tiên — React 18#

Đặt ./instrument là dòng import đầu tiên của src/main.tsx. Các import chạy trước phần còn lại của file, nên một lệnh init viết bên dưới import App sẽ không bao giờ chạy nếu một module của App lỗi lúc đang nạp — ví dụ thiếu biến môi trường. Trang trắng và không có lỗi nào được báo. Bản này chạy được với React 18 và 19. ErrorBoundary báo lỗi render (kèm component stack) và hiện nội dung thay thế thay vì trang trắng.

src/main.tsx
import "./instrument"; // first line: starts Belvador before App's modules loadimport { createRoot } from "react-dom/client";import { ErrorBoundary } from "@belvador/react";import App from "./App";const root = document.getElementById("root");if (!root) throw new Error("Root element missing");createRoot(root).render(  <ErrorBoundary fallback={<p>Something went wrong.</p>}>    <App />  </ErrorBoundary>,);

3. Import đầu tiên — React 19#

React 19 tự xử lý nhiều lỗi và không để chúng tới window.onerror. Truyền reactErrorHandler() vào ba tuỳ chọn của root để Belvador thấy các lỗi đó. Các tuỳ chọn này không có trong React 18 — ở React 18 dùng bản phía trên.

src/main.tsx
import "./instrument"; // first line: starts Belvador before App's modules loadimport { createRoot } from "react-dom/client";import { ErrorBoundary, reactErrorHandler } from "@belvador/react";import App from "./App";const root = document.getElementById("root");if (!root) throw new Error("Root element missing");createRoot(root, {  onUncaughtError: reactErrorHandler(),  onCaughtError: reactErrorHandler(),  onRecoverableError: reactErrorHandler(),}).render(  <ErrorBoundary fallback={<p>Something went wrong.</p>}>    <App />  </ErrorBoundary>,);
Tuỳ chọn của rootBáo lỗi gì
onUncaughtErrorLỗi không error boundary nào bắt
onCaughtErrorLỗi đã bị error boundary bắt và hiện nội dung thay thế
onRecoverableErrorLỗi React tự phục hồi được, ví dụ lệch dữ liệu khi hydrate

reactErrorHandler nhận một callback tuỳ chọn, chạy sau khi đã báo: reactErrorHandler((error, errorInfo, eventId) => { … }).

4. Cho phép địa chỉ nhận lỗi trong CSP#

Text
connect-src 'self' https://ingest.belvador.dev;

Gộp dòng này vào connect-src hiện có; đừng thay cả chính sách.

Error boundary cho từng phần của trang#

Bọc những phần dễ lỗi của giao diện để một widget hỏng không kéo sập cả trang:

TSX
import { ErrorBoundary, withErrorBoundary } from "@belvador/react";export function Dashboard() {  return (    <ErrorBoundary      fallback={({ resetError }) => (        <div role="alert">          <p>Biểu đồ này chưa tải được.</p>          <button onClick={resetError}>Thử lại</button>        </div>      )}    >      <RevenueChart />    </ErrorBoundary>  );}// Hoặc bọc một component một lần:export const SafeRevenueChart = withErrorBoundary(RevenueChart, {  fallback: <p>Biểu đồ này chưa tải được.</p>,});

ErrorBoundary báo mỗi lỗi render một lần và hiện fallback. Hộp thoại xin phản hồi người dùng mà một số SDK có thì không có ở đây: nó sẽ phải tải script từ mạng.

Báo những lỗi bạn đã xử lý#

Mọi thứ của @belvador/browser cũng được export ở đây:

TSX
import { captureException, setUser } from "@belvador/react";setUser({ id: user.id });try {  await importCsv(file);} catch (error) {  captureException(error);  setStatus("failed");}

Kiểm tra#

Thêm tạm một nút, bấm thử rồi mở project trong Belvador:

TSX
function Crash(): never {  throw new Error("Belvador React test");}export function TestButton() {  const [crash, setCrash] = useState(false);  return crash ? <Crash /> : <button onClick={() => setCrash(true)}>Gửi lỗi thử</button>;}

Issue hiện component stack trong mục Ngữ cảnh. Nhớ xoá nút sau khi thử.

Giới hạn cần biết#

  • Hàm xử lý sự kiện (onClick, …) và code bất đồng bộ không nằm trong phạm vi của error boundary — đây là quy tắc của React. Lỗi ở đó mà không ai bắt vẫn tới Belvador qua bộ bắt lỗi toàn cục; lỗi bạn tự bắt thì cần captureException.

  • Các framework render phía máy chủ khác ngoài TanStack Start không nằm trong phạm vi cài đặt của gói này.

Bài viết về chủ đề này

Tất cả bài viết

Thấy chỗ sai hoặc thiếu? Gửi cho chúng tôi: hello@belvador.dev