fix(home): per-request hostname for featured product; gate proto switcher#3
Conversation
- Disable prerender on / so data-featured and copy match the request host. - Use lowercase hostname for git-rain matching. - Show prototype switcher only in dev, on preview hosts, or ?proto=1; hide Domain row when host already implies rain. - Style testkit/harness section borders; remove CSS-only hide for proto bar. Made-with: Cursor
📝 WalkthroughWalkthroughAdded per-request rendering, case-insensitive hostname checks, request-aware proto query handling, and conditional proto-toggle UI rendering tied to environment and hostname; also added branded border styles and removed CSS-based hiding of the proto toggle. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
git-fire-website | f8ddff1 | Commit Preview URL Branch Preview URL |
Apr 16 2026, 09:39 AM |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Proto switcher disappears after clicking any link
- protoUrl now includes proto=1 when the request URL has proto=1 so switcher links keep the production opt-in.
Preview (c31e4ab13f)
diff --git a/src/pages/index.astro b/src/pages/index.astro
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,4 +1,7 @@
---
+/** Per-request hostname selects featured product — must not prerender to static HTML. */
+export const prerender = false;
+
import BaseLayout from '../layouts/BaseLayout.astro';
import LayoutCurrent from '../components/LayoutCurrent.astro';
import LayoutA from '../components/LayoutA.astro';
@@ -6,12 +9,26 @@
import LayoutC from '../components/LayoutC.astro';
const hostname = Astro.url.hostname;
+const hostLower = hostname.toLowerCase();
const featuredParam = Astro.url.searchParams.get('featured');
const layoutParam = Astro.url.searchParams.get('layout');
+const keepProtoQuery = Astro.url.searchParams.get('proto') === '1';
+/** Dev / preview only — hide on canonical and mirror marketing domains */
+const showProtoSwitcher =
+ import.meta.env.DEV ||
+ Astro.url.searchParams.get('proto') === '1' ||
+ hostLower === 'localhost' ||
+ hostLower.startsWith('127.') ||
+ hostLower.endsWith('.workers.dev') ||
+ hostLower.endsWith('.pages.dev');
+
+/** Hostname already selects rain; hide Domain row so the bar is not a second “tester” */
+const showProtoDomainGroup = showProtoSwitcher && !hostLower.includes('git-rain');
+
const featured: 'fire' | 'rain' = featuredParam === 'rain' ? 'rain'
: featuredParam === 'fire' ? 'fire'
- : hostname.includes('git-rain') ? 'rain'
+ : hostLower.includes('git-rain') ? 'rain'
: 'fire';
const layout: 'current' | 'a' | 'b' | 'c' = layoutParam === 'a' ? 'a'
@@ -27,6 +44,7 @@
function protoUrl(f: string, l: string): string {
const parts: string[] = [];
+ if (keepProtoQuery) parts.push('proto=1');
if (f !== 'fire') parts.push(`featured=${f}`);
if (l !== 'current') parts.push(`layout=${l}`);
return parts.length ? `?${parts.join('&')}` : '?';
@@ -39,21 +57,27 @@
{layout === 'c' && <LayoutC featured={featured} />}
{layout === 'current' && <LayoutCurrent featured={featured} />}
- <div class="proto-toggle" aria-label="Prototype switcher">
- <div class="proto-toggle__group">
- <span class="proto-toggle__label">Domain</span>
- <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': featured === 'fire' }]} href={protoUrl('fire', layout)}>fire.*</a>
- <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': featured === 'rain' }]} href={protoUrl('rain', layout)}>rain.*</a>
+ {showProtoSwitcher && (
+ <div class="proto-toggle" aria-label="Prototype switcher">
+ {showProtoDomainGroup && (
+ <>
+ <div class="proto-toggle__group">
+ <span class="proto-toggle__label">Domain</span>
+ <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': featured === 'fire' }]} href={protoUrl('fire', layout)}>fire.*</a>
+ <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': featured === 'rain' }]} href={protoUrl('rain', layout)}>rain.*</a>
+ </div>
+ <div class="proto-toggle__sep" aria-hidden="true"></div>
+ </>
+ )}
+ <div class="proto-toggle__group">
+ <span class="proto-toggle__label">Layout</span>
+ <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': layout === 'current' }]} href={protoUrl(featured, 'current')}>now</a>
+ <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': layout === 'a' }]} href={protoUrl(featured, 'a')}>A</a>
+ <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': layout === 'b' }]} href={protoUrl(featured, 'b')}>B</a>
+ <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': layout === 'c' }]} href={protoUrl(featured, 'c')}>C</a>
+ </div>
</div>
- <div class="proto-toggle__sep"></div>
- <div class="proto-toggle__group">
- <span class="proto-toggle__label">Layout</span>
- <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': layout === 'current' }]} href={protoUrl(featured, 'current')}>now</a>
- <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': layout === 'a' }]} href={protoUrl(featured, 'a')}>A</a>
- <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': layout === 'b' }]} href={protoUrl(featured, 'b')}>B</a>
- <a class:list={['proto-toggle__btn', { 'proto-toggle__btn--active': layout === 'c' }]} href={protoUrl(featured, 'c')}>C</a>
- </div>
- </div>
+ )}
<script>
import { initInstallPickers } from '../scripts/install-pickers.ts';
diff --git a/src/styles/global.css b/src/styles/global.css
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -381,6 +381,19 @@
scroll-margin-top: 5.5rem;
}
+/* Library sections — top stripe + tinted dividers (same tokens as .site-nav a[data-project]) */
+#testkit.section,
+#testkit.feature-row {
+ border-top: 3px solid var(--color-testkit);
+ border-bottom-color: color-mix(in srgb, var(--color-testkit) 45%, var(--color-border));
+}
+
+#harness.section,
+#harness.feature-row {
+ border-top: 3px solid var(--color-harness);
+ border-bottom-color: color-mix(in srgb, var(--color-harness) 45%, var(--color-border));
+}
+
.js [data-reveal] {
opacity: 0;
transform: translateY(14px);
@@ -804,9 +817,8 @@
.section--rich .wrap { grid-template-columns: 1fr; }
}
-/* Prototype switcher — hidden in production; re-enable by removing display:none */
+/* Prototype switcher — only rendered on dev/preview hosts (see index.astro); opt-in with ?proto=1 */
.proto-toggle {
- display: none;
position: fixed;
bottom: var(--space-lg);
left: 50%;You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit 78ac614. Configure here.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/pages/index.astro`:
- Around line 58-76: The switcher links drop the ?proto=1 flag because
protoUrl(...) doesn't preserve the current query param; update protoUrl to carry
through the proto=1 flag (or accept an options param) so every generated href
includes proto=1 when the current page request/query (or the showProtoSwitcher
state) indicates proto is enabled; locate uses of protoUrl in this file (and the
protoUrl function definition) and change protoUrl to read the current query or
an explicit boolean and append ?proto=1 (or merge into existing querystring) so
the anchors rendered for featured/layout keep proto=1.
🪄 Autofix (Beta)
❌ Autofix failed (check again to retry)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7785ae69-a939-4731-925f-2fe30a06c3ef
📒 Files selected for processing (2)
src/pages/index.astrosrc/styles/global.css
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found. |
Keep proto=1 on switcher links so layout/domain changes do not drop the bar. Made-with: Cursor
…it-fire/git-fire-website into fix/homepage-hostname-and-proto-toggle Made-with: Cursor
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/index.astro (1)
13-38:⚠️ Potential issue | 🟠 MajorGate the query overrides, not just the switcher UI.
featuredandlayoutstill honor?featured=/?layout=on every request. On canonical production hosts,/?layout=aor/?featured=rainwill still render prototype variants even though the switcher is hidden, and users have no visible way back. Please ignore those params unless the proto gate is enabled for the request.🔧 Proposed fix
const featuredParam = Astro.url.searchParams.get('featured'); const layoutParam = Astro.url.searchParams.get('layout'); const keepProtoQuery = Astro.url.searchParams.get('proto') === '1'; /** Dev / preview only — hide on canonical and mirror marketing domains */ const showProtoSwitcher = import.meta.env.DEV || - Astro.url.searchParams.get('proto') === '1' || + keepProtoQuery || hostLower === 'localhost' || hostLower.startsWith('127.') || hostLower.endsWith('.workers.dev') || hostLower.endsWith('.pages.dev'); /** Hostname already selects rain; hide Domain row so the bar is not a second “tester” */ const showProtoDomainGroup = showProtoSwitcher && !hostLower.includes('git-rain'); -const featured: 'fire' | 'rain' = featuredParam === 'rain' ? 'rain' - : featuredParam === 'fire' ? 'fire' +const featured: 'fire' | 'rain' = showProtoSwitcher && featuredParam === 'rain' ? 'rain' + : showProtoSwitcher && featuredParam === 'fire' ? 'fire' : hostLower.includes('git-rain') ? 'rain' : 'fire'; -const layout: 'current' | 'a' | 'b' | 'c' = layoutParam === 'a' ? 'a' - : layoutParam === 'b' ? 'b' - : layoutParam === 'c' ? 'c' - : layoutParam === 'current' ? 'current' +const layout: 'current' | 'a' | 'b' | 'c' = showProtoSwitcher && layoutParam === 'a' ? 'a' + : showProtoSwitcher && layoutParam === 'b' ? 'b' + : showProtoSwitcher && layoutParam === 'c' ? 'c' + : showProtoSwitcher && layoutParam === 'current' ? 'current' : 'b';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/index.astro` around lines 13 - 38, The query overrides for featured/layout must be ignored unless the proto gate is enabled for the request: update the featured and layout assignments so they only honor featuredParam and layoutParam when showProtoSwitcher (or keepProtoQuery) is true; otherwise derive values from hostLower/defaults as before. Concretely, change the ternary logic in the featured (symbol: featured, uses featuredParam) and layout (symbol: layout, uses layoutParam) initializers to first check showProtoSwitcher || keepProtoQuery before applying the query values, falling back to the host-based and default branches when that gate is false.
🧹 Nitpick comments (1)
src/pages/index.astro (1)
2-24: Make sure any HTML cache varies by host and proto params.This page now renders different HTML for the same path based on hostname and query string. If Cloudflare or any upstream cache keys only on
/, one variant can bleed across domains or prototype links. Please verify the cache key includes at leastHost,featured,layout, andprotobefore enabling edge caching.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/index.astro` around lines 2 - 24, This page renders different HTML per request based on hostname and query params (see prerender=false, hostname/hostLower, featuredParam, layoutParam, keepProtoQuery, showProtoSwitcher), so ensure any upstream/edge cache keys vary by Host and the featured/layout/proto query values; update the response caching policy to include a Vary header (or edge cache key) for Host and/or include featured, layout, proto in the cache key so variants cannot bleed across domains or proto toggles.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/pages/index.astro`:
- Around line 13-38: The query overrides for featured/layout must be ignored
unless the proto gate is enabled for the request: update the featured and layout
assignments so they only honor featuredParam and layoutParam when
showProtoSwitcher (or keepProtoQuery) is true; otherwise derive values from
hostLower/defaults as before. Concretely, change the ternary logic in the
featured (symbol: featured, uses featuredParam) and layout (symbol: layout, uses
layoutParam) initializers to first check showProtoSwitcher || keepProtoQuery
before applying the query values, falling back to the host-based and default
branches when that gate is false.
---
Nitpick comments:
In `@src/pages/index.astro`:
- Around line 2-24: This page renders different HTML per request based on
hostname and query params (see prerender=false, hostname/hostLower,
featuredParam, layoutParam, keepProtoQuery, showProtoSwitcher), so ensure any
upstream/edge cache keys vary by Host and the featured/layout/proto query
values; update the response caching policy to include a Vary header (or edge
cache key) for Host and/or include featured, layout, proto in the cache key so
variants cannot bleed across domains or proto toggles.
|
@cursor address the feedback from coderabbit |
|
Here is what changed in response to the CodeRabbit / Bugbot thread. Issue: On production, the bar only appears with Fix: Brought back the original visibility rules ( const featuredParam = Astro.url.searchParams.get('featured');
const layoutParam = Astro.url.searchParams.get('layout');
const protoGate = Astro.url.searchParams.get('proto') === '1';
/** Dev / preview, or production opt-in via ?proto=1 — hide on canonical marketing domains otherwise */
const showProtoSwitcher =
import.meta.env.DEV ||
protoGate ||
hostLower === 'localhost' ||
hostLower.startsWith('127.') ||
hostLower.endsWith('.workers.dev') ||
hostLower.endsWith('.pages.dev');
// ...
function protoUrl(f: string, l: string): string {
const params = new URLSearchParams();
if (f !== 'fire') params.set('featured', f);
if (l !== 'current') params.set('layout', l);
if (protoGate) params.set('proto', '1');
const qs = params.toString();
return qs ? `?${qs}` : '?';
}
|
CodeRabbit asked to carry proto=1 through protoUrl for production ?proto=1. Use URLSearchParams and only append proto when the request opted in. Re-show the switcher on localhost, 127.*, and Cloudflare preview hosts per the PR description, while still hiding it on canonical marketing domains. Co-authored-by: Ben Schellenberger <bschellenberger2600@users.noreply.github.com>



Summary
The home page was being prerendered to static HTML, so
Astro.url.hostnamewas evaluated at build time anddata-featuredwas alwaysfire. That broke git-rain-first ordering (hero cards, section order, navbar link order, and logo) ongit-rainmarketing domains.Changes
export const prerender = falseon/so Cloudflare serves HTML with the correctdata-featuredfor each host.git-rainusing a lowercased hostname..workers.dev,.pages.dev), or when?proto=1. On hosts that already imply rain, the Domain row is hidden so layout switching stays without duplicating domain simulation.display: noneon.proto-toggle.How to verify
wrangler devafter build: open/on agit-rainhostname and confirmgit-rainis first (cards + nav + sections) and canonical fire domains default to git-fire first.?proto=1on production to exercise the switcher when needed.Note
Medium Risk
Disables prerendering for
/, changing how the homepage is served/cached and making rendering depend on request hostname/query params; mistakes could cause inconsistent marketing content across domains.Overview
Fixes homepage host-specific featured-product selection by disabling prerendering on
/(export const prerender = false) and switching hostname checks to use a lowercased host (ensuringgit-raindomains render withrainfeatured at request time).Gates the prototype switcher so it only renders in dev/preview environments or when explicitly enabled via
?proto=1, preserves theprotoflag across switcher links, and hides the Domain toggle group ongit-rainhosts. Adds section accent styling for#testkit/#harnessand removes the CSS-based “hide proto bar in prod” approach since visibility is now controlled server-side.Reviewed by Cursor Bugbot for commit f8ddff1. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
Bug Fixes
Style