Types of links you can test on this page
Choose a link type below to find examples, see how they behave and test how your tool handles them.
How to test these links and compare results
Run your link checker on this page, or use individual examples in your browser automation tests. Wait at least three seconds before scanning so the dynamically added link is included.
Each section explains the example links and includes a results table. What the server does describes the response or failure associated with each example. Predicted in LinkScan describes its predicted classification, not a verified result. Other tools may classify the same link differently.
Some links deliberately return errors, trigger certificate warnings or fail to connect. External websites may change their behaviour over time.
For automated comparisons, the example URLs, server behaviour and
LinkScan predictions are also available as JSON at
/example/expected.json.
LinkScan predictions and test details
Predictions apply to LinkScan – Broken Link Checker 2.1.0 and are based on the implemented classifier and page-relative rules (FR56–62, reviewed 2026-10-12), not an extension run. These predictions have not yet been verified with the selected release build. Measured results will appear alongside them when available. “Needs verification” marks cases that require a measured scan to confirm. Older versions may report different results.
Use the Scan page for this page's results. Its filters are All, Broken, Redirects, A11Y, Unknown and OK; A11Y means link accessibility issues. “Not listed” means LinkScan skips the example. Predictions are not scan totals.
This is fixture version 7. Two examples are unavailable: a 999 status code, because the server accepts only statuses 200–599, and an HTTP-only page, because this site's hosting upgrades requests to HTTPS.
Test environment to be recorded
- Browser
- Chrome (exact version and OS to be filled on release day), new profile, no other extensions
- Extension
- LinkScan – Broken Link Checker 2.1.0, selected release build (to be filled on release day)
- Page
- https://linkscan.app/example/, fixture version 7, website commit to be filled on release day
- Run
- Wait at least 3 s after load. On the Scan page choose Scan All Links, then Re-scan to force fresh checks for this page. If an unscanned-page card shows Check Page Links, use that action instead. Record whole-page scope and cache state; do not substitute a selected-links run.
- Date and time
- to be filled on release day (UTC)
- Network
- to be filled on release day (ISP and country, no VPN or proxy, IPv4 or IPv6)
- Server
- Fixture behaviour checked with curl on the same day
- Raw output
- On the Scan page set the filter to All and copy the page-scoped table. Record known-issue state and capture every result group, OK included; document skipped cases separately because they have no result row.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Breadcrumb Home C-breadcrumb-home | / | 200 | OK | Same address as the §1 HTTPS link, so it is one more location on that row. |
| Jump to Section (16 links) C-jump-nav | #protocol-scheme … #edge-cases | Not requested | Not listed | Existing or exempt same-page target: no finding and no request. |
| Navbar logo C-navbar-home | / | 200 | OK | Same address as the §1 HTTPS link, so it is one more location on that row. |
| Navbar menu (desktop and mobile copies) C-navbar-menu | /example/, /guides/, /privacy-policy/, /contact/ | 200 | OK | Extra locations on the §5, §3 and §2 rows; /guides/ is a row of its own, shared with the footer. The mobile menu copy is hidden on wide screens but still counted. |
| Navbar install button (Add to Chrome) C-navbar-install | https://chromewebstore.google.com/detail/broken-links-scanner/jcfgjohakfnckffjncgfmoldibhbmofm | 200 (to curl) | OK needs verification | The Chrome Web Store listing, a third-party site; it may answer the extension differently than curl. One button serves wide and narrow screens. |
| Footer links C-footer | /example/, /guides/, /contact/, /about/, /privacy-policy/, https://koval.dev | 200 | OK | Extra locations on the §5, §2, §3 and §3 external rows, and on the /guides/ row. /about/ is a new URL row in fixture version 6; predicted 200 OK, pending a selected-release run. |
| Buy Me a Coffee support link C-support-widget | https://www.buymeacoffee.com/kovaldev | Third-party page; response must be measured | OK (subject to third-party response) needs verification | A plain link; no widget script is loaded. |
1. Protocol & Scheme Variations
Compare HTTPS, HTTP and special links that open apps or files instead of web pages.
- HTTPS link — The normal case: a secure, complete address. Nothing to fix.
- HTTP link — Insecure. Browsers upgrade it or warn the visitor. Use https://.
- WWW HTTPS link — A different host than the bare domain, so it costs an extra redirect. Link to the canonical host.
- Protocol-relative — Inherits the page's scheme. A legacy pattern; write https:// explicitly.
- Scheme-less link — Missing https://, so the browser treats it as a path under the current page and it breaks. Add the scheme.
- FTP Link — Browsers no longer open FTP. Serve the file over HTTPS.
- File system link — Points at the visitor's own disk, so it never works for anyone else. Remove it.
- Data URI — Inline data that is invalid here, and browsers block opening data: links. Link to a real file.
- Custom scheme (SMS) — Opens an app, not a page, so the scanner skips it. Make sure the number is right.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| HTTPS link S1-https | https://linkscan.app/ | 200 | OK | One row for this address: also //linkscan.app, the §7 image link, both §11 links, the navbar logo and the breadcrumb Home link (one extra location in fixture version 5). |
| HTTP link S1-http | http://linkscan.app/ | 301 → https://linkscan.app/; HSTS, so Chrome upgrades it before asking | Redirect: Use https instead needs verification | The final scheme is checked even when Chrome upgrades before a visible hop. |
| WWW HTTPS link S1-www | https://www.linkscan.app | 301 → https://linkscan.app/ | OK → https://linkscan.app/ (1 hop) | One hop is reported as OK with the final address, not as a redirect problem. |
| Protocol-relative S1-protocol-relative | //linkscan.app | 200 | OK | Resolves to https://linkscan.app/, the S1-https row. |
| Scheme-less link S1-scheme-less | linkscan.app/about | 404 (resolves to /example/linkscan.app/about) | Broken: 404 Page not found | Without https:// the address is a path under this page. |
| FTP Link S1-ftp | ftp://files.linkscan.app/file.zip | Not requested | Not listed | Not an http(s) link: skipped without a row. |
| File system link S1-file | file:///C:/secret.txt | Not requested | Not listed | Not an http(s) link: skipped without a row. |
| Data URI S1-data | data:image/png;base64,INVALIDDATA | Not requested | Not listed | Not an http(s) link: skipped without a row. |
| Custom scheme (SMS) S1-sms | sms:+123456789 | Not requested | Not listed | Not an http(s) link: skipped without a row. |
2. Absolute vs. Relative Paths
See how full URLs and relative paths point to different destinations.
- Absolute link — A full address that resolves the same from any page.
- Root-relative — Resolves from the site root. Safe when pages move.
- Path-relative — Depends on where the page sits, so it breaks when the page moves. Prefer root-relative.
- Dot-relative — Resolves inside the current folder (here /example/contact/), which does not exist. Prefer root-relative.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Absolute link S2-absolute | https://linkscan.app/contact/ | 200 | OK | One row with the root-relative and ../ links, §9 Working Page and the navbar and footer links. |
| Root-relative S2-root-relative | /contact/ | 200 | OK | Same row as S2-absolute. |
| Path-relative S2-path-relative | ../contact/ | 200 | OK | Resolves to /contact/ from /example/, so it shares the S2-absolute row. |
| Dot-relative S2-dot-relative | ./contact/ | 404 (resolves to /example/contact/) | Broken: 404 Page not found |
3. Internal vs. External Links
Test links within this site, across subdomains and to other websites.
- Internal link — A page on this site, under your control.
- Cross-subdomain — A separate host that may not exist or may be down. Check it like an external link.
- External site — Outside your control and can disappear any time. Re-check external links regularly.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Internal link S3-internal | /privacy-policy/ | 200 | OK | One row with the two §4 links to this page, §9 200 OK, §10 Proper ARIA and the navbar and footer links. |
| Cross-subdomain S3-cross-subdomain | https://blog.linkscan.app | No DNS record, no answer | Broken: Can't connect | The failed HEAD is retried once with GET, which fails the same way. |
| External site S3-external | https://koval.dev | 200 (to curl) | OK needs verification | A third-party site; it may answer the extension differently than curl. Also the footer link. |
4. Anchor Fragments
Compare working and missing jump targets on this page and another page.
- Working anchor — Jumps to an element with that id on this page.
- Broken anchor — No element has this id, so the click does nothing. Fix the id or remove the link.
- Bare hash — Jumps to the top of the page; usually a placeholder or a script hook. Use a button for actions.
- Absolute self anchor — Same page written with its full path. Works, but a plain #anchors is simpler.
- Anchor to a name attribute — Targets a legacy name attribute. Use an id instead.
- Other page anchor — The page is checked; the fragment on it is not.
- Other page, missing anchor — The page loads, but the jump target is missing, so the visitor lands at the top.
Dead same-page targets are checked in the DOM without a request. A fragment on another page is checked as that page without the fragment, so the last two links share one result.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Working anchor S4-working-anchor | #anchors | Not requested | Not listed | Existing or exempt same-page target: no finding and no request. |
| Broken anchor S4-broken-anchor | #does-not-exist | Not requested; no matching DOM target | Broken: This anchor points nowhere | Checked against id and a[name] in the page DOM. |
| Bare hash S4-bare-hash | # | Not requested | Not listed | Existing or exempt same-page target: no finding and no request. |
| Absolute self anchor S4-absolute-self-anchor | /example/#anchors | Not requested | Not listed | Existing or exempt same-page target: no finding and no request. |
| Anchor to a name attribute S4-name-anchor | #legacy-target | Not requested | Not listed | Existing or exempt same-page target: no finding and no request. |
| Other page anchor S4-other-page-anchor | /privacy-policy/#top | 200 | OK | The fragment is removed before checking, so this is a location on the S3-internal row. |
| Other page, missing anchor S4-other-page-missing-anchor | /privacy-policy/#does-not-exist | 200 | OK | Same row as S3-internal. The missing jump target is not detected. |
| Jump target <a name> (no href, no text) S4-name-target | no href | Not requested | Not listed | A jump target, not a link: ignored. |
5. Cyclic & Self Links
Try a link that reloads this page and an anchor that jumps to the top.
- Self-link — Points to the page you are on and just reloads it. Remove it, or mark it with aria-current="page".
- Top anchor — Browsers jump to the top of the page for #top even when no element has id="top".
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Self-link S5-self | /example/ | 200 | OK | Also the Testing Lab links in the navbar and footer. |
| Top anchor S5-top | #top | Not requested | Not listed | Existing or exempt same-page target: no finding and no request. |
6. Mail & Telephone
Compare complete and incomplete email addresses and telephone numbers. These links open apps rather than web pages.
- Valid mail — Opens the mail app with an address and subject. The scanner skips it.
- Invalid mail — No address, so it opens an empty draft. Add the address.
- Valid tel — International format that dials correctly on phones.
- Malformed tel — Letters can't be dialed. Use digits with a country code, like +14165551234.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Valid mail S6-mail-valid | mailto:info@linkscan.app?subject=Hello | Not requested | Not listed | Not an http(s) link: skipped without a row. |
| Invalid mail S6-mail-empty | mailto: | Not requested | Not listed | Not an http(s) link: skipped without a row. |
| Valid tel S6-tel-valid | tel:+14165551234 | Not requested | Not listed | Not an http(s) link: skipped without a row. |
| Malformed tel S6-tel-malformed | tel:123-ABC | Not requested | Not listed | Not an http(s) link: skipped without a row. |
7. Image & Media Links
A visible image can link to a working page or a missing one. Test the destination, not just whether the image loads.
-
— Image link that works. Its name comes from the image's alt text.
-
— Broken link in image. The image shows fine, but the target returns 404, which is easy to miss.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Image link that works S7-image-ok | https://linkscan.app/ | 200 | OK | A location on the S1-https row. |
| Broken link in image S7-image-404 | https://linkscan.app/404error | 404 | Broken: 404 Page not found | The link text comes from the image's alt: "Test Image". |
8. JavaScript-driven Links
This example uses JavaScript instead of a page URL. Check how your tool handles an action without a destination.
- JS Link — Not a real destination: fails without JavaScript and with middle-click. Use a button for actions.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| JS Link S8-javascript | javascript:void(0) | Not requested | Not listed | Not an http(s) link: skipped without a row. |
9. HTTP Status Code Playground
Test successful responses, missing pages, access errors and slow replies. Some examples respond differently to HEAD and GET requests.
- 200 OK — The page loads. Nothing to fix.
- Working Page — Another healthy page.
- 404 Error — The page doesn't exist. Fix the address or add a redirect.
- 401 Unauthorized — Needs a login. Fine for members-only pages, broken for the public.
- 403 Forbidden — Access refused. Often a bot block or wrong permissions; open it in a browser to confirm.
- 410 Gone — Removed on purpose. Remove the link.
- 429 Too Many Requests — Rate-limited. Not necessarily broken; check again later.
- 500 Internal Server Error — The server failed. Check again; report it to the site owner if it persists.
- 502 Bad Gateway — A proxy got no valid answer from the server behind it. Usually temporary.
- 503 Service Unavailable — The server is down or in maintenance. Check again later.
- HEAD answers 405, GET answers 200 — The server refuses quick HEAD checks; the scanner retries with GET. Not broken.
- HEAD answers 404, GET answers 200 — The server answers HEAD checks wrongly, but the page works.
- Slow response (15 seconds) — Visitors may give up before it loads. Look at server performance.
Compare the recognised bot challenge with the plain 403 above, the login redirect with a direct login link, and the six-second success with the fast control and timeout. Live bot-header access and selected-request timing still need verification.
- 504 Gateway Timeout — Unlike 503, a 504 is counted as broken.
- HEAD blocked by a bot rule — HEAD 403 is retried with GET.
- HEAD not implemented — HEAD 501 is retried with GET.
- Works when clicked, blocked for scanners — FR56: requires the extension to read cf-mitigated: challenge. Confirm header access in the selected build.
- Rate limit with Retry-After — 429 with Retry-After: 30, every method
- Down for maintenance — 503 with Retry-After: 120, every method
- Login-gated page — FR56 recognises the login path reached from a different path.
- Slow but under the timeout — FR57: successful responses at or above 3000 ms are advisory; timeout stays Unknown.
- Direct login destination — An intentionally linked login path is not a login-redirect finding. Compare R-login-gate and the plain S9-403.
- Fast successful response — Negative slow-response control. Network conditions can make even this route slow. Timing covers the selected request to headers, not page rendering.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| 200 OK S9-200 | /privacy-policy/ | 200 | OK | A location on the S3-internal row. |
| Working Page S9-working-page | /contact/ | 200 | OK | A location on the S2-absolute row. |
| 404 Error S9-404 | /non-existent-page/ | 404 | Broken: 404 Page not found | HEAD 404 is retried with GET, which also answers 404. |
| 401 Unauthorized S9-401 | /test/status/401 | 401 to every method | Unknown: Needs login — open it signed in to check | 401 is not retried with GET. |
| 403 Forbidden S9-403 | /test/status/403 | 403 to every method | Broken: 403 Access denied | HEAD 403 is retried with GET, which also answers 403. |
| 410 Gone S9-410 | /test/status/410 | 410 to every method | Broken: 410 Page not found | |
| 429 Too Many Requests S9-429 | /test/status/429 | 429 to every method | Unknown: Rate-limited, try again later | Not counted as broken. |
| 500 Internal Server Error S9-500 | /test/status/500 | 500 to every method | Broken: 500 Server error | |
| 502 Bad Gateway S9-502 | /test/status/502 | 502 to every method | Broken: 502 Server error | |
| 503 Service Unavailable S9-503 | /test/status/503 | 503 to every method | Unknown: Temporarily unavailable | Not counted as broken. |
| HEAD 405, GET 200 S9-head-405 | /test/head-405 | HEAD → 405, GET → 200 | OK | The server refuses HEAD with 405 but answers GET with 200. LinkScan is predicted to retry with GET. |
| HEAD 404, GET 200 S9-head-404 | /test/head-404 | HEAD → 404, GET → 200 | OK | The server returns 404 for HEAD but answers GET with 200. LinkScan is predicted to retry with GET. |
| Slow response (15 seconds) S9-slow | /test/slow | 200 after about 15 s | Unknown: No response within 10 seconds | The 10 s timeout is not retried. |
| 504 Gateway Timeout R-504 | /test/status/504 | 504 to every method | Broken: 504 Server error | Unlike 503, a 504 is counted as broken. |
| HEAD blocked by a bot rule R-head-403 | /test/head-403 | HEAD → 403, GET → 200 | OK | HEAD 403 is retried with GET. |
| HEAD not implemented R-head-501 | /test/head-501 | HEAD → 501, GET → 200 | OK | HEAD 501 is retried with GET. |
| Works when clicked, blocked for scanners R-bot-wall | /test/bot-wall | 403 (cf-mitigated: challenge) unless Sec-Fetch-Mode is navigate; a click gets 200 | Unknown: Could not check — site blocked the request needs verification | A browser visit gets 200, while an automated request gets a bot challenge. The predicted classification depends on access to the challenge header. |
| Rate limit with Retry-After R-rate-limit | /test/rate-limit | 429 with Retry-After: 30, every method | Unknown: Rate-limited, try again later | |
| Down for maintenance R-maintenance | /test/maintenance | 503 with Retry-After: 120, every method | Unknown: Temporarily unavailable | |
| Login-gated page R-login-gate | /test/login-gate | 302 → /test/login?next=/test/login-gate → 200 | Unknown: Needs login — open it signed in to check | The URL redirects to a login page. LinkScan is predicted to identify the login requirement from the destination path. |
| Slow but under the timeout R-slow-ok | /test/slow-ok | 200 after 6 s | Redirect: Slow response | Headers arrive after six seconds. LinkScan is predicted to flag a successful selected request taking at least three seconds; this is not page-load time. Timeouts remain Unknown. |
| Direct login destination S9-direct-login | /test/login | 200 without a redirect | OK | An intentionally linked login path is not a login-redirect finding. Compare R-login-gate and the plain S9-403. |
| Fast successful response S9-fast | /test/ok/fast | 200 without an intentional delay | OK (if selected request takes less than 3 s) needs verification | Negative slow-response control. Network conditions can make even this route slow. Timing covers the selected request to headers, not page rendering. |
10. Accessibility Attributes
Test links with missing destinations, empty names and vague text. Compare what is visible on the page with the name available to screen readers.
- Proper ARIA — The label names the destination. Good.
- Empty link — No text and no label, so screen readers just say "link". Add text or an aria-label.
- No href — Not a link at all and not keyboard-focusable. Add an href, or use a button.
- Empty href — Reloads the current page. Point it at a real destination.
- Whitespace href — Same as an empty href.
- Click here — Means nothing out of context. Describe the destination instead.
- READ more — Generic text. Say what there is to read.
- here — The label helps screen readers, but sighted visitors still see "here". Make the visible text descriptive.
- Label-only link — Has a name for screen readers, so LinkScan reports it as OK, but there is nothing visible to click. Add visible text.
- Privacy policy details — Named by other text on the page through aria-labelledby, so LinkScan reports it as OK. Valid, but the link itself has nothing visible to click.
-
Image with empty alt — The link has no name at all. Give the image alt text that names the destination.
- Click here to send the developer a message — LinkScan flags only link text that is exactly a vague phrase, so this reports as OK. The text works, but it starts with filler. Lead with the destination.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Proper ARIA S10-proper-aria | /privacy-policy/ | 200 | OK | A location on the S3-internal row. |
| Empty link S10-empty-link | /test/ok/empty-link | 200 | Accessibility: Empty link text | |
| No href S10-no-href | no href | Not requested | Accessibility: Missing destination | Gets its own row; nothing is requested. |
| Empty href S10-empty-href | "" | Not requested | Accessibility: Missing destination | Its own row, not merged with the S5-self row. |
| Whitespace href S10-whitespace-href | " " | Not requested | Accessibility: Missing destination | Its own row, like S10-empty-href. |
| Click here S10-click-here | /test/ok/click-here | 200 | Accessibility: Vague link text | |
| READ more S10-read-more | /test/ok/read-more | 200 | Accessibility: Vague link text | Case and surrounding spaces are ignored. |
| here (with aria-label) S10-here | /test/ok/here | 200 | Accessibility: Vague link text | Flagged on the visible text despite the aria-label. |
| Label-only link S10-label-only | /test/ok/label-only | 200 | OK | Its aria-label gives it an accessible name, so it is not flagged. Nothing visible to click is not checked. |
| Named by aria-labelledby S10-labelledby | /test/ok/labelledby | 200 | OK | aria-labelledby gives it an accessible name, so it is not flagged. |
| Image with empty alt S10-image-empty-alt | /test/ok/image-empty-alt | 200 | Accessibility: Empty link text | |
| Text that starts with filler S10-filler-text | /test/ok/filler-text | 200 | OK | Only exact vague phrases are flagged; a sentence that starts with "Click here" is not. |
11. Rel & Target Attributes
Compare new-tab links with and without rel attributes. A working destination does not tell you whether a tool checks these attributes.
- Correct _blank — Opens a new tab safely.
- Missing rel — In older browsers the new tab can control this page. Add rel="noopener".
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Correct _blank S11-blank-rel | https://linkscan.app | 200 | OK | A location on the S1-https row. |
| Missing rel S11-blank-no-rel | https://linkscan.app | 200 | OK | rel and target are not checked. A location on the S1-https row. |
12. Security & Mixed Content
Compare an HTTP link on this HTTPS page with a destination that has an untrusted certificate. Watch for HTTPS upgrades and browser security warnings.
- HTTP on HTTPS page — Sends the visitor from a secure page to an insecure one. Use https://.
- Bad SSL certificate — Self-signed, so browsers show a full-page warning. The site needs a trusted certificate.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| HTTP on HTTPS page S12-http | http://linkscan.app | 301 → https://linkscan.app/; HSTS, so Chrome upgrades it before asking | Redirect: Use https instead needs verification | A location on the S1-http row. |
| Bad SSL certificate S12-self-signed | https://self-signed.badssl.com/ | Self-signed certificate; the TLS handshake fails | Broken: Can't connect |
13. Redirects
A redirect sends a request to another URL. A redirect chain passes through several URLs. A redirect loop repeats destinations without reaching a page.
- 301 Moved Permanently (one hop) — Works. Update the link to the new address to skip the hop.
- 308 Permanent Redirect (one hop) — Like 301. Update the link to the final address.
- 302 Found (one hop) — A temporary move. Fine to keep while the move is temporary.
- Redirect chain (two hops) — Each hop adds delay. Link to the final address.
- Redirect chain (three hops) — A longer chain, same fix: link to the final address.
- Redirect chain (twelve hops) — A browser may follow the full chain, while a checker may stop at its redirect limit. This is a long chain, not a repeating loop.
- Redirect loop — Pages redirect to each other forever; browsers show an error. Fix the redirect rules.
- Redirect to a missing page — Looks like a redirect, but it ends in a 404. Fix the redirect target.
- HTTP and www redirect — Two upgrades for one link. Use the canonical https:// address.
A redirect to a recognised not-found path returning 200 is predicted Broken; a deep-path redirect home is advisory. Direct 200 error bodies are not read. The ordinary one-hop links above are negative controls.
- 307 Temporary Redirect (one hop) — 307 → /privacy-policy/
- Soft 404 (error page with status 200) — The body is not read. A direct 200 with error text remains a missed problem in v2.1.
- Soft 404 by redirect to the home page — FR56 detects deep-path redirects ending at the site root, even with one hop.
- Redirect to a 200 not-found URL — The recognised final path supplies the signal, not its response body.
- Direct 200 not-found URL — Negative redirect control: a direct 200 error page remains undetected even at a recognised path.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| 301 Moved Permanently (one hop) S13-301 | /test/moved | 301 → /privacy-policy/ | OK → /privacy-policy/ (1 hop) | |
| 308 Permanent Redirect (one hop) S13-308 | /test/moved-308 | 308 → /contact/ | OK → /contact/ (1 hop) | |
| 302 Found (one hop) S13-302 | /test/redirect/1 | 302 → /test/redirect/0 → 200 | OK → /test/redirect/0 (1 hop) | |
| Redirect chain (two hops) S13-chain-2 | /test/redirect/2 | 302 → /test/redirect/1 → 302 → /test/redirect/0 → 200 | Redirect: chain of 2 redirects | The fix suggests linking to /test/redirect/0. |
| Redirect chain (three hops) S13-chain-3 | /test/redirect/3 | 3 × 302, then 200 | Redirect: chain of 3 redirects | |
| Redirect chain (twelve hops) S13-chain-12 | /test/redirect/12 | 12 × 302, then 200 | Broken: Redirect loop (stopped at the 10th hop) needs verification | With sufficient observed hops the 10-hop cap produces Broken. If events are entirely absent, one synthetic hop can yield OK; a partial chain with two or more recorded hops remains Redirect if it completes. Verify the actual browser result. |
| Redirect loop S13-loop | /test/loop/a | 302 → /test/loop/b → 302 → /test/loop/a, forever | Broken: Redirect loop needs verification | Same dependency as S13-chain-12; the fallback is Broken: Can't connect. |
| Redirect to a missing page S13-redirect-to-404 | /test/redirect-to-404 | 301 → /non-existent-page/ → 404 | Broken: 404 Page not found | Whether the row also shows the hop is settled by the run. |
| HTTP and www redirect S13-http-www | http://www.linkscan.app/ | 301 → https://www.linkscan.app/ → 301 → https://linkscan.app/ | Redirect: chain of 2 redirects needs verification | An HTTPS upgrade is advisory even if HSTS reduces the visible hop count. With fewer than two observed hops this can report Use https instead, not a chain. An owner-supplied pre-fixture-7 scan on 2026-10-12 reported the HTTPS-upgrade advisory; exact build/browser metadata was not supplied. |
| 307 Temporary Redirect (one hop) R-moved-307 | /test/moved-307 | 307 → /privacy-policy/ | OK → /privacy-policy/ (1 hop) | |
| Soft 404 (error page with status 200) R-soft-404 | /test/soft-404 | 200 with a "Page not found" page | OK | The page returns 200 even though its content says it is missing. LinkScan does not read the response body, so it is predicted to miss this problem. |
| Soft 404 by redirect to the home page R-soft-404-redirect | /test/soft-404-redirect | 301 → / | Redirect: Redirected to the home page | The missing deep-path URL redirects to the site root. LinkScan is predicted to flag this even with one redirect. |
| Redirect to a 200 not-found URL S13-not-found-redirect | /test/redirect-to-not-found | 302 → /test/not-found → 200 | Broken: Redirected to a not-found page | The recognised final path supplies the signal, not its response body. |
| Direct 200 not-found URL S13-direct-not-found | /test/not-found | 200 without a redirect | OK | Negative redirect control: a direct 200 error page remains undetected even at a recognised path. |
14. Network Failures
Test failures that happen before a page returns an HTTP status: missing domains, invalid certificates and connections that do not respond.
- Domain that does not exist — The reserved .invalid suffix is classified as a local address without a request from this public page, not as a DNS failure.
- Expired SSL certificate — Browsers block the page until the site renews its certificate.
- Certificate for another host — The certificate names a different domain, so browsers block the page.
- Port that does not answer — The connection times out. Check the port in the address.
The local/private examples below are for scanning, not for browsing your machine or network. The public HTTPS link in §1 is a negative control. Same-site exemptions apply only when the scanned page is itself local, private, staging or preview—not to every link on that page.
- Localhost address — Do not click unless you intend to access your own machine. LinkScan blocks this linked request on a public page.
- Private IPv4 address — Do not click unless you intend to access your private network. Compare the public HTTPS control in §1.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Domain that does not exist S14-no-domain | https://does-not-exist.invalid/ | Not requested: recognised local/reserved address on this public page | Broken: Local or private address | The .invalid suffix is caught before HTTP; this is not a measured DNS failure. |
| Expired SSL certificate S14-expired-cert | https://expired.badssl.com/ | Expired certificate; the TLS handshake fails | Broken: Can't connect | |
| Certificate for another host S14-wrong-host-cert | https://wrong.host.badssl.com/ | Certificate for another name; the TLS handshake fails | Broken: Can't connect | |
| Port that does not answer S14-port-81 | https://linkscan.app:81/ | No answer (curl gave up after 12 s) | Unknown: No response within 10 seconds | |
| Localhost address S14-localhost | http://localhost:3000/ | Not requested from this public page | Broken: Local or private address | Do not click unless you intend to access your own machine. LinkScan blocks this linked request on a public page. |
| Private IPv4 address S14-private-ip | http://192.168.1.10/ | Not requested from this public page | Broken: Local or private address | Do not click unless you intend to access your private network. Compare the public HTTPS control in §1. |
16. Edge-case URLs
Compare URLs with tracking parameters, different casing, encoded spaces and international characters. Some resolve to the same page; others may not.
- Tracking parameters — A separate address from the clean one. Keep tracking off internal links.
- Uppercase path — Paths are case-sensitive on many servers, where this would be a 404. This site's host redirects it to /contact/ instead, which costs a hop. Match the real path.
- No trailing slash — Often costs a redirect. Match the site's canonical form.
- Encoded space in query — Spaces must stay encoded as %20.
- Read the complete guide to finding, fixing and preventing broken links on every page of your website, including redirects, missing anchors and slow external resources — Very long link text. Works, but it is hard to scan and gets cut off in result lists. Keep link text short and specific.
- Internationalized domain — A non-ASCII domain; browsers convert it to punycode (xn--…).
- Added by a script two seconds after the page loads. Wait for the page to finish before you scan:
Links inside graphics, web components and frames
These examples place links inside SVGs, image maps, web components and embedded frames. Some tools may not detect them. Each points to a missing page; LinkScan's predicted coverage is listed in the table below.
- A link inside an SVG graphic:
-
A clickable area of an image map:
- A link inside a web component's shadow DOM:
- A link inside an embedded frame:
Preview links and controls
These same-site query examples exercise the implemented preview rule without relying on a third-party staging host. Specific preview patterns and same-site staging labels are recognised, not every draft URL. Broken and Unknown outcomes take precedence. Slow advice measures the selected request to headers, not page load.
- Same-site preview query — The exact preview=true query triggers advice on this public page.
- Non-preview query control — preview=false does not match the implemented preview=true rule.
- Preview URL with an HTTP error — Broken HTTP outcomes take precedence over preview advice.
- Preview URL temporarily unavailable — Unknown HTTP outcomes also take precedence over preview advice.
| Case | Link | What the server does | Predicted in LinkScan | Notes |
|---|---|---|---|---|
| Tracking parameters S16-tracking | /contact/?utm_source=example&utm_medium=test | 200 | OK | Its own row, separate from /contact/. |
| Uppercase path S16-uppercase | /Contact/ | 301 → /contact/ (Netlify ignores case) | OK → /contact/ (1 hop) | On a case-sensitive server this would be a 404. |
| No trailing slash S16-no-slash | /contact | 301 → /contact/ | OK → /contact/ (1 hop) | |
| Encoded space in query S16-encoded-space | /test/status/200?q=hello%20world | 200 | OK | Its own row, separate from /test/status/200. |
| Very long link text S16-long-text | /test/status/200 | 200 | OK | The link text is cut at 200 characters in the row. |
| Internationalized domain S16-idn | https://münchen.de/ | 301 → http://www.muenchen.de/, then more redirects | Redirect: chain of 2 or more redirects needs verification | A third-party site; checked as https://xn--mnchen-3ya.de/. |
| Link added two seconds after load S16-late-link | /test/ok/late-link | 200 | OK | Only present if the scan starts at least 2 s after the page loads. |
| Link inside an SVG graphic S16-svg | /test/status/404 | Not requested | Not listed | SVG links are not read (known gap). |
| Image map area S16-image-map | /test/status/404 | Not requested | Not listed | <area> links are not read (known gap). |
| Link inside shadow DOM S16-shadow-dom | /test/status/404 | Not requested | Not listed | Shadow DOM is not read (known gap). |
| Link inside an iframe S16-iframe | https://linkscan.app/test/status/404 | Not requested | Not listed | Frames are not read (known gap). |
| Same-site preview query S16-preview | /test/ok/preview?preview=true | 200 | Redirect: Preview or staging address | The exact preview=true query triggers advice on this public page. |
| Non-preview query control S16-preview-control | /test/ok/preview?preview=false | 200 | OK | preview=false does not match the implemented preview=true rule. |
| Preview URL with an HTTP error S16-preview-broken | /test/status/404?preview=true | 404 | Broken: 404 Page not found | Broken HTTP outcomes take precedence over preview advice. |
| Preview URL temporarily unavailable S16-preview-unknown | /test/status/503?preview=true | 503 | Unknown: Temporarily unavailable | Unknown HTTP outcomes also take precedence over preview advice. |