Why Your Redirects Should Live in Git

·5 min read

Every URL change ships with a silent assumption: someone will add the redirect later. Usually they do not. The URL changes, the redirect ticket sits in the backlog, and Google quietly starts crawling 404s. By the time Search Console surfaces it, the ranking signal has been leaking for weeks.

This is not a discipline problem. It is an architecture problem. When redirect config lives in a separate system from the code that changes URLs, the two will drift. Every time.

The fix is to put your redirects in the same place as everything else that changes URLs: your git repo.

What "redirects in git" actually means

It means a file — committed alongside your code — that defines every redirect your site needs. When a URL changes, the developer adds a line to the file in the same PR. The redirect and the URL change are reviewed together, merged together, and deployed together. They are never out of sync because they cannot be.

This is not a new idea. Netlify shipped _redirects in 2016. Vercel has vercel.json. Cloudflare Pages has its own _redirects support. Every major hosting platform eventually built this feature because it is the obviously correct way to manage redirects for code-driven sites.

The problem is that all of these are platform-native features. They work by having the hosting platform read the file at deploy time and configure its own CDN. If you are not on that platform, there is nothing to read the file.

What you actually get

When redirects are in git, a few things change:

The redirect is never an afterthought. The developer changing the URL is the same person who sees the redirectiq.json file in their editor. Adding the redirect entry is a one-line edit, done in the same context as the URL change.

Redirects get reviewed. PR review catches redirect errors the same way it catches code errors. Wrong destination, missing redirect for a high-traffic page, redirect chain that wasn't obvious — all visible in the diff before it merges.

The history is complete. git log redirectiq.json tells you every redirect that was ever added, when, and why (assuming reasonable commit messages). No separate audit trail to maintain.

Deploys are atomic. The URL change and the redirect land in the same deploy. There is no window where the new URL is live but the old one 404s — even for a minute.

The file format

We use redirectiq.json, a simple JSON file:

{
  "version": 1,
  "redirects": [
    { "from": "/old-blog-post", "to": "/blog/new-title", "type": "301" },
    { "from": "/docs/v1/*", "to": "/docs/v2/", "type": "301" },
    { "from": "/products/old-name", "to": "/products/new-name", "type": "301" }
  ]
}

Three fields per entry: source path, destination, redirect type. Wildcards and named parameters work the same as they do on Netlify. The file is served as a static asset from your domain and polled by RedirectIQ on a schedule.

This is deliberately not a compiled format, not a DSL, not a database record. It is a text file that any developer can read, edit, and review in a PR. The barrier to adding a redirect should be as low as possible — if it takes more than 30 seconds, it will get skipped.

Wiring it to your deploy pipeline

The file sitting in git is half the solution. The other half is having changes go live when the code deploys, not an hour later.

RedirectIQ supports a deploy webhook: a URL you call from your CI/CD pipeline after a successful deploy. When the webhook fires, RedirectIQ fetches your redirectiq.json immediately, diffs it against what is currently at the edge, and syncs any changes. The redirect is live in seconds, as part of the same pipeline run that deployed the URL change.

A one-line addition to your deploy script:

curl -X POST https://app.redirectiq.com/api/v1/domains/YOUR_DOMAIN_ID/sync-json \
  -H "Authorization: Bearer $REDIRECTIQ_API_KEY"

If you do not want to touch the pipeline at all, hourly polling also works. RedirectIQ checks the file once per hour and applies changes automatically. Less immediate, but zero CI changes required.

We use this on our own site

This site manages all its redirects via redirectiq.json. The file is live at redirectiq.com/redirectiq.json — you can inspect every redirect we have and see exactly what the file looks like in production.

One of the entries in that file is a redirect for a blog post we renamed during editing. The old slug and the new slug landed in the same commit. The redirect went live as part of the same deploy. No ticket, no dashboard, no gap between the URL change and the redirect being live.

That is the workflow in practice. One commit, one PR, redirect and content change together. See it described in detail in The _redirects File for Any Host.

How to set it up

1. Create redirectiq.json in your public assets directory and commit it to your repo

2. Deploy it — the file needs to be reachable at a public HTTPS URL on your domain

3. Add your domain to RedirectIQ and enable File Sync with the URL of your file

4. Add the deploy webhook call to your CI/CD pipeline (optional but recommended)

5. Start adding redirects to the file whenever you change a URL

The first time a developer adds a redirect in the same commit as the URL change — without filing a ticket, without switching tools — the workflow will feel obviously right. It is what this should have always looked like.

---

Want the full format reference? See the File Sync docs for the complete redirectiq.json spec, pathMappings for monorepos, and security model.