Repository navigation
feat(hacklytics2027): move the site from Next.js to Astro - #579
Conversation
The site is a static page with a handful of interactive spots, but the Next export shipped about 150 KB of gzipped JavaScript (React, the App Router runtime, an inlined RSC payload) to run them. Astro renders every section to HTML at build time and sends script only where a visitor can use it. What runs where: - Sections, sprites and the FAQ render at build time with no JS. - Navbar, theme toggle, countdown, bloom-on-scroll and the service worker registrar are small plain scripts. The theme icon follows the theme in CSS, so it is right on first paint, and the no-flash theme script stays an inline script in <head>. - The four flower beds are the only React: hero (client:idle), footer and 404 (client:visible), and the mobile menu (client:media below 1024px). Markup, copy, CSS, head tags, URLs, 404 page, sw.js and public files are unchanged. Astro writes to out/, so CI and Firebase need no change except the immutable-cache rule, which now matches /_astro/ instead of /_next/static/ (sw.js caches the same path cache-first). Astro 6 and @astrojs/react 5 rather than 7: the root package.json overrides vite to 7 for the whole repo and Astro 7 needs vite 8. typecheck is tsc --noEmit because astro check needs the TypeScript JS API, which TypeScript 7 does not ship.
Update the site reference and README for the new commands, folder layout and the per-piece hydration choices, and the repo-level docs that named the old framework.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit bfa254c. Configure here.
| <script> | ||
| import "../scripts/theme-toggle"; | ||
| </script> | ||
| {import.meta.env.PROD && <script>import "../scripts/service-worker";</script>} |
There was a problem hiding this comment.
Service worker script never bundles
High Severity
Wrapping the service-worker <script> in an import.meta.env.PROD expression leaves it unprocessed. Astro only bundles top-level <script> tags, so production HTML ships a classic script with a source import that throws and never calls register(). New visitors get no worker; the network-first page cache and offline fallback never install.
Reviewed by Cursor Bugbot for commit bfa254c. Configure here.
Dependency ReviewThe following issues were found:
|
astro below 7.2.8 allows remote code execution through AVIF image optimization, and 6.x has no patch. Move to astro 7.4.2 and @astrojs/react 7.1.1. Astro 7 needs vite 8, but the root override pins vite to ^7.3.7 to patch Dependabot alerts for every other workspace. Rather than lift that, two scoped overrides (astro>vite and @astrojs/react>vite, both 8.3.5) give vite 8 to the Astro site only. mainweb, packages and tooling still resolve vite 7.3.7.
mainweb sets reactCompiler: true, and Next resolves the compiler plugin from mainweb's own dependencies. mainweb never declared it; it resolved only because hacklytics2027 listed babel-plugin-react-compiler@1.0.0 and pnpm used it to satisfy next's optional peer for the whole workspace. Moving hacklytics2027 to Astro dropped that entry, and CI's clean install of web then failed: "Failed to resolve package babel-plugin-react-compiler while attempting to resolve React Compiler". Same version as before, so the compiled output is unchanged.
|
Visit the preview URL for this PR (updated for commit dc6e8fb): https://hacklytics2027--pr-579-815buvvh.web.app (expires Fri, 13 Nov 2026 16:12:40 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: c48ba34db61581e25fe2978355160b5eefe0e83f |
Activation deletes only cache names other than CACHE_VERSION, and it was still hacklytics-v4. A returning visitor kept the Next.js pages and /_next/static chunks cached under it, so an offline visit could render a cached shell that requests scripts the Astro build no longer has. v5 makes activation drop them.


hacklytics2027 is a static marketing site with no database. Next shipped its React runtime to render pages that are almost entirely static. Astro renders them at build time and hydrates only what needs a browser.
What changed
@astrojs/react7.1.1, Tailwind 4 through@tailwindcss/vite,outDir: "out"so CI and the Firebasehacklyticstarget are unchanged. Astro below 7.2.8 is affected by GHSA-26w7-cxv4-gfx2 (critical)."vite": "^7.3.7"override (fix(deps): bump vite to ^7.3.7 #505, a security pin for Dependabot alerts Drop the exports entry for the deleted http-security module #328-Sync dev from main #332) is unchanged; two selector overrides,"astro>vite"and"@astrojs/react>vite", give only this sitevite@8.3.5.pnpm why vite -r:@query/api, root, vitest and@vitest/mockerstill resolve 7.3.7; mainwebtypecheckandbuildpass.<head>, same string as before. Countdown is an inline script after the hero so it never paints "00".client:idle, footer and 404client:visible, mobile menuclient:media="(max-width: 1023px)".firebase.jsonimmutable-cache rule andsw.jscache-first path now match/_astro/instead of/_next/static/.typecheckistsc --noEmitoversrc/:astro checkcannot load TypeScript 7 (no JS API)..astrofiles are covered by the build.docs/sites/hacklytics2027.md, mentions indocs/architecture.md,docs/getting-started.md, root README.babel-plugin-react-compiler@1.0.0itself. It usesreactCompiler: truebut only ever resolved the plugin through hacklytics2027's entry; dropping that broke the web build on a clean install.Measurements
Lighthouse 12.6.1, alternating, mobile n=5, desktop n=3, median (range), busy machine.
Mobile FCP is within noise (1263 vs 1356 ms). Numbers above are from Astro 6; a 3-run mobile recheck on Astro 7 gave score 83 vs 95, LCP 3496 vs 2383 ms, TBT 329 vs 175 ms, script 151 vs 72 KB.
Parity
lib/links.ts, plant-a-flower, header hide on scroll, section offsets, mobile menu (aria, inert, body lock), theme toggle with persistence and no flash, 404 status, no overflow 320 to 1440, focus ring, zero console errors.<head>identical apart from the favicon cache-buster query and Next's chunk scripts being gone.pnpm turbo run lint typecheck build --filter=hacklytics2027passes.Not verified
Real Firebase
cleanUrlsand headers (the PR preview channel shows them), and service-worker behaviour across a deploy.Note
Medium Risk
Large framework swap plus new Vite 8 override paths affect build outputs and caching; regressions would surface as broken Firebase hosting or hydration gaps on the marketing site.
Overview
Summary
The Hacklytics 2027 marketing workspace drops the Next.js static-export stack for Astro 7 with
@astrojs/react,@tailwindcss/vite, and a matchingastro.config.mjsthat still outputs Firebase’sout/directory while only hydrating the React pixel beds.Operational updates
Monorepo docs (
README.md,docs/architecture.md,docs/getting-started.md,docs/sites/hacklytics2027.md,sites/hacklytics2027/README.md) now describe the Astro workflow, dev scripts, island strategy, and caching rules; Firebase Hosting serves/_astro/**immutably instead of/_next/static, andsites/hacklytics2027/.gitignore/.oxlintrcalign with Astro tooling.Dependencies & build tooling
Root
package.json/pnpm-lock.yamladd Astro + Vite 8 overrides (astro>vite,@astrojs/react>vite), uplift LightningCSS to 1.33 with yaml peer wiring, movebabel-plugin-react-compilerontosites/mainweb, and remove Next-specific deps fromhacklytics2027.Risk note
Verify Firebase preview headers/service-worker behavior with the new asset path and ensure CI picks up the dual Vite override cleanly across workspaces.
Reviewed by Cursor Bugbot for commit dc6e8fb. Bugbot is set up for automated code reviews on this repo. Configure here.