Version: 1.0.0
Effective Date: 2026-08-02
Developer: Ngoc-Tien Nguyen (Nguyễn Ngọc Tiến)
Contact: tiennn.ict@gmail.com
QReact reads QR codes from images and creates QR codes from text, links, and pages. Everything it does runs inside your browser, on your own device.
QReact collects nothing. There is no server, no account, no analytics, no telemetry, no crash reporting, and no third-party service of any kind. The extension makes no network requests at all — it works with your device fully disconnected from the internet.
This document explains exactly what the extension touches anyway, because "we don't collect anything" is only meaningful if you can see what it does have access to.
| What | When | What happens to it |
|---|---|---|
| An image you give it | When you paste (Ctrl+V), drag and drop, or pick a file in the Read tab | Decoded in memory. Never uploaded, never written to disk. |
| A screenshot of the visible part of the current tab | When you choose "Read QR code on screen", or "Read QR code in this image" — see section 4 | Held in memory only, decoded, then discarded when the operation ends. |
The position and size of one <img> element |
Only when you choose "Read QR code in this image" | Four numbers, used to crop the screenshot. Discarded immediately. |
| The address of the current tab | Only when you click "Create QR code for this page" | Turned into a QR image shown in the popup. Not stored. |
| A link address, selected text, or an image address | Only when you click the matching right-click menu item | Handed to the extension by the browser, encoded into a QR image. Not stored. |
The extension has no way to read the content of any web page. It does not declare a content script and it holds no permission for any website.
createImageBitmap() and OffscreenCanvas — browser features that run entirely locally.The extension does not:
Two features take a screenshot of the visible part of the tab you are on. A screenshot captures everything currently visible in that tab, not just the QR code — including anything else on screen at that moment.
"Read QR code on screen" (right-click menu item and popup button) captures the visible area of the current tab and searches all of it for QR codes. This exists because some QR codes are not images at all — they are drawn on a canvas, rendered as SVG, or shown inside a video, and there is no image file to read.
"Read QR code in this image" also takes a screenshot, but then crops it down to the rectangle of the image you right-clicked (plus 8 pixels of margin on each side) and decodes only that crop. If the image's rectangle cannot be measured — the image sits inside an <iframe>, or the page will not allow the measuring function to run — the extension falls back to decoding the whole visible area instead.
In every case:
Two storage areas, both local to your browser. Neither is ever synced to any account or server.
storage.local (persists until you remove the extension)| Key | What it holds |
|---|---|
language | "en" or "vi" — the interface language you picked |
ecLevel | "L", "M", "Q", or "H" — an error-correction level, written only if you changed it yourself |
imageSize | A number — the output image size, written only if you typed one |
That is the complete list. No QR content, no history, no URLs, no identifiers of any kind are kept here.
storage.session (cleared when you close the browser)When you pick something from the right-click menu, the extension opens its popup — a fresh page that cannot receive arguments directly. So the background writes one temporary record, pendingAction, which the popup then reads. Depending on the menu item, that record holds either the content to encode (a link, selected text, an image address) or the text decoded from a QR code.
This record is:
storage.session, which the browser itself clears when you close it.QReact requests exactly four permissions and no host permissions at all.
| Permission | Why it is needed |
|---|---|
contextMenus |
To add the "QR Reader & Creator" entry to your right-click menu. |
activeTab |
To read the address of the tab you are on when you ask for a QR code of that page, and to capture the visible area of that tab when you ask it to read a code from the screen. It grants temporary access to the one tab you are actively using, only at the moment you invoke the extension. |
storage |
To remember the three settings in section 5, and to pass the temporary handoff record from the right-click menu to the popup. |
scripting |
To run one small function in the page when you choose "Read QR code in this image". That function receives only the image's address and returns only four numbers — the image's position and size. It does not read page text, page markup beyond the list of images, cookies, or storage. |
QReact does not request host_permissions and does not declare a static content script. Both of those require a match pattern, which is what produces the "Read and change all your data on all websites" warning. Neither activeTab nor scripting produces any permission warning at install time.
The obvious way to read a QR code from a web image would be to download it with fetch(imageUrl). QReact deliberately does not do that: it would be a network request, it would require access to every website, and it would break the one promise this extension is built around. Measuring the image and cropping the screenshot gives the same result without contacting anything.
The single technical exception, for the sake of completeness: the extension reads its own language files (locales/en.json, locales/vi.json) through a chrome-extension:// address. That reads a file inside the installed package on your own disk; no host is contacted.
Some results give you an action button. Pressing one opens a new tab, and from that point on it is your browser making the request, exactly as if you had typed the address yourself. Nothing opens automatically, and nothing is sent unless you press the button.
| Button | Where it goes | Who receives what |
|---|---|---|
| Open link | The http or https address inside the QR code |
That website receives a normal visit from your browser |
| Open in Maps | https://www.google.com/maps/search/?api=1&query=… |
Google receives the coordinates from the QR code |
| Find on Zalo (Vietnamese numbers, Vietnamese interface) | https://zalo.me/<number> |
Zalo receives the phone number from the QR code |
| Send email | A mailto: address |
Handed to whichever mail application or web mail handler you have configured |
| Call | A tel: number |
Handed to whichever calling application you have configured |
QReact always shows the full decoded content before you act on it — links are never shortened, never hidden behind a label, and never opened for you. You see exactly where a link leads before deciding.
QReact does not check links against any URL-reputation service, because sending your links to a third party would break the core promise of this extension. Your browser already has that protection built in: Chrome and Edge use Safe Browsing and SmartScreen, Firefox uses Safe Browsing, and they warn you when a newly opened tab leads somewhere dangerous.
Two buttons create a file, and both build it in memory and hand it to your browser's normal download flow:
qreact-qr.png.contact.vcf.Both land in your normal downloads folder and are yours entirely. The extension does not read them back and does not keep a copy.
None of the above requires you to take our word for it. The extension ships as readable source — not bundled, not minified — so the code running on your machine is the code you can inspect.
The quickest check needs no code reading at all:
chrome://extensions → Inspect views: popup), and switch to the Network tab.To read the code: in Chrome or Edge, enable Developer mode on chrome://extensions, note the extension ID, and open the matching folder in your browser profile's Extensions directory. In Firefox, rename the downloaded .xpi file to .zip and unpack it.
If a future version of QReact changes what it accesses, this policy will be updated before that version is published, and the version number and effective date at the top of this page will change with it.
Questions about this policy: tiennn.ict@gmail.com
QReact đọc mã QR từ ảnh và tạo mã QR từ văn bản, liên kết, hoặc trang web. Mọi việc extension làm đều chạy bên trong trình duyệt, ngay trên máy bạn.
QReact không thu thập bất cứ thứ gì. Không có máy chủ, không có tài khoản, không có analytics, không có telemetry, không có báo lỗi tự động, không có dịch vụ bên thứ ba nào. Extension không thực hiện một request mạng nào cả — ngắt mạng hoàn toàn thì nó vẫn chạy đủ mọi chức năng.
Dù vậy, tài liệu này vẫn nói rõ extension chạm tới những gì, bởi vì câu "chúng tôi không thu thập gì" chỉ có nghĩa khi bạn nhìn thấy được nó có quyền chạm tới những gì.
| Cái gì | Khi nào | Nó đi đâu |
|---|---|---|
| Ảnh bạn đưa vào | Khi bạn dán (Ctrl+V), kéo thả, hoặc chọn tệp ở tab Đọc mã QR | Giải mã trong bộ nhớ. Không tải lên đâu cả, không ghi ra đĩa. |
| Ảnh chụp vùng đang nhìn thấy của tab hiện tại | Khi bạn chọn "Đọc mã QR trên màn hình", hoặc "Đọc mã QR trong ảnh" — xem mục 4 | Chỉ nằm trong bộ nhớ, giải mã xong là bỏ. |
Vị trí và kích thước của đúng một thẻ <img> |
Chỉ khi bạn chọn "Đọc mã QR trong ảnh" | Bốn con số, dùng để cắt ảnh chụp. Bỏ đi ngay sau đó. |
| Địa chỉ của tab hiện tại | Chỉ khi bạn bấm "Tạo mã QR cho trang này" | Biến thành ảnh QR hiện trong popup. Không lưu lại. |
| Địa chỉ liên kết, văn bản đã bôi đen, hoặc địa chỉ ảnh | Chỉ khi bạn bấm đúng mục menu chuột phải tương ứng | Trình duyệt đưa cho extension, mã hoá thành ảnh QR. Không lưu lại. |
Extension không có cách nào đọc nội dung của bất kỳ trang web nào. Nó không khai content script và không giữ quyền truy cập website nào.
createImageBitmap() và OffscreenCanvas — tính năng có sẵn của trình duyệt, chạy hoàn toàn cục bộ.Extension không:
Hai chức năng có chụp ảnh vùng đang nhìn thấy của tab bạn đang mở. Ảnh chụp lấy toàn bộ những gì đang hiện ra trong tab đó, không riêng mã QR — kể cả mọi thứ khác đang có trên màn hình lúc ấy.
"Đọc mã QR trên màn hình" (mục menu chuột phải và nút trong popup) chụp vùng đang nhìn thấy của tab hiện tại rồi tìm mã QR trên toàn bộ vùng đó. Chức năng này tồn tại vì có những mã QR không phải là ảnh — chúng được vẽ bằng canvas, dựng bằng SVG, hoặc nằm trong video, không có tệp ảnh nào để đọc cả.
"Đọc mã QR trong ảnh" cũng chụp màn hình, nhưng sau đó cắt xuống đúng khung của tấm ảnh bạn vừa right-click (cộng thêm 8 pixel đệm mỗi cạnh) và chỉ giải mã phần đã cắt. Nếu không đo được khung của ảnh — ảnh nằm trong <iframe>, hoặc trang không cho phép chạy hàm đo — extension quay về giải mã cả vùng đang nhìn thấy.
Trong mọi trường hợp:
Hai vùng lưu trữ, cả hai đều nằm cục bộ trong trình duyệt. Không vùng nào được đồng bộ lên tài khoản hay máy chủ nào.
storage.local (giữ cho tới khi bạn gỡ extension)| Khoá | Chứa gì |
|---|---|
language | "en" hoặc "vi" — ngôn ngữ giao diện bạn chọn |
ecLevel | "L", "M", "Q", hoặc "H" — mức sửa lỗi, chỉ được ghi nếu chính bạn đổi nó |
imageSize | Một con số — kích thước ảnh xuất ra, chỉ được ghi nếu bạn tự gõ vào |
Đó là toàn bộ danh sách. Không có nội dung QR nào, không lịch sử, không URL, không mã định danh nào được giữ ở đây.
storage.session (tự xoá khi bạn đóng trình duyệt)Khi bạn chọn một mục trong menu chuột phải, extension bật popup lên — mà popup là một trang mới toanh, không nhận được tham số trực tiếp. Vì vậy phần chạy nền ghi một bản ghi tạm tên pendingAction để popup đọc. Tuỳ theo mục menu, bản ghi đó chứa hoặc nội dung cần mã hoá (một liên kết, đoạn văn bản đã bôi đen, một địa chỉ ảnh), hoặc văn bản vừa giải mã được từ mã QR.
Bản ghi này:
storage.session, vùng mà chính trình duyệt xoá sạch khi bạn đóng nó.QReact xin đúng bốn quyền, và không xin quyền truy cập host nào cả.
| Quyền | Vì sao cần |
|---|---|
contextMenus |
Để thêm mục "Đọc và tạo mã QR" vào menu chuột phải của bạn. |
activeTab |
Để đọc địa chỉ tab bạn đang mở khi bạn yêu cầu tạo mã QR cho trang đó, và để chụp vùng đang nhìn thấy của tab đó khi bạn yêu cầu đọc mã QR trên màn hình. Quyền này chỉ cho phép truy cập tạm thời đúng một tab bạn đang dùng, đúng lúc bạn gọi extension. |
storage |
Để nhớ ba tuỳ chọn ở mục 5, và để chuyển bản ghi tạm từ menu chuột phải sang popup. |
scripting |
Để chạy một hàm nhỏ trong trang khi bạn chọn "Đọc mã QR trong ảnh". Hàm đó nhận vào duy nhất địa chỉ của ảnh và trả ra duy nhất bốn con số — vị trí và kích thước của ảnh. Nó không đọc văn bản trang, không đọc DOM ngoài danh sách ảnh, không đọc cookie hay storage. |
QReact không xin host_permissions và không khai content script tĩnh. Cả hai thứ đó đều đòi match pattern, mà match pattern chính là cái sinh ra cảnh báo "Đọc và thay đổi dữ liệu của bạn trên mọi trang web". Cả activeTab lẫn scripting đều không sinh cảnh báo quyền nào lúc cài.
Cách hiển nhiên nhất để đọc mã QR trong một ảnh trên web là tải ảnh đó về bằng fetch(imageUrl). QReact cố tình không làm vậy: đó là một request ra mạng, nó đòi quyền truy cập mọi website, và nó phá vỡ đúng lời cam kết mà extension này được dựng lên để giữ. Đo khung ảnh rồi cắt ảnh chụp cho ra cùng kết quả mà không phải liên hệ với bất cứ đâu.
Một ngoại lệ kỹ thuật duy nhất, nói ra cho đủ: extension đọc chính file ngôn ngữ của nó (locales/en.json, locales/vi.json) qua địa chỉ chrome-extension://. Đó là đọc một tệp nằm trong gói đã cài trên ổ đĩa của bạn; không có host nào được liên hệ.
Một số kết quả có kèm nút hành động. Bấm vào là mở một tab mới, và từ lúc đó trở đi chính trình duyệt của bạn gửi request, y như khi bạn tự gõ địa chỉ vào. Không có gì tự động mở, và không có gì được gửi đi trừ khi bạn bấm nút.
| Nút | Dẫn tới đâu | Ai nhận được gì |
|---|---|---|
| Mở liên kết | Địa chỉ http hoặc https nằm trong mã QR |
Website đó nhận một lượt truy cập bình thường từ trình duyệt của bạn |
| Mở bản đồ | https://www.google.com/maps/search/?api=1&query=… |
Google nhận được toạ độ lấy từ mã QR |
| Tìm Zalo (số Việt Nam, giao diện tiếng Việt) | https://zalo.me/<số> |
Zalo nhận được số điện thoại lấy từ mã QR |
| Gửi email | Một địa chỉ mailto: |
Giao cho ứng dụng email hoặc web mail mà bạn đã đặt làm mặc định |
| Gọi | Một số tel: |
Giao cho ứng dụng gọi điện mà bạn đã đặt làm mặc định |
QReact luôn hiện đầy đủ nội dung đã giải mã trước khi bạn hành động — liên kết không bị rút gọn, không bị giấu sau một cái nhãn, và không bao giờ được mở giùm bạn. Bạn nhìn thấy chính xác liên kết dẫn tới đâu rồi mới quyết định.
QReact không kiểm tra liên kết qua dịch vụ đánh giá URL nào, bởi gửi liên kết của bạn cho bên thứ ba là phá vỡ đúng cam kết cốt lõi của extension này. Trình duyệt của bạn đã có sẵn lớp bảo vệ đó: Chrome và Edge dùng Safe Browsing và SmartScreen, Firefox dùng Safe Browsing, và chúng sẽ cảnh báo khi tab vừa mở dẫn tới nơi nguy hiểm.
Có hai nút tạo ra tệp, cả hai đều dựng tệp trong bộ nhớ rồi giao cho luồng tải xuống bình thường của trình duyệt:
qreact-qr.png.contact.vcf.Cả hai nằm trong thư mục tải xuống thường lệ của bạn và hoàn toàn thuộc về bạn. Extension không đọc lại chúng và không giữ bản sao nào.
Bạn không cần phải tin lời chúng tôi về bất cứ điều nào ở trên. Extension được phát hành ở dạng mã nguồn đọc được — không bundle, không minify — nên code đang chạy trên máy bạn đúng là code bạn xem được.
Cách kiểm tra nhanh nhất, không cần đọc dòng code nào:
chrome://extensions → Inspect views: popup), sang tab Network.Muốn đọc code: với Chrome hoặc Edge, bật Developer mode ở chrome://extensions, xem ID của extension, rồi mở thư mục tương ứng trong thư mục Extensions của hồ sơ trình duyệt. Với Firefox, đổi đuôi tệp .xpi đã tải thành .zip rồi giải nén.
Nếu một phiên bản QReact về sau thay đổi những gì nó chạm tới, chính sách này sẽ được cập nhật trước khi phiên bản đó được phát hành, và số phiên bản cùng ngày hiệu lực ở đầu trang sẽ đổi theo.
Thắc mắc về chính sách này: tiennn.ict@gmail.com