diff --git a/src/App.tsx b/src/App.tsx index cd89bbb..5b744ab 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -45,6 +45,7 @@ import code, { AnalyticsOptions, CustomHtmlOptions, Custom404Options, + SubdomainRedirect, } from "./code"; import "./styles.css"; @@ -163,6 +164,9 @@ export default function App() { const [custom404, setCustom404] = useState({ notionUrl: "", }); + const [subdomainRedirects, setSubdomainRedirects] = useState< + SubdomainRedirect[] + >([]); function createInputHandler( setter: React.Dispatch>, @@ -294,6 +298,32 @@ export default function App() { setCopied(false); } + function addSubdomainRedirect(): void { + setSubdomainRedirects([ + ...subdomainRedirects, + { subdomain: "", redirectUrl: "" }, + ]); + setCopied(false); + } + + function deleteSubdomainRedirect(index: number): void { + setSubdomainRedirects(subdomainRedirects.filter((_, i) => i !== index)); + setCopied(false); + } + + function handleSubdomainRedirectChange( + index: number, + field: keyof SubdomainRedirect, + value: string, + ): void { + setSubdomainRedirects( + subdomainRedirects.map((redirect, i) => + i === index ? { ...redirect, [field]: value } : redirect, + ), + ); + setCopied(false); + } + function toggleSlugMetadata(index: number): void { setSlugMetadataExpanded({ ...slugMetadataExpanded, @@ -359,6 +389,7 @@ export default function App() { analytics, customHtml, custom404, + subdomainRedirects, }; const script = noError ? code(codeData) : undefined; @@ -914,6 +945,81 @@ export default function App() { /> + + + Subdomain Redirects + + + Redirect subdomains (e.g., www) to the main domain or other + URLs + + {subdomainRedirects.map((redirect, index) => ( + + + + handleSubdomainRedirectChange( + index, + "subdomain", + e.target.value, + ) + } + variant="outlined" + size="small" + sx={{ flex: 1 }} + /> + + handleSubdomainRedirectChange( + index, + "redirectUrl", + e.target.value, + ) + } + variant="outlined" + size="small" + sx={{ flex: 2 }} + /> + + + + ))} + + + r.subdomain && r.redirectUrl) + .map((r) => ` '${r.subdomain}': '${r.redirectUrl}',\n`) + .join("") || "" +} }; + /* Step 4: enter a Google Font name, you can choose from https://fonts.google.com */ const GOOGLE_FONT = '${googleFont || ""}'; @@ -276,6 +295,22 @@ ${slugs return handleOptions(request); } let url = new URL(request.url); + + // Handle subdomain redirects (Issue #15) + const hostname = url.hostname; + const domainParts = MY_DOMAIN.split('.'); + const hostParts = hostname.split('.'); + // Check if the request is for a subdomain of the main domain + if (hostParts.length > domainParts.length) { + const subdomain = hostParts.slice(0, hostParts.length - domainParts.length).join('.'); + const mainDomainFromHost = hostParts.slice(hostParts.length - domainParts.length).join('.'); + if (mainDomainFromHost === MY_DOMAIN && SUBDOMAIN_REDIRECTS[subdomain]) { + const redirectBase = SUBDOMAIN_REDIRECTS[subdomain]; + const redirectUrl = redirectBase + url.pathname + url.search; + return Response.redirect(redirectUrl, 301); + } + } + // Use the original Notion site domain instead of www.notion.so url.hostname = NOTION_SITE_DOMAIN; if (url.pathname === '/robots.txt') {