Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import code, {
AnalyticsOptions,
CustomHtmlOptions,
Custom404Options,
SubdomainRedirect,
} from "./code";
import "./styles.css";

Expand Down Expand Up @@ -163,6 +164,9 @@ export default function App() {
const [custom404, setCustom404] = useState<Custom404Options>({
notionUrl: "",
});
const [subdomainRedirects, setSubdomainRedirects] = useState<
SubdomainRedirect[]
>([]);

function createInputHandler<T>(
setter: React.Dispatch<React.SetStateAction<T>>,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -359,6 +389,7 @@ export default function App() {
analytics,
customHtml,
custom404,
subdomainRedirects,
};

const script = noError ? code(codeData) : undefined;
Expand Down Expand Up @@ -914,6 +945,81 @@ export default function App() {
/>
</Box>

<Box sx={{ mt: 3, pt: 2, borderTop: 1, borderColor: "grey.300" }}>
<Typography
variant="subtitle2"
color="text.secondary"
gutterBottom
>
Subdomain Redirects
</Typography>
<Typography variant="caption" color="text.secondary">
Redirect subdomains (e.g., www) to the main domain or other
URLs
</Typography>
{subdomainRedirects.map((redirect, index) => (
<Box
key={index}
sx={{
mt: 1,
p: 1.5,
backgroundColor: "grey.100",
borderRadius: 1,
}}
>
<Stack direction="row" spacing={1} alignItems="flex-start">
<TextField
label="Subdomain"
placeholder="www"
value={redirect.subdomain}
onChange={(e) =>
handleSubdomainRedirectChange(
index,
"subdomain",
e.target.value,
)
}
variant="outlined"
size="small"
sx={{ flex: 1 }}
/>
<TextField
label="Redirect URL"
placeholder={`https://${domain}`}
value={redirect.redirectUrl}
onChange={(e) =>
handleSubdomainRedirectChange(
index,
"redirectUrl",
e.target.value,
)
}
variant="outlined"
size="small"
sx={{ flex: 2 }}
/>
<Button
onClick={() => deleteSubdomainRedirect(index)}
color="error"
size="small"
sx={{ minWidth: "auto", px: 1 }}
>
<DeleteIcon fontSize="small" />
</Button>
</Stack>
</Box>
))}
<Button
onClick={addSubdomainRedirect}
size="small"
variant="text"
startIcon={<AddIcon />}
sx={{ mt: 1 }}
>
Add Redirect
</Button>
</Box>

<Box sx={{ mt: 3, pt: 2, borderTop: 1, borderColor: "grey.300" }}>
<Stack
direction="row"
Expand Down
35 changes: 35 additions & 0 deletions src/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ export interface Custom404Options {
notionUrl?: string;
}

export interface SubdomainRedirect {
subdomain: string;
redirectUrl: string;
}

export interface CodeData {
myDomain: string;
notionUrl: string;
Expand All @@ -58,6 +63,7 @@ export interface CodeData {
analytics: AnalyticsOptions;
customHtml: CustomHtmlOptions;
custom404: Custom404Options;
subdomainRedirects: SubdomainRedirect[];
}

function getId(url: string): string {
Expand Down Expand Up @@ -87,6 +93,7 @@ export default function code(data: CodeData): string {
analytics,
customHtml,
custom404,
subdomainRedirects,
} = data;
let url = myDomain.replace("https://", "").replace("http://", "");
if (url.slice(-1) === "/") url = url.slice(0, url.length - 1);
Expand Down Expand Up @@ -157,6 +164,18 @@ ${slugs
*/
const CUSTOM_404_PAGE_ID = '${custom404?.notionUrl ? getId(custom404.notionUrl) : ""}';

/*
* Step 3.7: subdomain redirect configuration (optional)
* Redirect subdomains (e.g., www) to the main domain or other URLs
*/
const SUBDOMAIN_REDIRECTS = {
${
subdomainRedirects
?.filter((r) => 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 || ""}';

Expand Down Expand Up @@ -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') {
Expand Down
Loading