10 điều AI thường làm sai trong quá trình phát triển web

Ngày xuất bản: Ngày 11 tháng 11 năm 2026

Tuần này, chúng tôi đã phát hành phiên bản 1.0 của Modern Web Guidance, một bộ kỹ năng tích hợp kiến thức chuyên môn về nền tảng web, các phương pháp hay nhất và dữ liệu về khả năng tương thích của trình duyệt ngay vào các tác nhân lập trình của bạn. Mục tiêu của chúng tôi khi cung cấp Modern Web Guidance là giúp các nhà phát triển sử dụng tác nhân lập trình AI tận dụng tối đa sức mạnh và khả năng của nền tảng web hiện đại, từ đó cải thiện trải nghiệm web cho người dùng.

Kể từ khi chúng tôi ra mắt bản xem trước của Modern Web Guidance vào tháng 5, các tác nhân lập trình ngày càng trở nên hiệu quả hơn và nhiều mô hình tiên phong mới mẻ đã được phát hành. Một trong những câu hỏi chúng tôi thường nghe nhất là: các mô hình tiên phong mới này đã tuân theo các phương pháp hay nhất về phát triển web chưa?

Rất tiếc, câu trả lời là "không" – và chúng tôi biết câu trả lời là "không" vì chúng tôi đã thử nghiệm.

Mỗi hướng dẫn trong Modern Web Guidance đều xác định một bộ kỳ vọng phải đúng nếu các phương pháp hay nhất trong hướng dẫn được tuân thủ đúng cách. Sau đó, bộ đánh giá của chúng tôi sẽ kiểm thử các hướng dẫn đó bằng cách đưa ra cùng một câu lệnh cho một tác nhân chạy có cài đặt Modern Web Guidance (tác nhân có hướng dẫn) và một tác nhân khác chạy không cài đặt Modern Web Guidance (tác nhân không có hướng dẫn). Kết quả của cả hai lần chạy được kiểm tra dựa trên kết quả dự kiến được xác định trong hướng dẫn.

Khi so sánh tỷ lệ vượt qua có hướng dẫn và không có hướng dẫn, bạn có thể thấy rằng các mô hình AI (ngay cả những mô hình tiên phong mới nhất) không tự động tuân thủ các phương pháp hay nhất về phát triển web hiện đại một cách đáng tin cậy.

Trung bình, các tác nhân lập trình không được hướng dẫn chỉ vượt qua khoảng 50% số lượt kiểm tra trong bộ đánh giá của chúng tôi, so với khoảng 90% khi sử dụng Modern Web Guidance.

Biểu đồ thanh ngang so sánh tỷ lệ vượt qua bài kiểm tra đánh giá trung bình của các tác nhân lập trình tiên tiến (tính đến ngày 9 tháng 11 năm 2026): 52% khi không có Modern Web Guidance so với 91% khi có Modern Web Guidance.

Bạn có thể xem trang tổng quan về việc đánh giá để biết danh sách đầy đủ các bước kiểm tra cụ thể mà chúng tôi thực hiện cho từng hướng dẫn, cũng như điểm số của từng mô hình trong các bước kiểm tra đó.

Tuy nhiên, để có cái nhìn tổng quan, bài đăng này đề cập đến 10 vấn đề mà chúng tôi thấy các mô hình AI thường xuyên mắc phải, trong các lĩnh vực chính mà nhà phát triển web có nhiều khả năng gặp phải nhất trong công việc hằng ngày, chẳng hạn như khả năng hỗ trợ tiếp cận, trải nghiệm người dùng, hiệu suất và bảo mật.

1. Hỗ trợ tiếp cận: Tiêu điểm bàn phím và quản lý inert

Đối với những người thao tác bằng bàn phím hoặc trình đọc màn hình, thứ tự lấy tiêu điểm có thể dự đoán được là yếu tố giúp giao diện người dùng tương tác trở nên hữu dụng. Nếu không có thuộc tính này, tiêu điểm có thể chuyển sang nội dung nền bị ẩn hoặc bị kẹt trong hàng chục điểm dừng thẻ bổ sung.

Quản lý tiêu điểm và inert là một trong những lỗ hổng lớn nhất về khả năng hỗ trợ tiếp cận trong các bản đánh giá của chúng tôi, đồng thời là một trong những khía cạnh được cải thiện nhiều nhất nhờ Modern Web Guidance. Sau đây là các lỗi phổ biến nhất:

  • Không di chuyển tiêu điểm vào các chế độ xem mới mở và quên khôi phục tiêu điểm về phần tử kích hoạt khi quay lại.
  • Dựa vào bẫy thẻ JavaScript thủ công và aria-modal="true" trên các phương thức tuỳ chỉnh, thay vì sử dụng phương thức <dialog> hoặc đánh dấu nội dung nền inert.
  • Hiển thị mọi mục trong thanh công cụ hoặc lưới định hướng dưới dạng một điểm dừng thẻ riêng biệt thay vì sử dụng một điểm dừng thẻ duy nhất có tabindex chuyển vùng.
  • Tạo đường viền :focus-visible tuỳ chỉnh không có tỷ lệ tương phản 3:1 so với nền liền kề.

2. Hỗ trợ tiếp cận: Hỗ trợ giảm chuyển động

Sự di chuyển trang không mong muốn và ảnh động quy mô lớn không chỉ gây mất tập trung mà còn có thể gây chóng mặt, buồn nôn hoặc đau đầu cho người dùng bị rối loạn tiền đình hoặc nhạy cảm với chuyển động.

Các mô hình AI thường nhớ kiểm tra prefers-reduced-motion khi thêm hiệu ứng chuyển đổi CSS chuẩn hoặc ảnh động khung hình chính. Tuy nhiên, khi sử dụng các tính năng mới hơn như cuộn mượt mà, chuyển đổi khung hiển thị hoặc ảnh động dựa trên thao tác cuộn, họ thường quên giảm chuyển động hoặc mắc lỗi khi triển khai:

  • Đặt scroll-behavior:smooth trên toàn cầu và vô điều kiện trên phần tử gốc.
  • Sử dụng ảnh động CSS dựa trên thao tác cuộn mà không cần kiểm tra chế độ giảm chuyển động.
  • Xoá thời lượng transition trên các mục trong băng chuyền để giảm chuyển động trong khi cuộn, nhưng sau đó quên xoá các thuộc tính biến đổi, khiến các mục bị thay đổi kích thước đột ngột trong khi cuộn.
  • Áp dụng chế độ đặt lại thời lượng 0.01ms chung cho *, *::before và *::after khi chế độ giảm chuyển động đang hoạt động, đồng thời xoá tất cả các hiệu ứng chuyển đổi không chuyển động cần thiết (cần thiết để thông báo các thay đổi về trạng thái giao diện người dùng).
  • Bật hiệu ứng chuyển đổi khung hiển thị trên nhiều tài liệu một cách vô điều kiện và ghi đè ảnh động ::view-transition-* khi chế độ giảm chuyển động đang hoạt động, thay vì chỉ áp dụng quy tắc @view-transition sau khi kiểm tra chế độ giảm chuyển động.

3. Hỗ trợ tiếp cận: Xác thực biểu mẫu, gợi ý định dạng và trạng thái tự động điền

Biểu mẫu là nền tảng của hầu hết các hành trình trọng yếu của người dùng trên web. Một trở ngại nhỏ trong biểu mẫu thanh toán có thể ảnh hưởng lớn đến lợi nhuận của doanh nghiệp.

Khi tạo biểu mẫu, các mô hình AI sẽ thực hiện đúng nhiều thông tin cơ bản. Tuy nhiên, các biểu mẫu này thường không xử lý được những chi tiết nhỏ nhưng quan trọng, chẳng hạn như lỗi xác thực, vị trí thích hợp của phần giữ chỗ và gợi ý định dạng, cũng như việc tích hợp đúng cách với trình quản lý mật khẩu và tính năng tự động điền:

  • Triển khai lại quy trình xác thực :user-invalid CSS bằng JavaScript blur tuỳ chỉnh, thường gắn cờ các trường required chưa được chỉnh sửa ngay khi người dùng chuyển qua các trường đó.
  • Để aria-invalid không đồng bộ hoá với các lỗi hiển thị, đặt aria-invalid="true" sớm trên blur hoặc tạo kiểu :user-invalid trong CSS mà không đồng bộ hoá aria-invalid trong JavaScript.
  • Dựa vào văn bản placeholder biến mất để hiển thị các định dạng bắt buộc (chẳng hạn như MM/YY trên dữ liệu đầu vào ngày hết hạn của thẻ) thay vì hiển thị gợi ý cố định được liên kết với aria-describedby.
  • Đặt gợi ý về định dạng và quy tắc mật khẩu bên dưới <input> (thay vì bên trên) nơi chúng có thể bị bàn phím di động và cửa sổ bật lên tự động điền che khuất ngay khi người dùng cần đọc chúng.
  • Làm nổi bật các mục nhập :autofill bằng cách chỉ thay đổi màu đường viền thay vì kết hợp màu với một dấu hiệu không màu không làm thay đổi bố cục (chẳng hạn như box-shadow lồng ghép).

4. Trải nghiệm người dùng: Cử chỉ vuốt và chạm

Tác nhân có thể triển khai các cử chỉ chạm bằng JavaScript mệnh lệnh và viết logic vật lý tuỳ chỉnh của riêng mình. Những cách triển khai này có hiệu quả; tuy nhiên, các hoạt động tương tác bằng thao tác chạm dựa trên JavaScript hiếm khi mượt mà như người dùng mong đợi từ các ứng dụng gốc.

Nhiều hoạt động tương tác trong số này có thể được triển khai bằng CSS và API cuộn gốc, cho phép trình duyệt chạy hiệu ứng vật lý của cử chỉ ngoài luồng chính. Tuy nhiên, trong các bài đánh giá của chúng tôi, các mô hình AI thường bỏ qua những tính năng sau:

  • Triển khai cử chỉ vuốt để đóng hoặc vuốt để hiện bằng trình nghe pointermove hoặc touchmove thay vì sử dụng tính năng Cố định vị trí cuộn CSS.
  • Bỏ qua overscroll-behavior-x:none trên giao diện vuốt thẻ, điều này có thể vô tình kích hoạt thao tác quay lại hoặc chuyển tiếp của trình duyệt trong khi vuốt quá mức.
  • Thúc đẩy hiệu ứng tiến trình vuốt trên luồng chính trong lệnh gọi lại JavaScript thay vì sử dụng ảnh động dựa trên thao tác cuộn.
  • Không hỗ trợ đúng cách tiêu điểm bàn phím trên các bảng thao tác vuốt dựa trên thao tác cuộn.

5. Trải nghiệm người dùng: Hộp thoại, cửa sổ bật lên và hiệu ứng chuyển đổi lớp trên cùng

Trong các bản đánh giá của chúng tôi, các mô hình thường quay lại các giải pháp thay thế JavaScript bắt buộc khi tạo ảnh động, đóng hoặc chứa thao tác cuộn xung quanh hộp thoại và cửa sổ bật lên.

Thay vì dựa vào các tính năng HTML và CSS hiện đại được xây dựng cho lớp phủ lớp trên cùng, các tác nhân thường tự tạo máy trạng thái vào và ra, trình kích hoạt nhật ký và khoá cuộn nội dung. Những tính năng này khó duy trì hơn và dễ gặp lỗi giao diện người dùng nhỏ.

Khi bạn thực hiện đúng các hoạt động tương tác này, trải nghiệm có vẻ không ổn định có thể trở thành một trải nghiệm chỉn chu mà người dùng tin tưởng. Sau đây là những lỗi phổ biến nhất mà chúng tôi thấy:

  • Tạo lớp phủ position:fixed tuỳ chỉnh bằng trình xử lý nhấp chuột bên ngoài theo cách thủ công để đóng nhanh, thay vì chỉ sử dụng popover.
  • Tạo ảnh động vào và ra bằng cách bật/tắt các lớp chuyển đổi CSS và phối hợp với trình nghe requestAnimationFrame() và transitionend (với phương án dự phòng setTimeout()), thay vì thực hiện bằng CSS thuần tuý với @starting-style và transition-behavior.
  • Khoá thao tác cuộn trang phía sau một phương thức đang mở bằng cách đặt overflow:hidden trên <html> thay vì sử dụng phần tử <dialog> để chứa thao tác cuộn quá mức.
  • Thêm trình nghe popstate để phát hiện cử chỉ quay lại của Android và đóng các phương thức đang mở, thay vì sử dụng chức năng đóng nút quay lại gốc của phần tử <dialog> phương thức.

6. Trải nghiệm người dùng: Chế độ tối và các chế độ điều khiển thích ứng với giao diện

Người dùng bật chế độ tối để giảm mỏi mắt và loá mắt, vì vậy, một tia sáng trắng khi tải trang, các chế độ điều khiển biểu mẫu không có giao diện hoặc nút bật/tắt không đồng bộ với lựa chọn ưu tiên của hệ điều hành sẽ ngay lập tức làm giảm trải nghiệm.

Nút bật/tắt chế độ tối có vẻ đơn giản, nhưng các mô hình không được hướng dẫn trong bản đánh giá của chúng tôi liên tục bỏ lỡ các chi tiết chính của nền tảng cần thiết để chuyển đổi giao diện và kiểm soát biểu mẫu gốc một cách chính xác:

  • Thiếu <meta name="color-scheme" content="light dark"> trong <head>, khiến người dùng chế độ tối thấy một khung vẽ màu trắng nhấp nháy trong khi biểu định kiểu bên ngoài tải.
  • Tạo kiểu cho giao diện tối hoặc các thành phần có nền tối bằng màu sắc tuỳ chỉnh mà không đặt color-scheme, khiến thanh cuộn gốc và các thành phần điều khiển biểu mẫu bị kẹt ở chế độ sáng.
  • Bỏ qua hàm CSS light-dark() khi xác định mã thông báo màu thích ứng với giao diện tự động tuân theo color-scheme đang hoạt động.
  • Chỉ cung cấp nút bật/tắt nhị phân sáng hoặc tối để đặt chế độ ghi đè rõ ràng trong localStorage mà không có lựa chọn quay lại chế độ mặc định của hệ điều hành.
  • Quên thêm trình nghe sự kiện storage, khiến các thẻ đang mở khác không đồng bộ hoá khi người dùng thay đổi giao diện.

7. Hiệu suất: Khả năng phản hồi và độ mượt mà trong thời gian chạy

Người dùng dành phần lớn thời gian trên một trang web sau khi trang tải xong, vì vậy, các hoạt động tương tác chậm chạp và chuyển đổi giật cục có thể gây ảnh hưởng xấu đến trải nghiệm người dùng, tương tự như khi trang tải chậm ban đầu.

Trong các bản đánh giá của chúng tôi, các mô hình thường tuân theo các phương pháp hay nhất về thời gian tải cổ điển đã được quảng bá trong các công cụ như Lighthouse trong nhiều năm và thường biết cách giảm tải các vòng lặp nặng rõ ràng cho một Web Worker. Họ thường gặp khó khăn trong việc cải thiện khả năng phản hồi của luồng chính, một yếu tố thiết yếu để tối ưu hoá INP: tách biệt công việc bố cục, lên lịch cho các tác vụ theo mức độ ưu tiên và tận dụng các tính năng HTML và CSS mới để thực hiện công việc kết xuất ngoài luồng chính.

Ví dụ: chúng tôi thường thấy các nhân viên hỗ trợ:

  • Triển khai hàng đợi setTimeout() tuỳ chỉnh cho công việc trong nền hoặc công việc có mức độ ưu tiên thấp thay vì ưu tiên các tác vụ mà người dùng có thể nhìn thấy bằng scheduler.postTask() hoặc tận dụng tính năng tiếp tục tác vụ bằng scheduler.yield() khi trình duyệt hỗ trợ.
  • Xây dựng bố cục phức tạp (như lưới dữ liệu dày đặc) mà không áp dụng content-visibility:auto và contain-intrinsic-size, tức là các bản cập nhật sau khi người dùng tương tác sẽ kích hoạt quá trình dàn lại toàn bộ trang.
  • Ẩn các chế độ xem SPA không hoạt động bằng display:none (hoặc loại bỏ chúng) thay vì sử dụng content-visibility:hidden (kết hợp với inert). Cách trước sẽ huỷ trạng thái kết xuất được lưu vào bộ nhớ đệm, nên việc chuyển về sẽ kích hoạt bố cục và hiển thị đầy đủ.
  • Tạm dừng ảnh động <canvas> ngoài màn hình và vòng lặp nền bằng lệnh gọi lại Intersection Observer thay vì ghép nối content-visibility:auto với sự kiện contentvisibilityautostatechange (nếu có), bỏ lỡ lề kết xuất trước của trình duyệt trước khi các phần tử cuộn vào khung hiển thị.
  • Tạo gợi ý giao diện người dùng về khả năng cuộn bằng cách sử dụng trình nghe sự kiện scroll buộc phải tính toán bố cục liên tục, thay vì sử dụng truy vấn trạng thái cuộn CSS khi có sẵn (với các phương án dự phòng Intersection Observer).

8. Hiệu suất: Thay đổi bố cục và nhấp nháy hình ảnh

Sự thay đổi bố cục ngoài dự kiến làm mất tập trung của người đọc và có thể khiến người dùng nhấp vào các nút không mong muốn, đôi khi gây ra hậu quả không thể khắc phục!

Các mô hình có thể thêm thuộc tính width và height vào các phần tử <img> chuẩn một cách đáng tin cậy để ngăn chặn sự thay đổi bố cục, nhưng chúng thường bỏ qua các nguồn gây ra sự thay đổi bố cục và hiện tượng nhấp nháy trước khi hiển thị từ các phần tử <video>, việc hoán đổi phông chữ web, thanh công cụ của trình duyệt di động và các thử nghiệm phía máy khách – tất cả đều có thể ảnh hưởng đến CLS.

  • Bỏ qua các thuộc tính width và height rõ ràng trên các phần tử <video> (để trình phát chưa tải mặc định thành 300×150 và thay đổi bố cục sau khi siêu dữ liệu tải) hoặc tạo kiểu cho các phần tử trình bao bọc nội dung nghe nhìn thay vì đặt aspect-ratio và object-fit trực tiếp trên các phần tử nội dung nghe nhìn.
  • Ghép nối phông chữ web với phông chữ dự phòng của hệ thống mà không có font-size-adjust, khiến các đoạn văn và tiêu đề hiển thị lại rõ ràng khi phông chữ web được hoán đổi.
  • Định cỡ phần chính và bố cục toàn màn hình bằng đơn vị vh tĩnh thay vì đơn vị khung nhìn động hoặc nhỏ (dvh, svh), khiến nội dung bị nhảy khi thanh công cụ của trình duyệt di động mở rộng và thu lại.
  • Ẩn nội dung bằng đoạn mã chống nhấp nháy opacity:0 hoặc visibility:hidden cũ và thời gian chờ nhiều giây cho các thử nghiệm A/B phía máy khách (trì hoãn LCP và khiến các phần tử không hiển thị có thể nhấp được), thay vì sử dụng tập lệnh có blocking="render" khi có sẵn.
  • Kích hoạt hiệu ứng chuyển đổi khung hiển thị giữa các tài liệu trước khi mã đánh dấu quan trọng trong màn hình đầu tiên được phân tích cú pháp thay vì giữ lại lần kết xuất đầu tiên bằng rel="expect" và blocking="render", khiến các phần tử được phân tích cú pháp một nửa xuất hiện giữa quá trình chuyển đổi.

9. Bảo mật: Biện pháp phòng vệ DOM XSS và dọn dẹp HTML

Một lỗ hổng tập lệnh chéo trang (XSS) duy nhất cho phép kẻ tấn công chạy mã tuỳ ý trong trình duyệt của người dùng, đánh cắp dữ liệu phiên hoặc thực hiện hành động thay mặt họ. Đây là lý do tại sao các biện pháp phòng vệ do trình duyệt thực thi như dọn dẹp HTML an toàn, Loại đáng tin cậy và CSP nghiêm ngặt lại quan trọng đến vậy.

Các mô hình hiếm khi chủ động giải quyết những mối lo ngại về bảo mật này. Ví dụ: trong tất cả các nhiệm vụ trong bộ đánh giá đầy đủ của chúng tôi, các mô hình không thêm Chính sách bảo mật nội dung (CSP) hoặc tiêu đề tách biệt nhiều nguồn gốc nếu không có câu lệnh rõ ràng.

Ngay cả khi câu lệnh yêu cầu bảo mật trực tiếp, các mô hình không được hướng dẫn vẫn tiếp tục không vượt qua được hơn một nửa số lần kiểm tra bảo mật của chúng tôi, dẫn đến các phương án dự phòng tuỳ chỉnh không ổn định hoặc chính sách không đầy đủ. Điều này thể hiện rõ khi phòng vệ trước DOM XSS:

  • Viết trình dọn dẹp danh sách cho phép DOMParser tự tạo (dưới dạng phương án dự phòng setHTML() hoặc bên trong chính sách Trusted Types) thay vì sử dụng thư viện đã được kiểm tra như DOMPurify khi không có tính năng dọn dẹp gốc.
  • Gói DOMPurify một cách nhanh chóng trên mỗi lượt tải trang thay vì sử dụng setHTML() gốc khi được hỗ trợ và chỉ tải chậm DOMPurify làm phương án dự phòng.
  • Đăng ký các chính sách Kiểu tin cậy truyền qua (input) => input cho phép làm suy yếu việc thực thi bồn lưu trữ.
  • Kết hợp Trusted Types trên các trang tĩnh với CSP script-src 'self' trong danh sách cho phép của máy chủ lưu trữ thay vì khoá tập lệnh cùng dòng bằng hàm băm SHA-256.
  • Bỏ qua 'strict-dynamic' và 'report-sample' khi định cấu hình Chính sách bảo mật nội dung script-src dựa trên số chỉ dùng một lần.

10. Bảo mật: Đăng nhập bằng khoá truy cập, xác thực lại và vòng đời thông tin xác thực

Khoá truy cập giúp cải thiện khả năng bảo mật cho người dùng và tỷ lệ chuyển đổi đăng nhập cho doanh nghiệp, nhưng việc triển khai khoá truy cập (ngay cả khi có sự trợ giúp của tác nhân) là một thách thức.

WebAuthn có các API tuần tự hoá, phát hiện chức năng và báo hiệu cụ thể mà các mô hình không được hướng dẫn gần như hoàn toàn bỏ lỡ trong các bản đánh giá của chúng tôi. Nếu bạn yêu cầu một mô hình AI thêm tính năng đăng nhập, quản lý hoặc xác thực lại bằng khoá truy cập, thì mô hình đó thường viết các trình trợ giúp mã hoá byte thủ công, bỏ qua các bước kiểm tra chức năng trên giao diện người dùng quản lý hoặc không đồng bộ hoá thông tin đăng nhập với trình quản lý mật khẩu:

  • Tự viết các trình trợ giúp chuyển đổi Base64URL atob() và btoa() (dưới dạng đường dẫn chính hoặc mã nguyên mẫu dự phòng thừa) thay vì dựa vào các phương thức chuyển đổi tuần tự tích hợp sẵn như parseCreationOptionsFromJSON(), parseRequestOptionsFromJSON() và credential.toJSON().
  • Bỏ qua PublicKeyCredential.signalUnknownCredential() trong quá trình đăng nhập khi máy chủ báo cáo mã thông tin xác thực không xác định, để lại khoá truy cập đã xoá hoặc bị thu hồi trong trình quản lý mật khẩu của người dùng.
  • Bỏ qua PublicKeyCredential.getClientCapabilities() trước khi hiển thị giao diện người dùng để tạo và quản lý khoá truy cập.
  • Bỏ qua AbortController và AbortSignal khi bắt đầu yêu cầu xác thực lại bằng khoá truy cập nâng cao.
  • Truyền tuỳ chọn mediation:"immediate" của bản dùng thử theo nguyên gốc thay vì uiMode:"immediate" cho lời nhắc đăng nhập được đơn giản hoá.

Thu hẹp những khoảng cách này

10 lĩnh vực này chưa phải là danh sách đầy đủ và chúng tôi dự kiến những lỗ hổng kiến thức cụ thể sẽ thay đổi theo thời gian. Các mô hình sẽ bắt kịp và nền tảng web sẽ tiếp tục phát triển.

Tin vui là Modern Web Guidance giải quyết được tất cả những thiếu sót này và sẽ tiếp tục phát triển cùng với nền tảng.

Để bắt đầu sử dụng Modern Web Guidance, hãy chạy lệnh sau hoặc tìm kiếm trong thị trường trình bổ trợ của tác nhân:

npx modern-web-guidance@latest install

Bạn có thấy các mô hình làm sai những nhiệm vụ phát triển web khác không? Chúng tôi muốn nghe về điều đó. Mở một vấn đề trong kho lưu trữ GitHub của Modern Web Guidance hoặc giúp chúng tôi thu hẹp những khoảng trống đó cho các nhà phát triển khác bằng cách đóng góp cho dự án.