Lightweight GitHub Pages URL shortener powered by GitHub Actions.
- Minimal inside and out: no templates, no layouts, no code
- Uses only built-in GitHub Pages features (powered by Jekyll) and first-party actions
- Easy setup: add
pndurette/gh-pages-url-shortener-action
to a worflow, createurls.yml
See How it works.
-
Create new GitHub repository
- For example:
<your account>/url-shortener
- For example:
-
Enable GitHub Pages (
<new repo>
> Settings > Pages)- Source: GitHub Actions
-
[Optional] Configure custom domain
-
Create a new GitHub Actions workflow:
.github/workflows/deploy.yml
(This is GitHub's own GitHub Pages Jekyll starter workflow with
actions/jekyll-build-page
swapped for this action).See Configuration below for action inputs.
name: Deploy URL Shortener on: # Runs on pushes targeting the default branch push: branches: [main] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: contents: read pages: write id-token: write # Allow one concurrent deployment concurrency: group: "pages" cancel-in-progress: true jobs: # Build job build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Pages uses: actions/configure-pages@v3 - name: Generate URL Shortener uses: pndurette/gh-pages-url-shortener-action@v2 - name: Upload artifact uses: actions/upload-pages-artifact@v3 # Deployment job deploy: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest needs: build steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4
-
Create a URL redirect configuration file:
.github/urls.yml
Each
<key>
will be the path redirecting to a url<value>
. For example:--- abc: "https://google.com" def: "https://yahoo.com" uvw/xyz: "https://some-other-site.com" # The <key> can be a path
Will generate the following links:
http://<your site>/abc
will redirect tohttps://google.com
http://<your site>/def
will redirect tohttps://yahoo.com
http://<your site>/uvw/xyz
will redirect tohttps://some-other-site.com
-
Push to
main
(watch the action run summary for more info!)
Input | Description | Default | Required |
---|---|---|---|
urls_config |
The path to a YAML file associating redirect keys to URLs, e.g.: --- |
.github/urls.yml |
no |
default_redirect |
Default behaviour for |
Nothing here! |
no |
All the logic is shared between a Jekyll _config.yml
and the action itself in action.yml
.
Jekyll Collections
Each URL to redirect is created by the action as an individual document defined in a Collection:
# _config.yml
collections:
redirects:
output: true
permalink: /:path
The above reads: "In _redirects
(Jekyll's convention), generate one file per document (output: true
) for which the final URL path will be /:path
(i.e. path to the file, including the file, minus the extension)"
For example, for an entry link1: "https://google.com"
in urls.yml
, the action would create _redirect/link1.yml
as:
---
redirect_to: https://google.com
---
The jekyll-redirect-from
plugin
The redirect_to
front matter variable is provided by the jekyll-redirect-from plugin, which is whitelisted by GitHub Pages:
# _config.yml
plugins:
- "jekyll-redirect-from"
The plugin will generate an HTML file per Collection document, with every possible client-side way to redirect a url. The _redirect/link1.yml
file above would be generated by Jekyll to link1.html
as:
<!DOCTYPE html>
<html lang="en-US">
<meta charset="utf-8">
<title>Redirecting…</title>
<link rel="canonical" href="https://google.com">
<script>location="https://google.com"</script>
<meta http-equiv="refresh" content="0; url=https://google.com">
<meta name="robots" content="noindex">
<h1>Redirecting…</h1>
<a href="https://google.com">Click here if you are not redirected.</a>
</html>
Allowing it to be reached at https://<site>/link1
. It does the same for the index.html
and 404.hml
(for /
or non-existing path, respetively), which can also be redirects (absolute or relative to the domain) or plain strings (default is Nothing here!
).
The composite action in action.yml
reads urls.yml
and translates it to individual per-URL .md
file. It will then call the official actions/jekyll-build-pages
action to generate the content. It also shows a table summary of what was generated.
The generated file hierarchy is minimal. For instance, for a urls.yml
that might contain:
---
abc: "https://google.com"
def: "https://yahoo.com"
uvw/xyz: "https://some-other-site.com"
The action will generate (if the action input default_redirect
is set to a URL):
.
├── 404.md
├── _config.yml
├── _redirects
│ ├── abc.md
│ ├── def.md
│ └── uvw
| └── xyz.md
└── index.md
And the GitHub Pages-hosted directory will look like:
.
├── 404.html
├── abc.html
├── def.html
├── index.html
├── redirects.json
└── uvw
└── xyx.html
The MIT License (MIT) Copyright © 2023-2024 Pierre Nicolas Durette