Serve the app on app.qrmaster.net, marketing on www
Splits the two hostnames across one deployment. No files move: the Next app still serves every route on both hosts, and the middleware decides per host which paths it owns and 301s the rest. /login and /signup stay on www - all 82 marketing CTAs point at /signup, which carries a hard canonical to www plus ad traffic. src/lib/hosts.ts is the single source of truth for the boundary (APP_PATH_PREFIXES, isAppPath, wwwUrl, appUrl, urlForPath). The middleware and every absolute-URL builder read from it so they cannot drift apart. - Split the overloaded NEXT_PUBLIC_APP_URL into a www and an app origin. It previously fed both public URLs and in-app URLs, so any single value was wrong somewhere. Most important: QRCodeCard encodes this origin into the QR code the user downloads and prints, so it must stay on www. - Route Stripe return URLs, email links and OAuth redirects per path rather than against one origin, so /dashboard lands on app and /pricing on www. - Cross the host boundary once, after a successful login: the router cannot push across origins, so that jump needs a full load. The user arrives signed in because the session cookie is scoped to COOKIE_DOMAIN. - Keep the app host out of search indexes: X-Robots-Tag on every response plus a Disallow-all robots.txt via rewrite, and /sitemap.xml redirects to www. - Point the TikTok callback fallback at www explicitly. It used to read NEXT_PUBLIC_APP_URL, whose meaning changed here, and only the apex domain is verified with TikTok. Host splitting is inert while both origins are equal, so development is unaffected. Verified: tsc clean, production build succeeds including the Edge middleware bundle, and the path-to-host mapping is unit-checked (prefix traps like /created and /settings-guide stay on www, query strings do not break matching). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
// These landing pages (/vcard, /display, /coupon, /feedback) are public marketing-host
|
||||
// pages reached straight from a scanned QR code - never the app host.
|
||||
import { getWwwOrigin } from '@/lib/hosts';
|
||||
import { db } from '@/lib/db';
|
||||
import { hashIP } from '@/lib/hash';
|
||||
import { triggerLifecycleScoring } from '@/lib/revops-server';
|
||||
@@ -47,7 +50,7 @@ export async function GET(
|
||||
break;
|
||||
case 'VCARD':
|
||||
// For vCard, redirect to display page
|
||||
const baseUrlVcard = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3050';
|
||||
const baseUrlVcard = getWwwOrigin();
|
||||
destination = `${baseUrlVcard}/vcard?firstName=${encodeURIComponent(content.firstName || '')}&lastName=${encodeURIComponent(content.lastName || '')}&email=${encodeURIComponent(content.email || '')}&phone=${encodeURIComponent(content.phone || '')}&organization=${encodeURIComponent(content.organization || '')}&title=${encodeURIComponent(content.title || '')}`;
|
||||
break;
|
||||
case 'GEO':
|
||||
@@ -58,7 +61,7 @@ export async function GET(
|
||||
break;
|
||||
case 'TEXT':
|
||||
// For plain text, redirect to a display page
|
||||
const baseUrlText = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3050';
|
||||
const baseUrlText = getWwwOrigin();
|
||||
destination = `${baseUrlText}/display?text=${encodeURIComponent(content.text || '')}`;
|
||||
break;
|
||||
case 'PDF':
|
||||
@@ -81,12 +84,12 @@ export async function GET(
|
||||
break;
|
||||
case 'COUPON':
|
||||
// Redirect to coupon display page
|
||||
const baseUrlCoupon = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3050';
|
||||
const baseUrlCoupon = getWwwOrigin();
|
||||
destination = `${baseUrlCoupon}/coupon/${slug}`;
|
||||
break;
|
||||
case 'FEEDBACK':
|
||||
// Redirect to feedback form page
|
||||
const baseUrlFeedback = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3050';
|
||||
const baseUrlFeedback = getWwwOrigin();
|
||||
destination = `${baseUrlFeedback}/feedback/${slug}`;
|
||||
break;
|
||||
case 'BARCODE':
|
||||
|
||||
Reference in New Issue
Block a user