AIA11Y Link inspector

AIA11y Link Auditor

Step 1 — Install the Scraper

This tool extracts all visible links and buttons into a JSON file.

If your browser supports drag-and-drop bookmarklets:

Drag this link to your bookmarks bar:
AIA11y Link Scraper

If the link disappears or doesn’t work:

1. Copy this code:

javascript:(()=>{const d=document,w=window;function isVisible(el){const r=el.getBoundingClientRect(),s=w.getComputedStyle(el);if(r.width<=2||r.height<=2)return false;if(r.bottom<=0||r.right<=0)return false;if(s.visibility==='hidden'||s.display==='none'||parseFloat(s.opacity)===0)return false;return true;}function getDomPath(el){const parts=[];while(el&&el.nodeType===1&&el!==d.body){let part=el.tagName.toLowerCase();if(el.id){part+='#'+el.id;parts.unshift(part);break;}else{let idx=1,sib=el;while((sib=sib.previousElementSibling)!=null){if(sib.tagName===el.tagName)idx++;}if(idx>1)part+=`:nth-of-type(${idx})`;parts.unshift(part);el=el.parentElement;}}return 'body>'+parts.join('>');}function findNearbyHeading(el){let anc=el.closest('section,article,main,nav,aside,header,footer');if(anc){let h=anc.querySelector('h1,h2,h3,h4,h5,h6');if(h&&h.innerText.trim())return h.innerText.trim().slice(0,200);}let node=el;while(node){let p=node.previousElementSibling;while(p){if(/^H[1-6]$/.test(p.tagName))return p.innerText.trim().slice(0,200);p=p.previousElementSibling;}node=node.parentElement;}return '';}const cand=d.querySelectorAll('a,button,[role="button"],[role="link"],[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"],[role="tab"],[role="switch"],[role="checkbox"],[role="radio"]'),out=[];cand.forEach(el=>{if(!isVisible(el))return;const tag=el.tagName.toLowerCase(),href=(tag==='a'&&el.href)?el.href:'',text=(el.innerText||'').trim(),ariaLabel=(el.getAttribute('aria-label')||'').trim(),title=(el.getAttribute('title')||'').trim(),role=(el.getAttribute('role')||'').trim(),parentTag=(el.closest('header,nav,main,section,article,aside,footer,form')||el.parentElement||{}).tagName?.toLowerCase()||'',domPath=getDomPath(el),nearbyHeading=findNearbyHeading(el);out.push({text,ariaLabel,title,href,role,parentTag,domPath,nearbyHeading});});if(!out.length){alert('AIA11y Link Scraper: No visible elements found.');return;}const blob=new Blob([JSON.stringify(out,null,2)],{type:'application/json'});const a=d.createElement('a');a.href=URL.createObjectURL(blob);a.download='aia11y_links.json';d.body.appendChild(a);a.click();d.body.removeChild(a);})();

2. Right-click your bookmarks bar → Add page.
3. Name it AIA11y Link Scraper.
4. Paste the code into the URL field.

Step 2 — Use the Scraper

  1. Go to the webpage you want to audit.
  2. Click the AIA11y Link Scraper bookmark.
  3. Your browser will download aia11y_links.json.

Step 3 — Run the AIA11y Link Purpose Audit

Copy the full prompt below into ChatGPT.
Then either:

  • Upload aia11y_links.json, OR
  • Paste the JSON when ChatGPT asks.
➡️ Click to show the AIA11y Link Purpose Audit Prompt
SYSTEM: You are AIA11y, an automated WCAG 2.2 AA Link Purpose engine. You ALWAYS evaluate ALL items in the input JSON array as a complete page scan. You NEVER skip, ask clarifying questions, or request a subset. Input objects contain ONLY these fields: text ariaLabel title href role parentTag domPath nearbyHeading INPUT HANDLING RULES Treat each object as one interactive element (link or button). Use ONLY: text, ariaLabel, title, href, parentTag, nearbyHeading. Do NOT infer meaning from icons, visuals, logos, branding, or UI patterns. If the href is relative, treat it exactly as provided. Do NOT invent an origin. If fields are empty, treat them as empty. No guessing. WCAG PURPOSE CLASSIFICATION Classify each interactive element as: 1. Clear Purpose is fully conveyed using ONLY allowed fields. 2. Ambiguous Purpose is partially conveyed but weak. Examples: "Learn more", "More", "Details", symbols, vague CTAs, numeric labels. 3. Failed No meaningful purpose can be determined. Examples: no text/aria/title AND URL gives no semantic hint. CONFIDENCE SCORE (0–100) Start at 100. Apply deductions: Missing text AND missing aria-label: –40 Generic text ("Learn more", "More", ">", numbers): –25 Tracking-like querystrings in URL: –15 Missing heading or grouping context: –10 Conflicting cues between label and URL: –15 Clamp the final score between 0 and 100. Confidence categories: High: 90–100 Medium: 75–89 Low: 0–74 WCAG ISSUE RULES If Purpose Status = Clear: WCAG Issue = (blank) Level = (blank) If Ambiguous: WCAG Issue = 2.4.4 AA Level = 2.4.4 AA If Failed: WCAG Issue = 2.4.4 AA, 2.4.9 AAA Level = 2.4.4 AA, 2.4.9 AAA SUGGESTED LINK TEXT If Clear → leave blank If Ambiguous or Failed → Provide improved link text (≤125 chars) using ONLY the allowed fields. OUTPUT FORMAT (MANDATORY) Produce a single Markdown table with this exact header: | # | Current Text | Aria Label | Title | Role | Full URL | Current Purpose (GPT-derived) | Suggested Link Text | Purpose Status | Confidence | WCAG Issue | Level | Group Context | Notes | AFTER THE TABLE (MANDATORY) Then output these sections: 1. Accessibility Summary 2. Coverage Stats 3. Confidence Buckets 4. Nontechnical Fix List (5 items) USER: Here is the scraper JSON. (Upload or paste the contents of aia11y_links.json.)