prelo
Plugins / Redirect manager

Redirect manager

301s editable in Studio, enforced at the edge on deploy.

Agithub.com/anderdigitalInfrastructureprelo >= 0.5Updated Jun 2026Official
Use this plugin
1
2
or point your agent at the spec:
Your agent reads the spec and writes the code into your project. Review the diff like any change.

What this adds

A redirects table the site owner edits in Studio — old path, new path, 301 or 302 — without touching config files. On deploy the redirects are compiled into whatever your host enforces at the edge (Vercel config, Netlify _redirects, or the one-process server itself), so moved pages keep their link equity and nobody sees a 404.

How it works

Redirects are just a content type, so the generic Studio gives you the editing UI for free. A build-time step fetches the published redirects from the content API and writes them into the host's redirect format; publishing a redirect triggers the publish webhook, which triggers a redeploy.

The spec your agent followsexpand ▾
You are adding managed redirects to a Prelo project.

1. **Content type.** In `cms.config.js`:

   ```js
   redirect: {
     label: "Redirects",
     fields: {
       from: { type: "text", required: true },   // path, must start with /
       to:   { type: "text", required: true },   // path or absolute URL
       code: { type: "select", options: ["301", "302"], required: true },
       note: { type: "text" },
     },
     studio: { columns: ["from", "to", "code"] },
   },
   ```

   A redirect is live when published, off when draft — that gives the owner an on/off switch with no extra field.

2. **Fetch helper.** A small server-side helper `getRedirects()`: `GET {CMS_URL}/api/redirect?per_page=200` (paginate), returning `{from, to, code}` for published entries. Validate each: `from` starts with `/`, `to` is a path or http(s) URL, and `from !== to`; skip and warn on invalid rows. Detect and warn on duplicate `from` values (first one wins).

3. **Enforcement — pick what matches the deployment** (ask the user or read the repo):
   - **Vercel frontend:** generate the `redirects` array in `next.config` at build time (`async redirects()` calling `getRedirects()`), mapping `code` 301→`permanent: true`.
   - **Netlify:** a prebuild script writing `_redirects` lines (`{from} {to} {code}`) into the publish dir.
   - **One-process Prelo site (`web/site.js`):** check the redirect list at the top of `handle(url)` and return `{ status: 301/302, redirect: to }` if the site module supports it — otherwise emit an HTML meta-refresh page with the proper status. Cache the list in memory for 60 seconds; don't hit the db per request.
   - **Caddy/nginx self-host:** a deploy-time script writing a `redirects.caddy` / map file that the main server config imports.

4. **Redeploy on change.** Set `webhooks: { onPublish: "<deploy-hook-url>" }` in `cms.config.js` for static hosts so publishing a redirect rebuilds. For the one-process/self-host paths this is unnecessary (60-second cache).

5. **Safety rails.** Never allow a redirect from `/` (would loop the homepage into whatever someone types), from `/studio`, `/api`, or `/uploads` paths, or a chain longer than one hop you can detect (if `to` equals another redirect's `from`, warn at build time). Enforce in the fetch helper, not just docs.

6. **Verify.** Publish a test redirect in Studio, deploy (or wait out the cache), `curl -I` the old path and confirm the status code and `Location` header. Unpublish and confirm it stops.

After it's built

The owner manages redirects entirely in Studio: add a row when a page moves, publish it, done. Draft = disabled. The note field is theirs for "why does this exist" archaeology.