linkinator
linkinator copied to clipboard
Retry a gaxios request with new url
The way my site is built, some relative paths don't exist until we publish. I'm looking to retry failed HEAD requests with an absolute path.
Example: dist/index.html has 2 links in it. /link1 and link2. /link1 can be found no problem, returns a 200. /link2 returns a 404. I'd like to retry /link2 with an absolute path. http://mysite.com/link2.
Originally I was going to create a massive ignore list with all the relative paths that don't exist locally, but if any of those pages were to get deleted, I wouldn't be able to tell.
I could do the requests myself after, or write to a dummy file with all the new links and perform a new scan on just that file after?
Any ideas?
My working solution, it's not the cleanest, but it's quick and it works.
import fs from 'fs';
import { LinkChecker } from 'linkinator';
const checkForBrokenLinks = async () => {
const fullSiteChecker = new LinkChecker();
const absolutePath = 'http://myabsolutepath.com';
// Scan all index.html files in the /dist directory for broken url's.
// .check() is an AsyncFunction, let's wait for results.
const results = await fullSiteChecker.check({
path: '**/index.html',
timeout: 5000,
linksToSkip: [
'_nuxt',
'node_modules',
],
});
const brokenLinks = results.links.filter((x) => x.state === 'BROKEN');
const html = brokenLinks
.map((brokenLink) => `<a href="${absolutePath}${brokenLink.url}"/>`)
.join(' ');
// inject all the broken links into a temporary html file.
// We're going to re-run the scanner against the temporary file. Except this
// time we're swapping the local path with the absolute path. This
// is because the local references only work on prod.
fs.writeFile('retry.html', html, () => console.log('Created retry.html'));
const retryChecker = new LinkChecker();
const retryResults = await retryChecker.check({
path: 'retry.html',
timeout: 5000,
});
console.log(`Scanned a total of ${results.links.length} links`);
const broken = retryResults.links.filter((x) => x.state === 'BROKEN');
console.log(`Found ${broken.length} broken links`);
if (broken.length) {
broken.forEach((brokenLink) =>
console.log(
`${brokenLink.status} - ${brokenLink.url.replace(absolutePath, '')}`,
),
);
process.exit(1);
}
};
checkForBrokenLinks();
Greetings! I can see how something like this is useful, but it's bespoke enough that I wouldn't want to try adding it to the tool. It's a great sign that you were able to piece this together using linkinator as an npm module, so I'm going to consider this a win!