Counterpart to the redirects-website repo.
✏️ How to edit
💡 Motivation
✔️ Comparison
🧠 How it works
⚙️ Setup
- Add/change/remove redirect entries in one or more
.yaml
files in the top folder. Note: thefrom
field is case-insensitive. - Commit the changes to the
main
branch, either directly or with a pull request (recommended so the automatic process can catch errors before the changes go live). - Changes should take effect automatically within a minute or so. Verify that no errors occurred in the automatic process here:
- Verify that none of your redirect links are reported broken in the automatic process here: . Note that this is only a rough check. There may be false positives or true negatives, as it simply checks the status code of the link, which the third-party may choose inappropriately.
You can do this directly on github.com (tip: press . right now), or locally with git.
You've likely heard of services like Bitly, TinyURL, Rebrandly, and others.
They allow you to convert a long link like some-website.com/a-long-url?search=a-bunch-of-characters
into a shorter one like bit.ly/98K8eH
.
When someone visits the shorter link, the service automatically "redirects" them to the longer one.
You can think of it like a shortcut.
These services usually offer several other features that you probably want too:
- You can customize the text after the
/
, giving you a url that a human could actually remember and type in manually, likebit.ly/MyCoolLink
(sometimes called "back-halves"). - You can set up a custom domain to brand your links the way you want, giving you an even nicer link, like
my-website.com/MyCoolLink
. - You can see how many and what kinds of people have used the link over time (i.e. analytics).
This all sounds great, so what's the problem? Well namely: they hide or limit a lot of this functionality behind a paywall. Bitly, the de facto standard, is especially quite expensive. While you may be able to find one that gives you most or all of what you want for free right now, free plans have generally become more and more limited over time.
Paying for a plan may not be a problem for you, especially if you value the convenience of having a simple service that handles everything automatically. But with just a little bit of setup, we can accomplish all of this in a much better way. Well, at least much better-suited to the target audience of this approach: people/organizations who use GitHub and Git.
Here's how this approach compares to Bitly and similar services.
The benefits:
- Free(er)! You only need to pay for a custom domain name, if you want.
- Not subject to the pricing whims of Bitly or similar services. Pricing and features should remain the same.
- Uses tools and workflows you're already accustomed to and ideally prefer (assuming you're in the target audience mentioned above). You don't need to create a new account just for this purpose, like you do for e.g. Bitly.
- Multiple accounts can collaborate on the same set of links. Many url shortening services don't offer this, or only offer it at enterprise-level pricing.
- You get a nice git history of all of your links; who changed what and when.
- You can use whatever analytics service you want, e.g. Google Analytics.
- You're in complete control. With a bit of coding knowledge, you can customize it any way you'd like. All of the code has detailed comments and is written to be flexible/editable.
The equivalent:
- Adding/changing/removing links is quick, convenient, and automatic.
- You can customize the text of your links fully, both the domain and the part after the
/
. - You can track analytics for your links.
- You can restrict who can see and edit the links.
- You can organize your links and add comments however you want to make maintenance easier.
- You have to pay if you want a custom domain.
- People can't use web searches to find private info like Zoom room urls.
The downsides:
- More setup.
- Your redirect lists are not truly 100% hidden from the public1.
- Editing YAML is slightly harder than typing in textboxes, so you could accidentally break the formatting.
- If things go wrong, you have to troubleshoot it yourself or ask for help.
You have a private redirects GitHub repository that contains your redirect lists as .yaml
files.
This is how you specify where you want to redirect from and to.
You choose who can see or edit these lists using GitHub's permission settings.
You also have a public website GitHub repository that hosts a barebones GitHub Pages website. This is what actually performs the redirecting when a user visits a link. You can set this website up at a custom domain to make your links shorter and nicer.
After the one-time setup, all you have to do is edit the .yaml
files, and everything else updates automatically, within a minute or so.
Adding/removing/changing a link goes like this:
- You change one or more of the
.yaml
files in the redirects repo. deploy.yaml
tells GitHub Actions that any time someone commits a change to the repo, it should automatically run theencode.js
script.- The
encode.js
script combines all of your.yaml
files into one, and encodes it1. deploy.yaml
then tells GitHub to take the result of theencode.js
script and commit it to theredirect.js
script in the website repo.- In the website repo, GitHub Pages detects a change in the
redirect.js
script, and updates the website.
Then, a user visiting a link goes like this:
- They navigate to a link on the website, e.g.
/chatroom
. chatroom.html
isn't a file in the website repo, and thus isn't a page on the website, so GitHub loads404.html
for the user instead (but preserves the/chatroom
url). This file immediately runs some scripts:- The analytics code snippet sends2 stats like url, IP, date, time, location, etc. off to Google Analytics or whoever.
- The
redirect.js
script decodes the redirect lists previously encoded from the redirects repo, finds the long url corresponding to "chatroom" (case-insensitive), and navigates there instead. - They arrive at the intended destination, e.g.
zoom.us/j/12345abcdef
, with virtually no perceptible delay.
- Use the redirects repo (this repo) as a template.
Do not fork, because you cannot make forks private.
Name it
redirects
and make it private. - Use the website repo as a template.
Name it
redirects-website
and make it public. - Enable GitHub Pages on your copied website repo with the default settings.
- After a minute or so, GitHub should tell you that your site is now being hosted at
your-org.github.io/redirects-website
.
If you ever need to pull in updates from these templates, see the instructions here.
To allow your redirects repo to automatically write to your website repo, you need to "connect" them with a deploy key:
- Generate an SSH key pair.
- In your redirects repo, create a new repository actions secret named
DEPLOY_KEY
, and paste the private SSH key. - In your website repo, create a new deploy key with write/push access named
DEPLOY_KEY
, and paste the public SSH key.
Every analytics service is slightly different, but they should all have a way to get a snippet of JavaScript code that you can copy and paste into the webpages you want to track. Find out how to get that for the service you're using. For Google Analytics, those instructions are here.
When you find the code snippet, paste it into 404.html
where marked (above the redirect.js
script) in your website repo.
By default, GitHub Pages will host your redirects website at your-org.github.io/redirects-website
, which gets pretty long when you add on /some-link
.
You can make this shorter in one of two ways.
Note: If you do either of these, set baseurl = "";
in the redirect.js
script in your website repo.
e.g. your-domain.com/some-link
Follow the instructions here. In summary:
- Purchase a domain name from a reputable service.
- Point your domain name provider to GitHub Pages using an
A
record. This is slightly different for each company; they should have their own instructions on how to do it. - Set the custom domain field in the "Pages" settings of your website repo (automatically creates a
CNAME
file in the repo). - After a minute or so, GitHub should tell you that your site is now being hosted at
your-domain.com
.
e.g. your-org.github.io/some-link
- Name your website repo
your-org.github.io
to match your GitHub user/organization name. - In your redirects repo, change
redirects-website
indeploy.yaml
to the same name.
These aren't always necessary or desired, but may help the users and editors of your links.
In your redirects repo:
- Add a big warning to the top of the readme like "Do not share links here without permission 🔒", so that people who have access understand that it's privileged info.
In your website repo:
- Add a big link to the top of the readme to remind people where your website is hosted, e.g.
your-domain.com
. - In
redirect.js
, customize what happens when a user visits a url that has no matchingfrom
redirect (fallback action). - Add an
index.html
page with some filler content like "This website just performs redirects for [YOUR ORG]", in case people go to the root of the website with no e.g./some-link
.
If you already have a website being hosted with GitHub Pages that you want to incorporate this approach into:
- Skip templating the website repo.
- Instead, copy its
redirect.js
script into the top folder of your existing website repo, and modifybaseurl
in it as appropriate. - Include the script in your 404 page in the same way it is done here.
If an existing page and a redirect have same name/path, the redirect won't happen since the user won't get a
404
.
If your existing website is built and hosted in a different way, this approach would require modification3 and might not be appropriate for you.
Footnotes
-
This approach performs redirects "client-side" rather than "server-side". Because of this, your redirect list cannot be encrypted, it can only be obfuscated such that it is not searchable or human-readable. Anyone with some coding knowledge could still figure out all of your redirect lists with some effort. ↩ ↩2
-
The analytics service you're using should be able to capture all the necessary stats in time, before the redirection happens. But these services are usually closed source, so we can't know for sure exactly how they work. However, in testing with Google Analytics at least, everything seems to be captured fine. ↩
-
You would need to modify the
deploy.yaml
workflow to be able to commit/push/upload the result to wherever your website is, integrate it into your code as appropriate, and trigger a re-build of your website. ↩