diff --git a/app/(app)/domains/[id]/page.tsx b/app/(app)/domains/[id]/page.tsx index 6fb2cc3..06f3bb0 100644 --- a/app/(app)/domains/[id]/page.tsx +++ b/app/(app)/domains/[id]/page.tsx @@ -59,7 +59,10 @@ export default async function DomainDetailPage({ params }: { params: Promise<{ i ) : "—"} {group && {group.name}} - {domain.redirect_code} + + {domain.redirect_code} + {domain.redirect_code === 301 && ⚠} + {domain.preserve_path ? "ja" : "nein"} {domain.include_www ? "ja" : "nein"} {domain.verified_at ? new Date(domain.verified_at).toLocaleString("de-DE") : "—"} diff --git a/app/(app)/domains/new/page.tsx b/app/(app)/domains/new/page.tsx index f82d890..ec2025f 100644 --- a/app/(app)/domains/new/page.tsx +++ b/app/(app)/domains/new/page.tsx @@ -31,7 +31,7 @@ export default function NewDomainPage() { const [targetMode, setTargetMode] = useState<"url" | "group">("url"); const [targetUrl, setTargetUrl] = useState(""); const [groupId, setGroupId] = useState(""); - const [redirectCode, setRedirectCode] = useState<301 | 302>(301); + const [redirectCode, setRedirectCode] = useState<301 | 302>(302); const [preservePath, setPreservePath] = useState(true); const [includeWww, setIncludeWww] = useState(true); const [groups, setGroups] = useState([]); @@ -152,9 +152,14 @@ export default function NewDomainPage() { onChange={(e) => setRedirectCode(Number(e.target.value) as 301 | 302)} className="flex h-9 w-full rounded-md border border-input bg-zinc-950 px-3 py-1 text-sm text-zinc-100" > + 302 Temporär (empfohlen) 301 Permanent - 302 Temporär + {redirectCode === 301 && ( + + ⚠ 301 wird vom Browser gecacht — Folge-Aufrufe gehen direkt zum Ziel ohne hier gezählt zu werden. + + )} diff --git a/app/(app)/groups/page.tsx b/app/(app)/groups/page.tsx index 3cf6e90..ebf2a67 100644 --- a/app/(app)/groups/page.tsx +++ b/app/(app)/groups/page.tsx @@ -17,7 +17,7 @@ export default function GroupsPage() { const [open, setOpen] = useState(false); const [name, setName] = useState(""); const [targetUrl, setTargetUrl] = useState(""); - const [code, setCode] = useState<301 | 302>(301); + const [code, setCode] = useState<301 | 302>(302); const [creating, setCreating] = useState(false); const [error, setError] = useState(""); @@ -90,9 +90,12 @@ export default function GroupsPage() { Status-Code setCode(Number(e.target.value) as 301 | 302)} className="flex h-9 w-full rounded-md border border-input bg-zinc-950 px-3 py-1 text-sm text-zinc-100"> + 302 Temporär (empfohlen) 301 Permanent - 302 Temporär + {code === 301 && ( + ⚠ 301 wird vom Browser gecacht — Hits gehen verloren. + )} {error && {error}} diff --git a/lib/db.ts b/lib/db.ts index f19ee4b..38e94fb 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -33,7 +33,7 @@ function ensureSchema(db: Database.Database) { id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, target_url TEXT NOT NULL, - redirect_code INTEGER NOT NULL DEFAULT 301, + redirect_code INTEGER NOT NULL DEFAULT 302, created_by INTEGER REFERENCES users(id), created_at INTEGER NOT NULL ); @@ -44,7 +44,7 @@ function ensureSchema(db: Database.Database) { status TEXT NOT NULL DEFAULT 'pending', target_url TEXT, group_id INTEGER REFERENCES domain_groups(id) ON DELETE SET NULL, - redirect_code INTEGER NOT NULL DEFAULT 301, + redirect_code INTEGER NOT NULL DEFAULT 302, preserve_path INTEGER NOT NULL DEFAULT 1, include_www INTEGER NOT NULL DEFAULT 1, created_by INTEGER REFERENCES users(id), diff --git a/package.json b/package.json index e872a03..55b7f95 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "corex-nexredirect", - "version": "0.1.5", + "version": "0.1.6", "license": "MIT", "scripts": { "dev": "tsx watch server.ts", diff --git a/server.ts b/server.ts index e9cbd27..2416ec4 100644 --- a/server.ts +++ b/server.ts @@ -41,7 +41,13 @@ app.prepare().then(() => { const target = resolved.preserve_path ? resolved.target_url + (parsedUrl.path || "") : resolved.target_url; - res.writeHead(resolved.redirect_code || 301, { Location: target }); + res.writeHead(resolved.redirect_code || 302, { + Location: target, + // Forbid caching so every hit reaches us for analytics. + "Cache-Control": "no-store, no-cache, must-revalidate, max-age=0", + Pragma: "no-cache", + Expires: "0", + }); res.end(); return; }
+ ⚠ 301 wird vom Browser gecacht — Folge-Aufrufe gehen direkt zum Ziel ohne hier gezählt zu werden. +
⚠ 301 wird vom Browser gecacht — Hits gehen verloren.
{error}