A lightweight Nitro.js application that redirects all incoming requests to a specified target URL. Built with Nitro.
- Features
- Quick Start
- Configuration
- Docker Usage
- Local Development
- Production Deployment
- Testing
- Releasing
- Redirects every request to one configured target
- Configurable redirect status code: 301, 302, 303, 307 or 308
- Keeps the requested path and query string, with an optional base path on the target
- Validates its configuration at startup and refuses to start if it is invalid
- Available as a Docker image
docker run -d \
-e REDIRECT_TARGET=example.com \
-e REDIRECT_STATUS_CODE=301 \
-p 3000:3000 \
piscis/nitro-web-redirect:latest# Clone the repository
git clone https://github.com/piscis/nitro-web-redirect.git
cd nitro-web-redirect
# Install dependencies (using pnpm, the recommended package manager)
pnpm install
# Configure environment variables
echo 'REDIRECT_TARGET=example.com' > .env
# Start the server
pnpm run devConfigure the application using environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
REDIRECT_TARGET |
Yes | - | The redirect target: a host, optionally with a protocol and a base path |
REDIRECT_STATUS_CODE |
No | 301 | The redirect status code: one of 301, 302, 303, 307, 308 |
The configuration is checked once when the server starts. On success it logs the configuration it serves:
ℹ Redirecting to https://example.com with 301
If the configuration is invalid, the server logs the reason and exits with code 1 instead of starting:
REDIRECT_TARGETis missing, empty, or the stringundefinedornull.REDIRECT_STATUS_CODEis set to anything other than301,302,303,307or308(for example200,404orabc). An empty value counts as unset and gives301.
ERROR Invalid configuration: REDIRECT_STATUS_CODE "abc" is not one of 301, 302, 303, 307, 308
Each redirect is logged as one line, e.g. 301 GET /foo?x=1 → https://example.com/foo?x=1.
Every request is answered with a redirect to the target followed by the requested path and query string:
- Protocol: the target has a protocol only if it starts with
http://orhttps://. Otherwise the request's protocol is used, honouring theX-Forwarded-Protoheader set by a reverse proxy. A host such ashttpbin.orgcounts as having no protocol. - Trailing slashes on the target are trimmed, so
https://example.com/and/foogivehttps://example.com/foo. - Base path: a path in the target is placed in front of the requested path, so
https://example.com/baseand/foo?x=1givehttps://example.com/base/foo?x=1. - Path and query of the request are kept unchanged, including percent-encoding.
REDIRECT_TARGET |
Request | Location |
|---|---|---|
https://example.com |
http://redirect.local/foo?x=1 |
https://example.com/foo?x=1 |
example.com |
http://redirect.local/foo |
http://example.com/foo |
example.com |
/foo with X-Forwarded-Proto: https |
https://example.com/foo |
https://example.com/ |
/foo |
https://example.com/foo |
https://example.com/base |
/foo?x=1 |
https://example.com/base/foo?x=1 |
# Redirect to example.com with the same protocol as the request
REDIRECT_TARGET='example.com'
# Redirect to example.com with HTTPS protocol regardless of request protocol
REDIRECT_TARGET='https://example.com'
# Redirect into a base path on the target
REDIRECT_TARGET='https://example.com/base'
# Use a temporary redirect (302) instead of permanent (301)
REDIRECT_STATUS_CODE=302The official Docker image is available on Docker Hub:
docker pull piscis/nitro-web-redirect:latestdocker run -d \
-e REDIRECT_TARGET=example.com \
-e REDIRECT_STATUS_CODE=301 \
-p 3000:3000 \
piscis/nitro-web-redirect:latest# Build the image
docker build -t nitro-web-redirect .
# Run the container
docker run -d \
-e REDIRECT_TARGET=example.com \
-p 3000:3000 \
nitro-web-redirectversion: '3'
services:
redirect:
image: piscis/nitro-web-redirect:latest
environment:
REDIRECT_TARGET: example.com
REDIRECT_STATUS_CODE: 301
ports:
- '3000:3000'
restart: unless-stopped- Node.js 24 (see
.nvmrc) - pnpm 12.11.2 (pinned in
package.json;corepack enablepicks it up)
# Install dependencies
pnpm install
# Start development server
pnpm run devThe development server will be available at http://localhost:3000
pnpm run dev- Start development serverpnpm run build- Build for productionpnpm run preview- Preview production build locallypnpm run lint- Run lintingpnpm run test- Run tests in watch modepnpm run test:run- Run tests once
pnpm run buildpnpm startFor more deployment options, see the Nitro deployment documentation.
Run the test suite:
pnpm run test:runUnit tests in test/unit/ cover the configuration and location rules without a server. The tests in test/e2e/ build the server and send requests to it in-process with nitro-test-utils; each file runs one configuration, because the server reads it once at startup.
Versions come from the conventional-commit titles on main: pnpm release writes CHANGELOG.md and bumps package.json on a release branch, a v* tag creates the release, and the GitHub mirror publishes the image to Docker Hub after a smoke test. The steps are in docs/agents/releasing.md.