From d62c3f026043a98ef2f3f16033400a8a0278230b Mon Sep 17 00:00:00 2001 From: Kevin Brown Date: Thu, 23 Apr 2026 03:38:04 +0300 Subject: [PATCH 1/2] Make marketing routes statically rendered --- _TODO.md | 56 ++++++++++++++++++++++++++++++ src/pages/about/index.astro | 2 ++ src/pages/articles/index.astro | 2 ++ src/pages/case-studies/index.astro | 2 ++ src/pages/consent/index.astro | 2 ++ src/pages/contact/index.astro | 2 ++ src/pages/index.astro | 2 ++ src/pages/newsletter/index.astro | 2 ++ src/pages/offline/index.astro | 2 ++ src/pages/privacy/index.astro | 2 ++ src/pages/privacy/my-data.astro | 2 ++ src/pages/resume/index.astro | 2 ++ src/pages/services/index.astro | 2 ++ src/pages/terms.astro | 2 ++ 14 files changed, 82 insertions(+) diff --git a/_TODO.md b/_TODO.md index dc577ea1..a61217a5 100644 --- a/_TODO.md +++ b/_TODO.md @@ -40,3 +40,59 @@ https://aws.plainenglish.io/how-to-build-a-chatbot-using-aws-lex-and-lambda-in-2 - Need to move the unsubscribe link into an Action and handle it entirely within our website instead of on Hubspot - Need to add a newsletter publishing workflow as an action, using the newsletter static segment imported from Hubspot + +## Performance Issues + +2. Treat `src/pages/resume/index.astro` as build-time content, not request-time content. That page should not be doing `getCollection()` plus `render()` on every request if the content is static. + +3. Audit the homepage hydration/chunk fan-out after prerendering. The 22 JS chunks suggest too much client code is shipping for a marketing landing page. + +4. Investigate why production `_astro` assets are getting `max-age=0, must-revalidate` instead of immutable caching. That looks like a deployment/adapter behavior issue worth fixing after the SSR problem. + +Routes that do not need to stay dynamic: + +### Search page + +One route that is dynamic now but probably does not need to be: + +/search +It is currently marked prerender = false in index.astro:2, but the UI is already client-driven. index.astro:8 reads q, and the real search happens through the action in action.ts:12. That means /search can very likely be a static shell page and let the client read window.location.search and call the action. So I would not keep this dynamic unless you specifically want SSR-rendered search results for SEO. + +### Tags page + +One caution: + +src/pages/tags/[tag].astro is prerendered but also reads ?page=. That is not a reason to keep it dynamic, but it is a sign that query-param pagination there may not be doing what you expect in a prerendered route. + +It's using page for plain old server-side pagination. + +In src/pages/tags/[tag].astro, the route sets ITEMS_PER_PAGE = 12, then reads the query param here: + +src/pages/tags/[tag].astro + + +const currentPage = parseInt(Astro.url.searchParams.get('page') || '1') +It uses that value to: + +Compute the slice boundaries: +src/pages/tags/[tag].astro + +const startIndex = (currentPage - 1) * ITEMS_PER_PAGEconst endIndex = startIndex + ITEMS_PER_PAGE +Slice the sorted articles for that tag: +src/pages/tags/[tag].astro + +const paginatedContent = sortedContent.slice(startIndex, endIndex) +Render the pagination UI and link targets: +src/pages/tags/[tag].astro +That block builds: + +Previous / Next +numbered page links +ellipsis when there are many pages +links like /tags/foo?page=2, /tags/foo?page=3, etc. +So the intent is: + +/tags/some-tag means page 1 +/tags/some-tag?page=2 means articles 13-24 +/tags/some-tag?page=3 means the next 12, and so on +One important caveat: this route is also marked prerendered in src/pages/tags/[tag].astro. That means the code is written like SSR pagination, but because the route is static, the page query param may not actually produce distinct server-rendered HTML at runtime. In other words, the code is trying to use ?page= to choose which slice to render, but prerendering makes that suspicious. diff --git a/src/pages/about/index.astro b/src/pages/about/index.astro index dc1664fa..2e6f9774 100644 --- a/src/pages/about/index.astro +++ b/src/pages/about/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import PageLayout from '@layouts/PageLayout.astro' import AboutPage from '@components/Pages/About/index.astro' diff --git a/src/pages/articles/index.astro b/src/pages/articles/index.astro index 147aeb16..90257605 100644 --- a/src/pages/articles/index.astro +++ b/src/pages/articles/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import { type CollectionEntry, getCollection } from 'astro:content' import { isDev } from '@lib/config/environmentServer' import PageLayout from '@layouts/PageLayout.astro' diff --git a/src/pages/case-studies/index.astro b/src/pages/case-studies/index.astro index 75f7106d..9bce83b9 100644 --- a/src/pages/case-studies/index.astro +++ b/src/pages/case-studies/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import { getCollection, getEntry } from 'astro:content' import { Picture } from 'astro:assets' import Icon from '@components/Icon/index.astro' diff --git a/src/pages/consent/index.astro b/src/pages/consent/index.astro index 72d8c7b8..c6993325 100644 --- a/src/pages/consent/index.astro +++ b/src/pages/consent/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import PageLayout from '@layouts/PageLayout.astro' import ConsentPreferences from '@components/Pages/Consent/index.astro' diff --git a/src/pages/contact/index.astro b/src/pages/contact/index.astro index f2f23326..6f250c71 100644 --- a/src/pages/contact/index.astro +++ b/src/pages/contact/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import { companyContactData } from '@lib/content/contactData' import PageLayout from '@layouts/PageLayout.astro' import ContactPage from '@components/Pages/Contact/index.astro' diff --git a/src/pages/index.astro b/src/pages/index.astro index 394d2661..555d507a 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import BaseLayout from '@layouts/BaseLayout.astro' import Backstage from '@components/Home/Backstage/index.astro' import Carousel from '@components/Carousel/index.astro' diff --git a/src/pages/newsletter/index.astro b/src/pages/newsletter/index.astro index 78a4f56a..da72e43d 100644 --- a/src/pages/newsletter/index.astro +++ b/src/pages/newsletter/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import PageLayout from '@layouts/PageLayout.astro' import Newsletter from '@components/Pages/Newsletter/Signup/index.astro' diff --git a/src/pages/offline/index.astro b/src/pages/offline/index.astro index 21761aa8..0b047ddb 100644 --- a/src/pages/offline/index.astro +++ b/src/pages/offline/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import PageLayout from '@layouts/PageLayout.astro' import NetworkStatus from '@components/Toasts/NetworkStatus/index.astro' import Offline from '@components/Pages/Offline/index.astro' diff --git a/src/pages/privacy/index.astro b/src/pages/privacy/index.astro index 3e621f4b..9cdb40c1 100644 --- a/src/pages/privacy/index.astro +++ b/src/pages/privacy/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import PageLayout from '@layouts/PageLayout.astro' import PrivacyLayout from '@components/Pages/Privacy/index.astro' diff --git a/src/pages/privacy/my-data.astro b/src/pages/privacy/my-data.astro index ba31e137..029a681f 100644 --- a/src/pages/privacy/my-data.astro +++ b/src/pages/privacy/my-data.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import PageLayout from '@layouts/PageLayout.astro' import PrivacyForm from '@components/Pages/MyData/index.astro' diff --git a/src/pages/resume/index.astro b/src/pages/resume/index.astro index d1ed64e2..0dea66cd 100644 --- a/src/pages/resume/index.astro +++ b/src/pages/resume/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import { getCollection, render } from 'astro:content' import Resume from '@components/Pages/Resume/index.astro' diff --git a/src/pages/services/index.astro b/src/pages/services/index.astro index 65e3c6f3..0e47fb6c 100644 --- a/src/pages/services/index.astro +++ b/src/pages/services/index.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import { getCollection } from 'astro:content' import PageLayout from '@layouts/PageLayout.astro' import ServicesPage from '@components/Pages/Services/index.astro' diff --git a/src/pages/terms.astro b/src/pages/terms.astro index 22ef449d..977cc103 100644 --- a/src/pages/terms.astro +++ b/src/pages/terms.astro @@ -1,4 +1,6 @@ --- +export const prerender = true + import PageLayout from '@layouts/PageLayout.astro' import TermsOfUsePage from '@components/Pages/TermsOfUse/index.astro' From 0c930552c8c6e1e134a2e5ede42c8910f8c45de9 Mon Sep 17 00:00:00 2001 From: Kevin Brown Date: Thu, 23 Apr 2026 03:42:30 +0300 Subject: [PATCH 2/2] Fix Resume scoped CSS issue --- _TODO.md | 7 +------ src/components/Pages/Resume/index.astro | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/_TODO.md b/_TODO.md index a61217a5..41fe37f3 100644 --- a/_TODO.md +++ b/_TODO.md @@ -43,19 +43,14 @@ https://aws.plainenglish.io/how-to-build-a-chatbot-using-aws-lex-and-lambda-in-2 ## Performance Issues -2. Treat `src/pages/resume/index.astro` as build-time content, not request-time content. That page should not be doing `getCollection()` plus `render()` on every request if the content is static. - 3. Audit the homepage hydration/chunk fan-out after prerendering. The 22 JS chunks suggest too much client code is shipping for a marketing landing page. -4. Investigate why production `_astro` assets are getting `max-age=0, must-revalidate` instead of immutable caching. That looks like a deployment/adapter behavior issue worth fixing after the SSR problem. - -Routes that do not need to stay dynamic: - ### Search page One route that is dynamic now but probably does not need to be: /search + It is currently marked prerender = false in index.astro:2, but the UI is already client-driven. index.astro:8 reads q, and the real search happens through the action in action.ts:12. That means /search can very likely be a static shell page and let the client read window.location.search and call the action. So I would not keep this dynamic unless you specifically want SSR-rendered search results for SEO. ### Tags page diff --git a/src/components/Pages/Resume/index.astro b/src/components/Pages/Resume/index.astro index 5e1e8cef..b29381a9 100644 --- a/src/components/Pages/Resume/index.astro +++ b/src/components/Pages/Resume/index.astro @@ -104,7 +104,7 @@ const {