Skip to content

Commit e51caa3

Browse files
committed
feat: redirect vp-setup.void.app to setup.viteplus.dev
Add global Void middleware that 301-redirects requests on the default `vp-setup.void.app` host to the canonical custom domain `setup.viteplus.dev`, preserving path and query. Other hosts (custom domain, localhost, preview subdomains) pass through untouched.
1 parent dce6cef commit e51caa3

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { defineMiddleware } from "void";
2+
3+
const LEGACY_HOST = "vp-setup.void.app";
4+
const CANONICAL_ORIGIN = "https://setup.viteplus.dev";
5+
6+
export function buildRedirectTarget(host: string | undefined, requestUrl: string): string | null {
7+
if (host !== LEGACY_HOST) return null;
8+
const url = new URL(requestUrl);
9+
return `${CANONICAL_ORIGIN}${url.pathname}${url.search}`;
10+
}
11+
12+
export default defineMiddleware(async (c, next) => {
13+
const target = buildRedirectTarget(c.req.header("host"), c.req.url);
14+
if (target) return c.redirect(target, 301);
15+
await next();
16+
});

tests/redirect.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { describe, expect, it } from "vite-plus/test";
2+
import { buildRedirectTarget } from "../middleware/01.redirect-to-custom-domain";
3+
4+
describe("buildRedirectTarget", () => {
5+
it("redirects legacy host root to canonical origin", () => {
6+
expect(buildRedirectTarget("vp-setup.void.app", "https://vp-setup.void.app/")).toBe(
7+
"https://setup.viteplus.dev/",
8+
);
9+
});
10+
11+
it("preserves path and query string", () => {
12+
expect(
13+
buildRedirectTarget("vp-setup.void.app", "https://vp-setup.void.app/?tag=v1.2.3&arch=arm64"),
14+
).toBe("https://setup.viteplus.dev/?tag=v1.2.3&arch=arm64");
15+
});
16+
17+
it("returns null for the custom domain (no redirect)", () => {
18+
expect(buildRedirectTarget("setup.viteplus.dev", "https://setup.viteplus.dev/")).toBeNull();
19+
});
20+
21+
it("returns null for localhost during dev", () => {
22+
expect(buildRedirectTarget("localhost:5173", "http://localhost:5173/")).toBeNull();
23+
});
24+
25+
it("returns null when host header is missing", () => {
26+
expect(buildRedirectTarget(undefined, "https://vp-setup.void.app/")).toBeNull();
27+
});
28+
29+
it("does not match preview/staging subdomains", () => {
30+
expect(
31+
buildRedirectTarget("vp-setup-staging.void.app", "https://vp-setup-staging.void.app/"),
32+
).toBeNull();
33+
});
34+
});

0 commit comments

Comments
 (0)