HTTP 301/302 redirect service for waigant.com QR codes and short links.
Short URLs like link.waigant.com/album260101 redirect to their configured target — OneDrive, iCloud, or any other URL — with a configurable status code. Change the targets by editing redirects.yaml in this repository and pushing to main.
edit redirects.yaml → push to main → GitHub Actions builds HTML → GitHub Pages deploys it
There are no committed HTML files. Every push to main triggers a GitHub Actions workflow that:
redirects.yaml (the single source of truth).python3 generate.py to produce <path>.html files in the workflow workspace.link.waigant.com site.You never run generate.py by hand in normal use — the workflow does it. You only need Python + PyYAML locally if you want to preview the generated HTML before pushing.
redirects.yaml in any text editor.Add a new entry:
my-new-link:
url: "https://example.com/target"
status: 302 # optional, default 302
desc: "Short description" # optional
Commit and push:
git add redirects.yaml
git commit -m "Add my-new-link → https://example.com/target"
git push
my-new-link.html, and deploys it.https://link.waigant.com/my-new-link to confirm.That’s it. No HTML files to generate, no build commands to run, no Pages settings to touch.
Update: change the url (or status, desc) for the matching key in redirects.yaml, commit, and push. The workflow regenerates the HTML with the new target.
Remove: delete the key from redirects.yaml, commit, and push. The corresponding .html file is no longer generated, so the path returns a GitHub Pages 404.
redirects.yaml is a YAML document. Each top-level key is a short path (lowercase, hyphens OK), and its value is a mapping with up to three fields.
| Field | Required | Default | Description |
|---|---|---|---|
url |
yes | — | Absolute target URL, must start with https:// (or http://). |
status |
no | 302 | 301 = permanent, 302/307 = temporary. This is the intended HTTP status; the HTML uses meta refresh + JS, so the actual status observed by clients is the HTML redirect behavior, not a true server header. |
desc |
no | same as url |
Human-readable label shown on the intermediate page and as the page title. |
# redirects.yaml
album260101:
url: "https://1drv.ms/x/aBcDeFgH"
status: 302
desc: "Family album 2026-01"
album260102:
url: "https://icloud.com/sharedalbum/photo"
status: 302
desc: "iCloud shared album — summer trip"
permanent-link:
url: "https://waigant.com/about"
status: 301
desc: "About page — permanent"
YAML is more readable than JSON for this — no commas, no braces, comments are allowed (lines starting with #).
link.waigant.com/album260101.link.waigant.com.album260101.html (generated by the workflow from redirects.yaml).<meta http-equiv="refresh"> and a window.location.replace() that take the browser to the target URL.Because this uses generated static HTML (not server-side redirects), the site works on GitHub Pages’ CDN worldwide with zero server configuration. The only configuration is the redirects.yaml file.
meta refresh + JavaScript. Most browsers and QR-code-launched browsers follow the redirect immediately, but some strict HTTP clients (curl without -L, some API callers) may not see a true 301/302. For QR codes opened by mobile browsers this is not a problem. If you need true server-side redirect headers (e.g. for search engines, API clients, or link validators), use a server-side redirect on a VPS, Cloudflare Workers, or Netlify instead of this static-site approach.summer-camp-2026. Avoid spaces, Unicode, special characters.redirects.yaml, it takes up to ~2 minutes for the new redirect to be live. This is not an on-the-fly lookup — it’s a static site that’s rebuilt on each push. That’s fine for QR codes (the URL embedded in a QR code is fixed) but means you can’t use this as a dynamic router for arbitrary paths.The site is deployed by the GitHub Actions workflow in .github/workflows/deploy.yml, not by the legacy “Deploy from a branch” mode. This means:
redirects.yaml and push to main.The custom domain link.waigant.com is set via the CNAME file in the repo and the Pages environment in GitHub Actions. HTTPS is enforced.
You need access to the waigant.com DNS zone. This repository cannot create DNS records for you. Follow the steps below in your DNS admin console.
Two records at link.waigant.com:
Option A — CNAME (if link.waigant.com is a subdomain, not the apex of the zone):
Type: CNAME
Name: link
Value: waigant.github.io
TTL: 3600 (or default)
Option B — ALIAS / ANAME (if your DNS provider supports it at the apex):
Type: ALIAS / ANAME
Name: link (or @ for apex)
Value: waigant.github.io
Option C — A records (if your provider only does A records and you’re at the apex):
Type: A
Name: @
Values: 185.199.108.153, 185.199.109.153, 185.199.110.153, 185.199.111.153
After creating the record, wait for propagation (from seconds to hours depending on TTL), then verify:
dig link.waigant.com CNAME +short
# Should show waigant.github.io
dig link.waigant.com A +short
# Should show 185.199.108.153 et al. if using A records
Once DNS resolves, GitHub Pages issues a TLS certificate automatically (up to 24 hours). The site is then live at https://link.waigant.com/album260101.
ERR_NAME_NOT_RESOLVED — record hasn’t propagated or name is misspelled. Check in your DNS admin console and wait. Lower TTL to 300 temporarily for faster iteration.SSL_ERROR — GitHub Pages hasn’t issued the certificate yet. Make sure the domain is in the CNAME file and DNS points correctly. Certificate issuance can take up to 24 hours.404 — Pages is serving the site but the <path>.html file doesn’t exist. Check that you pushed redirects.yaml and that the GitHub Actions workflow completed successfully (check the Actions tab).If you want to preview the generated HTML before pushing:
# Install pyyaml if not present
pip install pyyaml
# Generate the HTML files in the repo root
python3 generate.py
# Open one in your browser
open album260101.html
This writes <path>.html files next to redirects.yaml. Do not commit these files — they are generated artifacts. The workflow produces them at deploy time. If you do run generate.py locally, delete the .html files before committing, or use git clean -fX *.html to remove them.
To avoid accidentally committing generated HTML files, the .gitignore in this repo already ignores the patterns that generate.py produces. If you ever need to scrub them:
git clean -fX *.html
| File / directory | Purpose |
|---|---|
redirects.yaml |
Source of truth — defines all redirects. Edit this. |
generate.py |
Reads redirects.yaml, writes <path>.html files. Used by the workflow and optionally locally. |
.github/workflows/deploy.yml |
GitHub Actions workflow — builds HTML from redirects.yaml and deploys to Pages on every push to main. |
CNAME |
Contains link.waigant.com — tells GitHub Pages which custom domain to use. |
README.md |
This file. |
AGENTS.md |
Instructions for AI agents working in this repo. |
.gitignore |
Ignores generated HTML, Python artifacts, IDE files, OS files. |
That’s the whole repo. There are no committed HTML files, no build scripts to run by hand, and no Pages settings to manage — just edit redirects.yaml and push.
This redirect service is provided as-is for personal use. The code in this repository (generate.py, deploy.yml, README, AGENTS.md) is free to reuse under the MIT License. The redirect target URLs themselves are controlled by whoever holds the waigant.com domain.