NiKo
NiKo

Reputation: 11412

301 redirect for site hosted at github?

Here's a Github repository of mine: https://github.com/n1k0/casperjs

There's a gh-pages branch to hold the project documentation, which is basically the project website: https://github.com/n1k0/casperjs/tree/gh-pages

This branch setups the documentation site at http://n1k0.github.com/casperjs/ — hurray.

In the meanwhile, I've bough the casperjs.org domain to get this website available through it, so I put a CNAME file as recommended in the docs: https://github.com/n1k0/casperjs/blob/gh-pages/CNAME — in their example, the operation is supposed to create redirects from www.example.com and charlie.github.com to example.com

While the website now points to http://casperjs.org/, there's no 301 redirect from http://n1k0.github.com/casperjs/ (the old site url) to the new domain name.

Any idea how to setup such a redirect, if it's even possible? Is it a bug? If it is, where should I open an issue?

Upvotes: 73

Views: 24724

Answers (9)

Josua Krause
Josua Krause

Reputation: 71

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.

Upvotes: 0

Jongwoo Lee
Jongwoo Lee

Reputation: 1128

No.

Other answers talk about redirections with meta refresh or javascript. But the OP asked about 301 redirects. And here's the answer: No. It is not possible. Your site on GitHub Pages is static, so you don't have any control over the server.

Upvotes: 21

Manual layout method

If you don't feel like using https://github.com/jekyll/jekyll-redirect-from it's easy to implement it yourself:

a.md:

---
layout: 'redirect'
permalink: /a
redir_to: 'http://example.com'
sitemap: false
---

_layouts/redirect.html based on Redirect from an HTML page :

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Redirecting...</title>
  {% comment %}
    Don't use 'redirect_to' to avoid conflict
    with the page redirection plugin: if that is defined
    it takes over.
  {% endcomment %}
  <link rel="canonical" href="{{ page.redir_to }}"/>
  <meta http-equiv="refresh" content="0;url={{ page.redir_to }}" />
</head>
<body>
  <h1>Redirecting...</h1>
  <a href="{{ page.redir_to }}">Click here if you are not redirected.<a>
  <script>location='{{ page.redir_to }}'</script>
</body>
</html>

Now:

firefox localhost:4000/a

will redirect you to example.com.

Like this example, the redirect-from plugin does not generate 301s, only meta + JavaScript redirects.

We can verify what is going on with:

curl localhost:4000/a

Tested on GitHub pages v64, live demo at: https://github.com/cirosantilli/cirosantilli.github.io/tree/d783cc70a2e5c4d4dfdb1a36d518d5125071e236/r

Upvotes: 7

equivalent8
equivalent8

Reputation: 14237

Github pages don't support anything like .htaccess or nginx/conf

https://help.github.com/articles/redirects-on-github-pages/

so easiest way is:

HTML redirect:

index.html

<html>
  <head>
    <meta http-equiv="refresh" content="0; url=http://www.mywebsite.com/" />
  </head>

  <body>
    <p><a href="http://www.mywebsite.com/">Redirect</a></p>
  </body>
</html>

Upvotes: 7

GromNaN
GromNaN

Reputation: 592

You can redirect using Javascript after host detection, like this:

if (window.location.href.indexOf('http://niko.github.com') === 0) {
    window.location.href = 'http://casperjs.org{{ page.url }}';
}

But I agree, it's not an HTTP redirection.

Upvotes: 8

Perry
Perry

Reputation: 879

Bringing this topic back from the dead to mention that GH now supports redirect-from's redirect-to parameter https://github.com/jekyll/jekyll-redirect-from#redirect-to

Simply add this to your _config.yml

gems:
  - jekyll-redirect-from

And this to the top of your index page.

---
redirect_to: "http://example.com"
---

Upvotes: 43

vinyll
vinyll

Reputation: 11409

Why didn't you use http://www.w3.org/TR/WCAG20-TECHS/H76.html?

That would give

<meta http-equiv="refresh" content="0;URL='http://casperjs.org/'" />

Upvotes: 7

Joey
Joey

Reputation: 439

I had a similar issue when switching the domain for my github pages site. I set up rerouter on Heroku to handle the 301 redirects to the new domain. It handles domain-to-domain redirects very simply, but you may have to modify it to handle your site's legacy domain+path location.

I described the steps in detail here:

http://joey.aghion.com/simple-301-redirects/

Upvotes: 1

piouPiouM
piouPiouM

Reputation: 5037

To avoid the duplicate content, in a first time you can add a meta canonical like this:

<link rel="canonical" href="http://casperjs.org">

Upvotes: 16

Related Questions