Soft redirects only work if the content type is html (or similar). For binary files, let's say 'foo.pdf', github will not make a redirect possible as it sets the mime type according to the pdf extension and a soft redirect will just be interpreted as broken pdf.
That said, it is still possible to redirect correctly on github, but only use the following solution if:
- the server doesn't allow you to set a 301 redirect yourself (as is the case for github pages)
- the mime type is set by the file extension and it is a binary file (example: pdf, png, ...)
- none of the other solutions here work for you
- the resource is directly accessed by the user using a browser and it is not referenced by eg html (for example
<img src="...">
- the old page is not indexed by google etal. anymore (ie., the sitemap points to the new url) as the solution will break google's crawling for the resource (google will only see a 404)
- you are allowed to provide custom 404 pages (as is the case for github pages)
the trick is to use embedded javascript in the 404 page that checks the url and redirects accordingly.
github pages allows you to define a 404 page by creating a file "404.html" in the root of the project (assuming the whole project is deployed via branch; otherwise put the file in the root of the deployed artifact)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data:; connect-src 'self'"
/>
<title>Page not found</title>
<style type="text/css" media="screen">
// style your 404 nicely
</style>
</head>
<body onload="redirect()">
<div class="container">
<h1>404</h1>
<p><strong>File not found</strong></p>
<p>The requested resource does not exist.</p>
<div id="suggestions">
<a href="/">Bring me back!</a>
</div>
</div>
</body>
<script>
function redirect() {
if (window.location.pathname === '/old_incorrect_path/foo.pdf') {
window.location = 'https://yourpage.com/path_to_correct_resource/foo.pdf';
}
}
</script>
</html>
The embedded javascript checks the requested pathname after the 404 page has loaded and will only redirect if it matches the old address. You can redirect multiple resources this way by chaining the ifs or just replace the host of the location for all urls if it's a full redirect for the whole page (but again use other methods where possible). Alternatively, you can also put the script at the top and let it execute right away instead of waiting for a full load, however, it might be nice for the user to see that their link was indeed a 404 before sending them to the correct place (and it's a good reminder for you to remove the hack once people overwhelmingly go to the correct link directly).
Note, setting a "Content-Security-Policy" to mostly 'unsafe-inline' makes sense as you shouldn't load other resources on a 404 page.
Please don't use this solution unless there is absolutely no other way to achieve the desired result. Again, it only works if the user directly browsers to the resource. Also, a web crawler will identify the pages as 404 and thus not count them as valid redirect. For example, google won't allow it for migrating a domain from the google search console (you need 301 redirects or valid soft redirects via <meta http-equiv="refresh" content="0; url=https://..." />
for google to accept the move). Also, referencing the resource via eg img will also break (as the image is seen as 404 only).
However, this is a valid solution for cases where, for one reason or another, users directly land on the resource while browsing and the referrers haven't updated the links yet (eg. stale google search result links or other pages linking to the old address). Their automated tooling (if they use any) will notify them that the link is returning a 404 and bring them to update the links (hopefully) eventually.