How to Test QR Codes on Websites and Mobile Apps
Test a QR code from its encoded payload through the final browser page or app screen, using real devices and the right failure cases.
A QR code works only when the whole journey works: the code decodes to the expected payload, the destination is correct, and the intended phone opens the right browser page or app screen. Test the deployed code on target devices, including app-installed and app-not-installed paths. A validator or screenshot can help inspect a web destination, but neither replaces a real-device scan and app handoff.
1. Define what success means
Before testing, write down the exact expected payload and outcome. A QR code may encode a URL, plain text, or a custom payload that an app understands. Decide what should happen when a user scans it, what should happen if the app is absent, and what an invalid, expired, or unsupported payload should do. The European Commission’s QR code security guide distinguishes URL use from custom payloads and digital codes from printed ones.
- Expected payload: the exact URL or custom data, including capitalization, path, query values, and required parameters.
- Expected destination: the final page or app screen, including any intended campaign, state, or account context.
- Supported routes: browser, installed app, in-app scanner, or a defined fallback.
- Failure behavior: what users see when offline, logged out, missing the app, or following an expired link.
QR symbol encoding, dimensions, error correction, decoding, and production quality are covered by ISO/IEC 18004:2024. Decoding correctly is one layer of verification; it does not establish that the destination or app behavior is correct.
2. Check the encoded payload and web destination
- Decode the deployed code with a trusted scanner or your app’s test tooling.
- Compare the decoded value character-for-character with the expected payload.
- For a URL, inspect the scheme, hostname, path, query string, and any fragment or state values your flow depends on.
- Open the URL and follow redirects. Confirm the final host and page are the intended ones.
- Check that any old URL still redirects if the destination has moved. A changed page address can break a printed or distributed QR code without a redirect; the U.S. Department of Energy’s QR code guidance recommends short URLs and redirects when addresses change.
Do not treat a successful decode or a browser preview as proof that a link is safe. Confirm that the payload and destination match the purpose stated to users, and handle unexpected payload types safely.
3. Test how the code is actually displayed
Test the deployed version in its real context: the website, app screen, email, presentation, or print. Check that the complete code is visible and not clipped, covered, distorted, or obscured by surrounding content. There is no universal minimum display size or scan distance in the cited guidance; test at the size and viewing distance your users will encounter.
For an on-screen QR code, use a second device to scan the screen. A screenshot viewed on the same phone does not test the scan journey. The European Commission guide treats codes shown on website or app screens as digital QR support, which differs from printed codes.
QR codes can be awkward when the user is already viewing the page on the device needed to scan. The Department of Energy advises against placing QR codes on websites, social media, or email when users can click a hyperlink instead. If you provide an on-screen QR code, offer a clickable link as an accessible and convenient alternative.
4. Scan on target phones
Use the scanner your audience is expected to use: the native camera, a system code scanner, or your app’s scanner. Record each step: whether the code was recognized, what payload preview appeared, what the user tapped, which browser or app opened, and the final URL or screen.
iPhone and iPad
Apple documents scanning with Camera or Code Scanner and then tapping the surfaced link. For an app that scans codes itself, Apple’s VisionKit camera scanning documentation describes recognizing QR codes in camera video and providing an action for the payload. Test both the native scan route and any in-app route your product offers.
Pixel phones
Google documents using Camera or the Scan QR code control on Pixel, then tapping the surfaced link. If a scan does not register, Google recommends making the full code visible, holding steady, improving the light, cleaning the lens, and adjusting distance while keeping the code in frame. See Google Pixel’s QR scanning guidance.
Practical capture checks
- Keep all four corners of the code in view and avoid glare or reflections.
- Check that the code remains clear at the actual displayed size and brightness.
- Try more than one target device and the scanner path users will actually use.
- If scanning a physical print, test that printed copy too; a digital source image does not reveal print quality problems.
5. Verify app links and fallback behavior
A QR code can decode to the right URL but still open the wrong place: a browser instead of the app, the app’s home screen instead of the intended content, or an app screen that requires a missing session. Test each route independently.
| Device state | What to verify |
|---|---|
| App installed, signed in | Expected app opens at the intended screen with the right item or state. |
| App installed, signed out | Sign-in and post-login return behavior are appropriate. |
| App not installed | The web fallback or install path is useful and does not dead-end. |
| Network unavailable or restricted | The user sees a recoverable error or a clear retry path. |
| Expired or invalid link | The destination explains the problem without opening unrelated content. |
For iOS Universal Links, verify that the Apple App Site Association file and its path patterns cover the URL being tested, and that the app configuration is in place. Google’s deep link validator guide explains that website checks do not establish that app configuration is correct. It also cautions that previews may not reflect app content when login or location restrictions apply, and recommends scanning on the user’s own device to confirm the correct app page opens. Treat a validator pass as one check, not proof of the complete journey.
6. Use a screenshot to inspect the web landing page
A screenshot is useful for checking what a URL destination renders: whether a redirect lands on the expected page, whether the page is blank, or whether an obvious error or consent layer covers the content. It cannot show whether a QR code is scannable, whether an app opens, or what a logged-in user sees on a device. Combine visual inspection with the real-device tests above.
For a manual browser capture, open the final URL in a browser, wait for the page to render, and save a screenshot. When checking a QR landing page, capture the actual deployed URL rather than a local mock. If the page depends on authentication, location, or device state, inspect the relevant state separately.
ScreenshotNeo API example
ScreenshotNeo is a website screenshot API and MCP server for developers. Its API can return a PNG, JPEG, WebP, or PDF from a URL. For this workflow, use a capture to inspect the web destination after resolving the QR code; it does not replace scanning the code on a phone.
Install the Python dependency with python -m pip install requests. Put your API key in an environment variable named SCREENSHOTNEO_API_KEY, then run:
import os
import requests
url = "https://example.com/qr-destination"
response = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={
"access_key": os.environ["SCREENSHOTNEO_API_KEY"],
"url": url,
},
timeout=90,
)
response.raise_for_status()
with open("qr-landing.webp", "wb") as image:
image.write(response.content)
See the ScreenshotNeo API documentation for request parameters and response details.
Or skip the browser setup
For a quick visual check of the decoded destination, make one GET request:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Every feature is on every plan. Use ScreenshotNeo to inspect the rendered web destination, then verify scanning and app handoff on your target phones.
Sign up free for 1,000 screenshots a month, with no card.
7. Troubleshooting checklist
| Symptom | Likely cause | What to do |
|---|---|---|
| Camera does not recognize the code | Code is clipped, too small for conditions, out of focus, poorly lit, or obscured. | Show the full symbol, steady the phone, improve light, clean the lens, and adjust distance while keeping the code in frame. |
| Code scans but opens the wrong page | Wrong payload, stale destination, unexpected redirect, or incorrect query value. | Decode and compare the exact payload; follow redirects and inspect the final URL. |
| Browser opens, app does not | App-link association or app configuration does not cover the URL, or the app is absent. | Check Universal Link configuration and association patterns; test installed and uninstalled paths on a device. |
| App opens to its home screen | The app received the link but did not route its path or state to the intended screen. | Check in-app route parsing and handling for the exact path and parameters; test signed-in and signed-out states. |
| Validator preview is wrong or incomplete | Login, location, or app behavior may not be represented in the preview. | Scan on the target device and confirm the final in-app page. Review app configuration separately. |
| Old printed codes fail | The original destination moved or expired without a redirect. | Restore an intentional redirect where possible; otherwise issue replacement codes and update digital placements. |
| Landing screenshot is blank or shows an error | Page load failed, a bot check intervened, or the destination requires state that the capture lacks. | Open the URL directly under the relevant conditions and inspect the response and final destination; do not infer scan or app behavior from the image. |
8. Performance, reliability, and cost
For a small release, a representative device matrix and a few focused failure cases usually produce more useful evidence than repeatedly scanning one device. Keep a record of the code version, decoded payload, device and OS, scanner used, app state, final URL or screen, and result. Re-run the journey after changing the destination, redirect rules, app-link association, or QR artwork.
Keep destination URLs short where feasible, and preserve redirects for codes already distributed. A static code continues to point to its encoded value; changing the website route does not update the code itself. If you automate landing-page screenshots, account for load time and any authentication or location requirements. ScreenshotNeo’s billing rule is based on clean shots; its documented response headers report the page verdict and whether the response was billed. A screenshot service can reduce browser setup for visual checks, but device scans and app-path testing remain necessary.
Frequently asked questions
Can I test a QR code from a screenshot on the same phone?
You can decode an image with suitable software, but that does not test the real scan journey for a code displayed on the phone itself. Use a second device for an on-screen code.
Does a valid QR code prove the link is safe?
No. Decoding confirms the payload can be read. Compare it with the intended destination and make the destination clear to users before they open it.
Should I put a QR code on a website?
Often a clickable link is easier when visitors are already on a device with a browser. If the QR code serves a cross-device task, provide a link too.
What proves that an app deep link works?
Scan on a representative device and confirm the intended app and screen open in the relevant installed, signed-in, and fallback states. A validator alone does not verify the entire user journey.


