How to Find Broken Links on Your Website
Broken links are one of those problems that silently destroy your SEO and user experience. Every 404 your visitors hit is a dead end -- they leave, and Google takes note. Studies show that sites with broken links rank measurably lower than equivalent sites without them.
The tricky part isn't fixing broken links. It's finding them. A site with 50 pages might have hundreds of outbound links, and any of them can break at any time when external sites change their URLs, remove content, or go offline entirely.
Why Broken Links Matter More Than You Think
- SEO impact: Google crawls your links. When it finds 404s, it treats your site as less maintained. Internal broken links waste crawl budget. External broken links signal outdated content.
- User experience: Every broken link is a frustrated visitor. On e-commerce sites, a broken product link is a lost sale.
- Credibility: Blog posts linking to dead resources look abandoned. Documentation with broken links looks unmaintained.
- Link equity: Internal links pass PageRank. A broken internal link is leaked authority that could be boosting another page.
The Manual Way: Browser Extensions
Extensions like "Check My Links" highlight broken links on a single page. This works for spot-checking but doesn't scale. You'd need to visit every page on your site manually, and you'd need to recheck periodically since external links break over time.
The DIY Way: Script It
const cheerio = require('cheerio');
const axios = require('axios');
async function checkLinks(pageUrl) {
const { data: html } = await axios.get(pageUrl);
const $ = cheerio.load(html);
const links = [];
$('a[href], img[src]').each((_, el) => {
const url = $(el).attr('href') || $(el).attr('src');
if (url && url.startsWith('http')) links.push(url);
});
const results = await Promise.allSettled(
links.map(url =>
axios.head(url, { timeout: 10000, maxRedirects: 5 })
.then(r => ({ url, status: r.status, ok: true }))
.catch(e => ({ url, status: e.response?.status || 0, ok: false }))
)
);
return results.map(r => r.value || r.reason);
}
This basic approach works but misses edge cases: relative URLs, fragment links, JavaScript-rendered content, rate limiting from target servers, and redirect chain analysis. Handling all of this properly requires significant error handling and infrastructure.
The API Way: LinkCheck
LinkCheck scans any page and checks every link in parallel, handling all the edge cases for you.
curl -X POST "https://linkcheck.grabshot.dev/v1/scan" \
-H "X-Api-Key: lc_your_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-site.com/blog"}'
The response includes:
- Every link on the page (anchors and images)
- HTTP status for each link (200, 301, 404, timeout, etc.)
- Redirect chains -- see where 301s actually lead
- Response times -- catch slow external dependencies
- Summary stats -- total links, broken count, redirect count
Node.js Integration
const resp = await fetch('https://linkcheck.grabshot.dev/v1/scan', {
method: 'POST',
headers: {
'X-Api-Key': 'lc_your_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({ url: 'https://your-site.com' })
});
const data = await resp.json();
// Find broken links
const broken = data.links.filter(l => !l.ok);
broken.forEach(l => {
console.log(`BROKEN: ${l.url} (${l.status})`);
});
CI/CD Integration
Add link checking to your deployment pipeline. Fail the build if broken links are detected:
# GitHub Actions example
- name: Check for broken links
run: |
RESULT=$(curl -s -X POST "https://linkcheck.grabshot.dev/v1/scan" \
-H "X-Api-Key: ${{ secrets.LINKCHECK_KEY }}" \
-H "Content-Type: application/json" \
-d '{"url": "${{ env.DEPLOY_URL }}"}')
BROKEN=$(echo "$RESULT" | jq '.summary.broken')
if [ "$BROKEN" -gt 0 ]; then
echo "Found $BROKEN broken links!"
echo "$RESULT" | jq '.links[] | select(.ok == false)'
exit 1
fi
Scan Your Site for Free
Find broken links before your visitors do. 25 free scans per month.
Try LinkCheck FreeBest Practices for Link Maintenance
1. Scan weekly, not yearly
External links break constantly. A quarterly check means you're serving broken links for months. Set up a weekly scan on your most important pages.
2. Fix internal links first
Internal broken links are entirely within your control and have the biggest SEO impact. Fix these immediately.
3. Use redirects for removed content
When you remove a page, 301 redirect it to the closest relevant page. Never just delete and leave a 404.
4. Monitor high-traffic pages
Your homepage, top blog posts, and landing pages should be checked more frequently. A broken link on your homepage is far worse than one on a 3-year-old blog post.
Wrapping Up
Broken links are a slow leak in your site's SEO and user experience. The fix is simple: scan regularly and fix what you find. Whether you build your own checker, use LinkCheck, or combine both, the important thing is to actually do it on a schedule.
More from GrabShot
- Detect What Fonts a Website Uses (FontSpy)
- Extract Colors from Any Website (ColorPeek)
- How to Monitor Cron Jobs in 2026 (CronPing)
- Best Screenshot APIs in 2026 (GrabShot)
- HTML to PDF API Guide (PDFMagic)
๐ง Developer API Tips
Get practical API tutorials and tools. No spam, unsubscribe anytime.