Skip to content

CU-DBMI/redirects

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

20 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

URL Redirects with GitHub

Counterpart to the redirects-website repo.

πŸ‘οΈ Overview
✏️ How to edit
πŸ’‘ Motivation
βœ”οΈ Comparison
🧠 How it works
βš™οΈ Setup

Overview

A free(er), DIY(-ish) alternative to URL shortening services such as Bitly.

The target audience for this approach is people/organizations who use Git, GitHub, and YAML. If you are not familiar with these, this is likely not for you.

How to edit

  1. Add/change/remove redirect entries in one or more .yaml files in the top folder of this repo. Tip: press . on GitHub to edit.
  2. Each entry should have a from field, the short/visited URL (case-insensitive) you want to redirect from (e.g. /some-link), and a to field, the longer/destination URL you want to redirect to (e.g. https://zoom.us/j/12345abcdef).
  3. Commit the changes to the main branch, either directly or preferably with a pull request so that automatic processes can catch errors before changes go live.
  4. Changes should take effect automatically within a minute or so. Verify that no errors occurred in the automatic process here: Encode and deploy
  5. Verify that none of your to links are reported broken in the automatic process here: Check links. Note: this is only a rough check. There may be false positives/negatives, as it simply checks the status code of the link, which the third-party may choose inappropriately.

Motivation

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, like bit.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.

Comparison

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. 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 /.
  • Automatically and periodically tries to check if any of your destination links are broken.
  • 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 private, only obfuscated.1.
  • Editing YAML is bit harder than typing in text boxes, so you could accidentally break the formatting.
  • If things go wrong, you have to troubleshoot it yourself or ask for help.

How it works

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 bare-bones 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.

flowchart
  subgraph s1["πŸ” Redirects Repo"]
    n1("πŸ“ redirects.yaml"):::node
    n2("πŸ€– deploy.yaml"):::node
    n3("βš™οΈ encode.js"):::node
  end
  subgraph s2["🌐 Website Repo"]
    n4("βš™οΈ redirect.js"):::node
    n5("πŸ“ƒ 404.html"):::node
  end
  subgraph s3["your-domain.com"]
    direction TB
    n6("🌐 your-domain.com/chatroom"):::node
    n7("😡 404.html"):::node
    n8("βš™οΈ analytics snippet πŸ“Š"):::node
    n9("βš™οΈ redirect.js"):::node
    n10("🏁 zoom.us/j/abcedf123456"):::node
  end
  s1:::group
  s2:::group
  s3:::group
  n1 --- n2
  n2 --- n3
  n6 --- n7
  n7 --- n8
  n8 --- n9
  n9 --- n10
  n3 ---|"πŸ”£ obfuscate"| n4
  s2 ---|"πŸ€– publish"| s3
  classDef group color:black,stroke-width:0px,fill:#f0f0f0
  classDef node color:black,stroke-width:0px,fill:#e0e0e0
  linkStyle default color:black,stroke:black
Loading

Adding/removing/changing a link goes like this:

  1. You change one or more of the .yaml files in the redirects repo.
  2. deploy.yaml tells GitHub Actions that any time someone commits a change to the repo, it should automatically run the encode.js script.
  3. The encode.js script combines all of your .yaml files into one, and encodes it1.
  4. deploy.yaml then tells GitHub to take the result of the encode.js script and commit it to the redirect.js script in the website repo.
  5. 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:

  1. They navigate to a link on the website, e.g. /chatroom.
  2. chatroom.html isn't a file in the website repo, and thus isn't a page on the website, so GitHub loads the 404.html page for the user instead (but preserves the /chatroom URL). This page immediately runs some scripts:
  3. The analytics code snippet sends2 stats like URL, IP, date, time, location, etc. off to Google Analytics or whoever.
  4. The redirect.js script decodes the redirect lists previously encoded from the redirects repo, finds the destination URL corresponding to "chatroom" (case-insensitive), and navigates there instead.
  5. They arrive at the intended destination, e.g. zoom.us/j/12345abcdef, with virtually no delay.

A check-broken.js script also runs periodically and on changes to your redirects repo, which tries to check if any of your destination links are broken.

Setup

Set up repos

  1. 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.
  2. Use the website repo as a template. Name it redirects-website and make it public.
  3. Enable GitHub Pages on your copied website repo with the default settings.
  4. 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 update your copies of these templates, see the instructions here.

Connect repos

To allow your redirects repo to automatically write to your website repo, you need to "connect" them with a deploy key:

  1. Generate an SSH key pair.
  2. In your redirects repo, create a new repository actions secret named DEPLOY_KEY, and paste the private SSH key as the value.
  3. In your website repo, create a new deploy key with write/push access named DEPLOY_KEY, and paste the public SSH key as the value.

Set up analytics

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 the 404.html page where marked (before the call to the redirect.js script) in your website repo.

Set up domain

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, as follows.

Note: If you do either of these, set baseurl = ""; in the redirect.js script in your website repo.

Custom domain

e.g. your-domain.com/some-link

Follow the instructions here. In summary:

  1. Purchase a domain name from a reputable service.
  2. 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.
  3. Set the custom domain field in the "Pages" settings of your website repo (automatically creates a CNAME file in the repo).
  4. After a minute or so, GitHub should tell you that your site is now being hosted at your-domain.com.

GitHub user/org site

e.g. your-org.github.io/some-link

  1. Name your website repo your-org.github.io to match your GitHub user/organization name.
  2. In your redirects repo, change redirects-website in deploy.yaml to the same name.

About GitHub user/org sites.

Tips

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 the redirect.js script, customize what fallback action happens when a user visits a URL that has no matching from redirect.
  • 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, e.g. your-domain.com with no /some-link.

Existing site

If you already have a website being hosted with GitHub Pages that you want to incorporate this approach into:

  1. Skip templating the website repo.
  2. Instead, copy the redirect.js script into the root of your existing website, and modify baseurl in it as appropriate.
  3. Run the redirect.js script from your 404 page in the same way it is done here. Note: If a redirect from has the same name/path of an existing page, the redirect won't happen since the user will just get that page instead of 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

  1. 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

  2. The analytics service you're using should be able to capture all its stats in time, before the redirection happens. Google Analytics has been tested and seems to work, but these services are usually closed source, so we can't say for certain that all services will work 100% correctly 100% of the time. ↩

  3. 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. ↩

About

No description, website, or topics provided.

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks