utilization reduction

This commit is contained in:
2026-09-22 16:38:43 -04:00
parent f3e9cdf0bd
commit bef8f8414b
31 changed files with 133 additions and 5 deletions

View File

@@ -1,9 +1,21 @@
User-agent: * User-agent: *
Allow: / Allow: /
Allow: /blog Allow: /blog
Allow: /projects
Disallow: /login # Private / dynamic paths — not for indexing.
Disallow: /debug/ # Keeps crawlers off auth, admin, and API pages so they don't burn
# uncached SSR function invocations.
Disallow: /account
Disallow: /analytics
Disallow: /api/
Disallow: /blog/create
Disallow: /blog/edit
Disallow: /checkout
Disallow: /databaseMGMT Disallow: /databaseMGMT
Disallow: /debug/
Disallow: /error-test
Disallow: /login
Disallow: /success
Disallow: /test
Sitemap: https://www.freno.me/sitemap.xml Sitemap: https://www.freno.me/sitemap.xml

View File

@@ -0,0 +1,29 @@
import { HttpHeader } from "@solidjs/start";
/**
* Renders edge-cache response headers for a page route.
*
* Sets `CDN-Cache-Control` so Vercel serves the rendered HTML from the edge
* (no origin re-render) for `maxAge` seconds, then stale-while-revalidate up
* to `staleSeconds`. `Cache-Control: public, max-age=0` keeps browsers
* revalidating, so visitors always get the latest version — only the CDN
* holds a cached copy. Function/CND-Cache-Control overrides the Vercel
* default, so repeated visits and bot crawls stop re-rendering at origin.
*/
export function EdgeCacheHeaders(props: {
/** Seconds the CDN may serve the response fresh. */
maxAge: number;
/** Seconds the CDN serves stale while revalidating (default: 1 day). */
staleSeconds?: number;
}) {
const stale = props.staleSeconds ?? 86400;
return (
<>
<HttpHeader name="Cache-Control" value="public, max-age=0" />
<HttpHeader
name="CDN-Cache-Control"
value={`public, s-maxage=${props.maxAge}, stale-while-revalidate=${stale}`}
/>
</>
);
}

View File

@@ -1,5 +1,5 @@
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { HttpStatusCode } from "@solidjs/start"; import { HttpHeader, HttpStatusCode } from "@solidjs/start";
import { useLocation, useNavigate } from "@solidjs/router"; import { useLocation, useNavigate } from "@solidjs/router";
import { createSignal, onCleanup, onMount, Show } from "solid-js"; import { createSignal, onCleanup, onMount, Show } from "solid-js";
import { TerminalErrorPage } from "~/components/TerminalErrorPage"; import { TerminalErrorPage } from "~/components/TerminalErrorPage";
@@ -90,6 +90,14 @@ export default function NotFound() {
description="404 - Page not found. The page you're looking for doesn't exist." description="404 - Page not found. The page you're looking for doesn't exist."
/> />
<HttpStatusCode code={404} /> <HttpStatusCode code={404} />
{/* Cache 404/fallback responses at the edge (Vercel caches 404s) so
bots/monitors that probe dead paths don't re-render the full page
on every request. Function headers override vercel.json here. */}
<HttpHeader name="Cache-Control" value="public, max-age=0" />
<HttpHeader
name="CDN-Cache-Control"
value="public, s-maxage=300, stale-while-revalidate=86400"
/>
<TerminalErrorPage <TerminalErrorPage
errorContent={errorContent} errorContent={errorContent}
quickActions={quickActions} quickActions={quickActions}

23
src/routes/api/health.ts Normal file
View File

@@ -0,0 +1,23 @@
import type { APIEvent } from "@solidjs/start/server";
/**
* Lightweight uptime/monitoring probe.
*
* Returns a tiny 200 that the edge CDN caches (`CDN-Cache-Control`), so
* health checks (Sentry uptime monitors, external monitors, `curl`) cost a
* fraction of a rendered page instead of a full SSR response. Point monitors
* at `https://freno.me/api/health`.
*/
export async function GET(_event: APIEvent) {
return new Response(JSON.stringify({ status: "ok" }), {
status: 200,
headers: {
"Content-Type": "application/json; charset=utf-8",
// Browser: always revalidate (tiny body, no reason to cache).
"Cache-Control": "public, max-age=0",
// Edge CDN: serve from cache for 1 min, then stale-while-revalidate
// for a day so repeated probe hits never touch the origin.
"CDN-Cache-Control": "public, s-maxage=60, stale-while-revalidate=86400"
}
});
}

View File

@@ -7,6 +7,7 @@ import {
useSearchParams useSearchParams
} from "@solidjs/router"; } from "@solidjs/router";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import { createAsync } from "@solidjs/router"; import { createAsync } from "@solidjs/router";
import { getRequestEvent } from "solid-js/web"; import { getRequestEvent } from "solid-js/web";
import AuthenticatedLike from "~/components/blog/AuthenticatedLike"; import AuthenticatedLike from "~/components/blog/AuthenticatedLike";
@@ -327,6 +328,7 @@ export default function PostPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={60} staleSeconds={3600} />
<PageHead <PageHead
title={p().title.replaceAll("_", " ")} title={p().title.replaceAll("_", " ")}
description={ description={

View File

@@ -1,6 +1,7 @@
import { Show } from "solid-js"; import { Show } from "solid-js";
import { useSearchParams, A, query } from "@solidjs/router"; import { useSearchParams, A, query } from "@solidjs/router";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import { createAsync } from "@solidjs/router"; import { createAsync } from "@solidjs/router";
import PostSortingSelect from "~/components/blog/PostSortingSelect"; import PostSortingSelect from "~/components/blog/PostSortingSelect";
import TagSelector from "~/components/blog/TagSelector"; import TagSelector from "~/components/blog/TagSelector";
@@ -90,6 +91,7 @@ export default function BlogIndex() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={60} staleSeconds={3600} />
<PageHead <PageHead
title="Blog" title="Blog"
description="Technical blog posts about web development, programming, and software engineering." description="Technical blog posts about web development, programming, and software engineering."

View File

@@ -3,6 +3,7 @@ import { useSearchParams } from "@solidjs/router";
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import RevealDropDown from "~/components/RevealDropDown"; import RevealDropDown from "~/components/RevealDropDown";
import { ContactForm } from "~/components/ContactForm"; import { ContactForm } from "~/components/ContactForm";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import { buildSubdomainUrl } from "~/lib/site-context"; import { buildSubdomainUrl } from "~/lib/site-context";
import { useSite } from "~/context/SiteContext"; import { useSite } from "~/context/SiteContext";
import NessaContactPage from "./nessa/contact"; import NessaContactPage from "./nessa/contact";
@@ -125,6 +126,8 @@ function MainContactPage() {
const viewer = () => searchParams.viewer ?? "default"; const viewer = () => searchParams.viewer ?? "default";
return ( return (
<>
<EdgeCacheHeaders maxAge={60} staleSeconds={3600} />
<ContactForm <ContactForm
subline={ subline={
<Show when={viewer() !== "lineage"}> <Show when={viewer() !== "lineage"}>
@@ -134,6 +137,7 @@ function MainContactPage() {
> >
<LineageContactQuestions /> <LineageContactQuestions />
</ContactForm> </ContactForm>
</>
); );
} }

View File

@@ -1,4 +1,5 @@
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { createSignal, onMount, onCleanup, Switch, Match } from "solid-js"; import { createSignal, onMount, onCleanup, Switch, Match } from "solid-js";
import DownloadOnAppStore from "~/components/icons/DownloadOnAppStore"; import DownloadOnAppStore from "~/components/icons/DownloadOnAppStore";
@@ -71,6 +72,7 @@ function MainDownloadsPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Downloads" title="Downloads"
description="Download The Nook, InputHalo, Gaze, Life and Lineage, Shapes with Abigail, and Cork. Available on macOS, iOS, and Android." description="Download The Nook, InputHalo, Gaze, Life and Lineage, Shapes with Abigail, and Cork. Available on macOS, iOS, and Android."

View File

@@ -1,4 +1,5 @@
import { ContactForm } from "~/components/ContactForm"; import { ContactForm } from "~/components/ContactForm";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
/** /**
@@ -19,6 +20,7 @@ import SubdomainHeader from "~/components/SubdomainHeader";
export default function GazeContactPage() { export default function GazeContactPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={60} staleSeconds={3600} />
<SubdomainHeader /> <SubdomainHeader />
<ContactForm /> <ContactForm />
</> </>

View File

@@ -11,6 +11,7 @@
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { createSignal } from "solid-js"; import { createSignal } from "solid-js";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark"; import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark";
import Button from "~/components/ui/Button"; import Button from "~/components/ui/Button";
@@ -48,6 +49,7 @@ export default function GazeDownloadsPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Download Gaze" title="Download Gaze"
description="Download Gaze for macOS — menu bar app for eye and posture health." description="Download Gaze for macOS — menu bar app for eye and posture health."

View File

@@ -1,5 +1,6 @@
import { createSignal, For } from "solid-js"; import { createSignal, For } from "solid-js";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark"; import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark";
import Button from "~/components/ui/Button"; import Button from "~/components/ui/Button";
@@ -60,6 +61,7 @@ export default function GazeLanding() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Home" title="Home"
description="Gaze is a macOS menu bar app for eye and posture health — blink reminders, 20-20-20 breaks, posture check-ins, and customizable reminder intervals." description="Gaze is a macOS menu bar app for eye and posture health — blink reminders, 20-20-20 breaks, posture check-ins, and customizable reminder intervals."

View File

@@ -15,11 +15,13 @@
*/ */
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
export default function GazePrivacyPolicy() { export default function GazePrivacyPolicy() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Privacy Policy" title="Privacy Policy"
description="Privacy policy for Gaze, a macOS eye health reminder app." description="Privacy policy for Gaze, a macOS eye health reminder app."

View File

@@ -1,5 +1,6 @@
import { Switch, Match, type JSX } from "solid-js"; import { Switch, Match, type JSX } from "solid-js";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import { DarkModeToggle } from "~/components/DarkModeToggle"; import { DarkModeToggle } from "~/components/DarkModeToggle";
import { Typewriter } from "~/components/Typewriter"; import { Typewriter } from "~/components/Typewriter";
import { useSite } from "~/context/SiteContext"; import { useSite } from "~/context/SiteContext";
@@ -57,6 +58,7 @@ export default function Home(): JSX.Element {
function MainHome(): JSX.Element { function MainHome(): JSX.Element {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Home" title="Home"
description="Michael Freno - Software Engineer based in Brooklyn, NY" description="Michael Freno - Software Engineer based in Brooklyn, NY"

View File

@@ -1,4 +1,5 @@
import { ContactForm } from "~/components/ContactForm"; import { ContactForm } from "~/components/ContactForm";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
/** /**
@@ -19,6 +20,7 @@ import SubdomainHeader from "~/components/SubdomainHeader";
export default function InputHaloContactPage() { export default function InputHaloContactPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={60} staleSeconds={3600} />
<SubdomainHeader /> <SubdomainHeader />
<ContactForm /> <ContactForm />
</> </>

View File

@@ -11,6 +11,7 @@
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { createSignal } from "solid-js"; import { createSignal } from "solid-js";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark"; import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark";
import Button from "~/components/ui/Button"; import Button from "~/components/ui/Button";
@@ -51,6 +52,7 @@ export default function InputHaloDownloadsPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Download InputHalo" title="Download InputHalo"
description="Download InputHalo for macOS — menu bar app for keyboard, mouse, and scroll visualization." description="Download InputHalo for macOS — menu bar app for keyboard, mouse, and scroll visualization."

View File

@@ -13,6 +13,7 @@
import { For, createSignal } from "solid-js"; import { For, createSignal } from "solid-js";
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import Button from "~/components/ui/Button"; import Button from "~/components/ui/Button";
import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark"; import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark";
@@ -98,6 +99,7 @@ export default function InputHaloLanding() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Home" title="Home"
description="A polished macOS menu bar app that visualizes keyboard presses, mouse clicks, cursor halos, and scroll events on screen — for streamers, presenters, and developers." description="A polished macOS menu bar app that visualizes keyboard presses, mouse clicks, cursor halos, and scroll events on screen — for streamers, presenters, and developers."

View File

@@ -23,11 +23,13 @@
*/ */
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
export default function InputHaloPrivacyPolicy() { export default function InputHaloPrivacyPolicy() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Privacy Policy" title="Privacy Policy"
description="Privacy policy for InputHalo, a macOS menu bar productivity app." description="Privacy policy for InputHalo, a macOS menu bar productivity app."

View File

@@ -1,4 +1,5 @@
import { ContactForm } from "~/components/ContactForm"; import { ContactForm } from "~/components/ContactForm";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import { LineageContactQuestions } from "../contact"; import { LineageContactQuestions } from "../contact";
@@ -24,6 +25,7 @@ import { LineageContactQuestions } from "../contact";
export default function LineageContactPage() { export default function LineageContactPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={60} staleSeconds={3600} />
<SubdomainHeader /> <SubdomainHeader />
<ContactForm> <ContactForm>
<LineageContactQuestions /> <LineageContactQuestions />

View File

@@ -33,6 +33,7 @@
* the form posts to the correct tRPC mutation (Lineage-branded email). * the form posts to the correct tRPC mutation (Lineage-branded email).
*/ */
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import DeletionForm from "~/components/DeletionForm"; import DeletionForm from "~/components/DeletionForm";
import { import {
@@ -45,6 +46,7 @@ import {
export default function LineageDeletionPage() { export default function LineageDeletionPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead title={PAGE_META.title} description={PAGE_META.description} /> <PageHead title={PAGE_META.title} description={PAGE_META.description} />
<SubdomainHeader /> <SubdomainHeader />
<div class="pt-20"> <div class="pt-20">

View File

@@ -30,6 +30,7 @@
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { createSignal, onMount, onCleanup } from "solid-js"; import { createSignal, onMount, onCleanup } from "solid-js";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import DownloadOnAppStore from "~/components/icons/DownloadOnAppStore"; import DownloadOnAppStore from "~/components/icons/DownloadOnAppStore";
import Button from "~/components/ui/Button"; import Button from "~/components/ui/Button";
@@ -71,6 +72,7 @@ export default function LineageDownloadsPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead title={PAGE_META.title} description={PAGE_META.description} /> <PageHead title={PAGE_META.title} description={PAGE_META.description} />
<SubdomainHeader /> <SubdomainHeader />

View File

@@ -11,6 +11,7 @@
*/ */
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import SimpleParallax from "~/components/SimpleParallax"; import SimpleParallax from "~/components/SimpleParallax";
import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark"; import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark";
@@ -25,6 +26,7 @@ import {
export default function LineageLandingPage() { export default function LineageLandingPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead title={PAGE_META.title} description={PAGE_META.description} /> <PageHead title={PAGE_META.title} description={PAGE_META.description} />
<SubdomainHeader /> <SubdomainHeader />
<SimpleParallax> <SimpleParallax>

View File

@@ -17,11 +17,13 @@
*/ */
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
export default function LineagePrivacyPolicy() { export default function LineagePrivacyPolicy() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Privacy Policy" title="Privacy Policy"
description="Privacy policy for Life and Lineage mobile game, outlining data collection, usage, and user rights." description="Privacy policy for Life and Lineage mobile game, outlining data collection, usage, and user rights."

View File

@@ -1,4 +1,5 @@
import { ContactForm } from "~/components/ContactForm"; import { ContactForm } from "~/components/ContactForm";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
/** /**
@@ -20,6 +21,7 @@ import SubdomainHeader from "~/components/SubdomainHeader";
export default function NessaContactPage() { export default function NessaContactPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={60} staleSeconds={3600} />
<SubdomainHeader /> <SubdomainHeader />
<ContactForm /> <ContactForm />
</> </>

View File

@@ -24,6 +24,7 @@
* Acceptance: `nessa.localhost:3000/deletion` renders the deletion form. * Acceptance: `nessa.localhost:3000/deletion` renders the deletion form.
*/ */
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import DeletionForm from "~/components/DeletionForm"; import DeletionForm from "~/components/DeletionForm";
import { import {
@@ -36,6 +37,7 @@ import {
export default function NessaDeletionPage() { export default function NessaDeletionPage() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead title={PAGE_META.title} description={PAGE_META.description} /> <PageHead title={PAGE_META.title} description={PAGE_META.description} />
<SubdomainHeader /> <SubdomainHeader />
<div class="pt-20"> <div class="pt-20">

View File

@@ -12,6 +12,7 @@
*/ */
import { For, Show } from "solid-js"; import { For, Show } from "solid-js";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import { useDarkMode } from "~/context/darkMode"; import { useDarkMode } from "~/context/darkMode";
import { useSite } from "~/context/SiteContext"; import { useSite } from "~/context/SiteContext";
@@ -59,6 +60,7 @@ export default function NessaLanding() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead {...NESSA_LANDING_META} /> <PageHead {...NESSA_LANDING_META} />
<SubdomainHeader /> <SubdomainHeader />

View File

@@ -29,11 +29,13 @@
*/ */
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
export default function NessaPrivacyPolicy() { export default function NessaPrivacyPolicy() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Privacy Policy" title="Privacy Policy"
description="Privacy policy for Nessa, a community platform for clubs, challenges, and social features." description="Privacy policy for Nessa, a community platform for clubs, challenges, and social features."

View File

@@ -1,4 +1,5 @@
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
import FeatureCollage from "~/components/nook/FeatureCollage"; import FeatureCollage from "~/components/nook/FeatureCollage";
import FeatureBreakdowns from "~/components/nook/FeatureBreakdowns"; import FeatureBreakdowns from "~/components/nook/FeatureBreakdowns";
@@ -57,6 +58,7 @@ export default function NookLanding() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Home" title="Home"
description="The Nook — a native macOS utility for coding-agent orchestration, fan and thermal control." description="The Nook — a native macOS utility for coding-agent orchestration, fan and thermal control."

View File

@@ -7,11 +7,13 @@
*/ */
import { buildMainSiteUrl } from "~/lib/subdomain-url"; import { buildMainSiteUrl } from "~/lib/subdomain-url";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader"; import SubdomainHeader from "~/components/SubdomainHeader";
export default function NookPrivacyPolicy() { export default function NookPrivacyPolicy() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Privacy Policy" title="Privacy Policy"
description="Privacy policy for The Nook, a coding-agent orchestration and hardware control app." description="Privacy policy for The Nook, a coding-agent orchestration and hardware control app."

View File

@@ -1,5 +1,6 @@
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
/** /**
* Main-site privacy policy — `freno.me/privacy-policy`. * Main-site privacy policy — `freno.me/privacy-policy`.
@@ -14,6 +15,7 @@ import { PageHead } from "~/components/PageHead";
export default function PrivacyPolicy() { export default function PrivacyPolicy() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Privacy Policy" title="Privacy Policy"
description="Privacy policy for the freno.me blog and personal site, covering accounts, comments, and contact forms." description="Privacy policy for the freno.me blog and personal site, covering accounts, comments, and contact forms."

View File

@@ -1,9 +1,11 @@
import { A } from "@solidjs/router"; import { A } from "@solidjs/router";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
export default function PrivacyPolicy() { export default function PrivacyPolicy() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Privacy Policy - Shapes with Abigail" title="Privacy Policy - Shapes with Abigail"
description="Privacy policy for Shapes with Abigail app, explaining our commitment to child safety and non-collection of personal data." description="Privacy policy for Shapes with Abigail app, explaining our commitment to child safety and non-collection of personal data."

View File

@@ -1,5 +1,6 @@
import { onCleanup, onMount } from "solid-js"; import { onCleanup, onMount } from "solid-js";
import { PageHead } from "~/components/PageHead"; import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
export default function Resume() { export default function Resume() {
let iframeRef: HTMLIFrameElement | undefined; let iframeRef: HTMLIFrameElement | undefined;
@@ -25,6 +26,7 @@ export default function Resume() {
return ( return (
<> <>
<EdgeCacheHeaders maxAge={300} />
<PageHead <PageHead
title="Resume" title="Resume"
description="View Michael Freno's resume - Software Engineer." description="View Michael Freno's resume - Software Engineer."