initial commit

This commit is contained in:
Josh Bairstow 2026-06-01 19:35:56 +10:00
commit 3ba76b4f02
90 changed files with 12507 additions and 0 deletions

53
src/lib/urls.ts Normal file
View file

@ -0,0 +1,53 @@
// Cross-subdomain URL helpers.
//
// In production, joshbairstow.com (apex), blog., art., and code. are all served from
// the same Astro build via the reverse proxy mapping host -> path prefix (see
// docs/planning.md §6.2). Internal navigation between subdomains must use absolute
// URLs so the browser actually swaps hosts; same-subdomain links can stay relative.
//
// In dev (a single localhost), the absolute hostnames don't resolve, so we collapse
// everything to relative paths against the path-prefix layout.
const PROD_APEX = "https://joshbairstow.com";
const SUBDOMAIN_HOSTS: Record<string, string> = {
apex: PROD_APEX,
blog: "https://blog.joshbairstow.com",
art: "https://art.joshbairstow.com",
code: "https://code.joshbairstow.com",
};
const SUBDOMAIN_PATH_PREFIXES: Record<string, string> = {
apex: "/",
blog: "/blog/",
art: "/art/",
code: "/code/",
};
export type Subdomain = keyof typeof SUBDOMAIN_HOSTS;
const isProd = import.meta.env.PROD;
/**
* Build a URL on a given subdomain. Use this for top-nav links and any
* cross-subdomain reference so the apex layout works whether viewed at the
* apex or at a subdomain.
*
* In dev, returns a relative path (so localhost works). In prod, returns an
* absolute https URL (so the reverse proxy can route by host).
*/
export function url(subdomain: Subdomain, path: string = "/"): string {
const normalized = path.startsWith("/") ? path : `/${path}`;
if (isProd) {
return `${SUBDOMAIN_HOSTS[subdomain]}${normalized === "/" ? "" : normalized}`;
}
const prefix = SUBDOMAIN_PATH_PREFIXES[subdomain];
if (normalized === "/") return prefix;
return `${prefix.replace(/\/$/, "")}${normalized}`;
}
// Convenience shortcuts so authors don't memorize the function signature.
export const home = (path: string = "/") => url("apex", path);
export const blog = (path: string = "/") => url("blog", path);
export const art = (path: string = "/") => url("art", path);
export const code = (path: string = "/") => url("code", path);