404 to Archive Redirecter

Redirects to the most recent Internet Archive snapshot if a page shows 404 or Not Found error.

  1. // ==UserScript==
  2. // @name 404 to Archive Redirecter
  3. // @namespace https://github.com/MathiasHM
  4. // @version 1.1
  5. // @description Redirects to the most recent Internet Archive snapshot if a page shows 404 or Not Found error.
  6. // @author Mathias H. M.
  7. // @match *://*/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. const currentURL = window.location.href;
  16. const archiveAPI = 'https://archive.org/wayback/available?url=';
  17.  
  18. // Prevent redirect loop
  19. if (window.location.hostname.includes('web.archive.org')) return;
  20.  
  21. const notFoundIndicators = [
  22. '404', 'not found', 'page not found', 'error 404',
  23. 'requested url was not found', 'this page does not exist',
  24. 'sorry, we couldn’t find', 'file not found', 'oops!', 'cannot be found'
  25. ];
  26.  
  27. function isPage404() {
  28. const text = document.body?.innerText?.toLowerCase() || '';
  29. const title = document.title?.toLowerCase() || '';
  30. const url = window.location.href.toLowerCase();
  31.  
  32. return notFoundIndicators.some(k =>
  33. text.includes(k) || title.includes(k) || url.includes(k)
  34. );
  35. }
  36.  
  37. function redirectToArchiveSnapshot(snapshotUrl) {
  38. console.log(`[404 to Archive Redirecter] Redirecting to snapshot: ${snapshotUrl}`);
  39. window.location.href = snapshotUrl;
  40. }
  41.  
  42. function showNoSnapshotFound() {
  43. alert("🚫 This page appears to be missing, and no Internet Archive snapshot was found.");
  44. console.warn("[404 to Archive Redirecter] No archive snapshot available.");
  45. }
  46.  
  47. function checkArchive() {
  48. fetch(`${archiveAPI}${encodeURIComponent(currentURL)}`)
  49. .then(res => res.json())
  50. .then(data => {
  51. if (data?.archived_snapshots?.closest?.url) {
  52. redirectToArchiveSnapshot(data.archived_snapshots.closest.url);
  53. } else {
  54. showNoSnapshotFound();
  55. }
  56. })
  57. .catch(err => {
  58. console.error("[404 to Archive Redirecter] Error querying archive:", err);
  59. });
  60. }
  61.  
  62. // Wait until the page loads before checking
  63. window.addEventListener('load', () => {
  64. setTimeout(() => {
  65. if (isPage404()) {
  66. console.log("[404 to Archive Redirecter] Page appears to be missing. Checking archive...");
  67. checkArchive();
  68. }
  69. }, 1000);
  70. });
  71. })();