TS làm được tay — chạy scan, inspect từng lỗi critical (đặc biệt H1 & alt), fix app-side/theme-side đúng cách có guardrail, và verify Phase 4 trước khi báo "fixed".
Panel Tools trong extension → chọn "♿ Accessibility — DFY Scan". Ô store tự điền từ conversation Crisp đang mở.
Bật Auto-discover pages từ sitemap.xml, đặt Số trang tối đa (mặc định 10), hoặc dán danh sách URL (mỗi dòng 1 URL) — có URL thì bỏ qua auto-discover.
Report HTML gộp: tổng quan (số trang, điểm tệ nhất, điểm trung bình, tổng lỗi) rồi từng trang — trang tệ nhất lên đầu, mỗi trang có điểm + verdict WCAG + lỗi nhóm theo severity.
Store khoá password:
Chỉ merchant tự tick. TS/CS không tick hộ. Chỉ dùng sau khi (a) khách đã fix ngoài app và TS verify storefront, hoặc (b) TS chạy manual test cùng khách và xác nhận không phải lỗi thật. Không dùng để làm đẹp điểm.
Trang không có H1, hoặc nhảy cấp (H2 → H4). Scanner chỉ báo jump đầu tiên tìm thấy → fix xong re-scan có thể lộ jump tiếp theo.
// Liệt kê heading theo thứ tự DOM
console.table([...document.querySelectorAll('h1,h2,h3,h4,h5,h6')]
.map(h => ({ level: h.tagName, text: h.textContent.trim().slice(0, 70) })));
// Đếm số H1 (phải = 1)
document.querySelectorAll('h1').length;
Đúng: đúng một H1, các cấp sau không nhảy quá 1 bậc (H1→H2→H3, không H2→H4). Nhanh hơn: dùng feature Page Structure trong widget.
Ảnh thiếu alt (screen reader không đọc được), hoặc empty-alt (logo/icon/banner bị đánh dấu trang trí sai).
// Ảnh thiếu alt hoặc alt rỗng
[...document.querySelectorAll('img')]
.filter(i => !i.hasAttribute('alt') || i.alt.trim() === '')
.map(i => i.currentSrc || i.src);
Alt AI sinh runtime, client-side, chỉ xuất hiện khi visitor bật Text-to-Speech trong widget. Không lưu ngược vào product data Shopify (app không có scope write_products). Điểm được cộng ngay khi bật toggle, trước khi thực sự có alt nào. Muốn alt trong data thật (SEO / tool 3rd-party) → phải nhập tay ở Admin.
Nút/link tương tác (thường icon-only: giỏ hàng, search, hamburger, social) không có tên → screen reader chỉ đọc "button".
[...document.querySelectorAll('a,button,input,select,textarea,[role="button"],[role="link"]')]
.filter(el => !el.getAttribute('aria-label') && !el.getAttribute('aria-labelledby')
&& !el.textContent.trim() && !el.title && !el.value && el.offsetParent !== null)
.map(el => el.outerHTML.slice(0, 120));
Thêm đúng một aria-label="..." bằng ngôn ngữ store (vd "Cart", "Search", "Open menu", "Facebook"). Tìm class trong sections/header.liquid, snippets/ qua Edit code. Duplicate theme trước.
Snippet mẫu:
Code đã viết xong nhưng chưa ship kèm extension — đừng hứa TS dùng được ngay. Khi ra mắt, nút "A11y Inspect" sẽ cho kiểm tra nhanh ngay trên tab storefront đang mở: 1 click → ra 3 danh sách (heading outline/H1, ảnh thiếu alt, phần tử thiếu accessible name) và highlight trực tiếp trên trang. Hiện tại vẫn dùng scan trong Tools panel + snippet console.
SEVERITY_SCORES = { critical: 10, moderate: 5, minor: 1 };
finalScore = Math.max(20, Math.min(100, 100 - totalScore));
lawsuitRisk = finalScore >= 90 ? 'Low' : 'High';
| Nhóm | Cơ chế | TS làm gì |
|---|---|---|
| ① AUTO solvedBySea | 1.4.11, 2.4.11, 2.5.8, 3.3.2 — app credit vô điều kiện | Không cần fix cho điểm |
| ② AI-credit | 1.1.1, 4.1.2, 4.1.3 — credit khi bật AI alt-text | Bật feature nếu đủ điều kiện, else fix thật |
| ③ Phải fix thật | Còn lại đang scan | TS vào theme/admin fix thật (guardrail) |
| Ưu tiên | WCAG | Điểm/lỗi | Vì sao |
|---|---|---|---|
| 🔴 1 | 1.3.1, 3.3.4, 3.3.8 | +10 | Critical, luôn phải fix thật |
| 🔴 2 | 1.1.1, 4.1.2 | +10 | Critical — bật AI thì credit, else fix thật |
| 🟡 3 | 2.4.2, 3.1.1, 3.2.1, 3.2.2, 4.1.3 | +1 | Minor, fix nhanh trong theme |
| ⚪ bỏ | 1.4.11, 2.4.11, 2.5.8, 3.3.2 | 0 | Auto-solved, không trừ điểm |
| ⚪ bỏ | 4.1.1 | 0 | Checker disabled, không scan |
| WCAG | Checker | Access | Fix |
|---|---|---|---|
| 1.3.1 | checkBasicAccessibility :250,263,290 | Pages / Themes | Đúng 1 H1, sửa cấp heading trong content/theme |
| 3.3.4 | checkErrorPrevention :1340 | Themes | Thêm bước review/confirm; N/A → markAsSolved |
| 3.3.8 | checkAccessibleAuthentication :1554 | Themes / Settings | Show-password toggle hoặc Customer Accounts OTP |
| 1.1.1 | checkBasicAccessibility :81,93,135 | App AI / Content | Bật AI alt-text (đủ điều kiện) hoặc nhập alt tay |
| 4.1.2 | checkNameRoleValue :651 | App AI / Themes | AI credit hoặc thêm aria-label đúng ngôn ngữ store |
| WCAG | Fix (theme, +1/lỗi) |
|---|---|
| 2.4.2 | <title>{{ page_title }} | {{ shop.name }}</title> |
| 3.1.1 | <html lang="{{ request.locale.iso_code }}"> |
| 3.2.1 | Chuyển logic khỏi focus sang click/submit handler |
| 3.2.2 | Thêm nút Submit/Go, bỏ auto-redirect khỏi onchange |
| 4.1.3 | Thêm role="status"/"alert" + aria-live (credit nếu AI ON) |
⚪ 1.4.11, 2.4.11, 2.5.8, 3.3.2 auto-solved; 4.1.1 checker disabled — bỏ khỏi checklist.
⚠️ Alt AI = runtime/Firestore, KHÔNG ghi product data (app không có scope write_products). Muốn alt trong data thật → nhập tay Admin.
POST /accessibility-scanner/reset-background-scan) khi scan kẹt; DOM Accessibility Scan để triage offline, không đụng store thật.