Skip to content

Comments

feat(web): enable prerender for static pages to improve TTFB#2048

Merged
yujonglee merged 3 commits intomainfrom
devin/1764582750-enable-prerender
Dec 1, 2025
Merged

feat(web): enable prerender for static pages to improve TTFB#2048
yujonglee merged 3 commits intomainfrom
devin/1764582750-enable-prerender

Conversation

@yujonglee
Copy link
Contributor

@yujonglee yujonglee commented Dec 1, 2025

Summary

Enables prerendering for static marketing/docs/blog pages to improve TTFB (Time To First Byte). Currently all requests go through Netlify Functions for SSR, causing cold start latency (400-900ms+ TTFB). With prerender enabled, static pages will be served directly from CDN.

Changes:

  • Set prerender.enabled to true in TanStack Start config
  • Added homepage (/) to the prerender filter
  • Added /enterprise to the prerender filter
  • Added skipValidation for env vars in CI to allow prerender to complete without server secrets

Pages that will be prerendered: /, /blog/*, /docs/*, /changelog/*, /legal/*, /product/*, /pricing, /enterprise

Pages that remain SSR (for auth): /app/*

Review & Testing Checklist for Human

  • Test Netlify preview thoroughly - visit homepage, docs, blog, changelog, product, enterprise, and pricing pages to ensure they render correctly
  • Check for hydration mismatches - open browser console and look for React hydration warnings
  • Verify /app/* routes still work - these should still use SSR and require authentication
  • Verify env validation works in Netlify preview - server functions should still validate env vars at runtime (only CI skips validation)
  • Measure TTFB improvement - compare preview URL TTFB vs production using browser DevTools or curl

Recommended test plan:

  1. Deploy to Netlify preview via this PR
  2. Visit key pages: /, /docs/quickstart, /blog, /changelog, /pricing, /enterprise
  3. Check browser console for errors
  4. Use DevTools Network tab to measure TTFB on preview vs production
  5. Test a server function (e.g., auth flow) to confirm env vars are still validated at runtime

Notes

Prerender was previously enabled in commit 81993cd and disabled 2 hours later in 4da9398. The likely cause was the global fetchUser() call in __root.tsx which was removed in PR #1939, so prerender should work now.

The skipValidation flag in env.ts only applies when CI=true (GitHub Actions). Netlify production/preview builds will still validate env vars at runtime, ensuring misconfigurations are caught in real deployments.

Link to Devin run: https://app.devin.ai/sessions/66411affa67940a78f1f796856710095
Requested by: yujonglee (@yujonglee)

Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@netlify
Copy link

netlify bot commented Dec 1, 2025

Deploy Preview for hyprnote-storybook ready!

Name Link
🔨 Latest commit 596cfe3
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/692d777dd5434a0008250848
😎 Deploy Preview https://deploy-preview-2048--hyprnote-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Dec 1, 2025

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit 596cfe3
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/692d777d43f6f9000873b133
😎 Deploy Preview https://deploy-preview-2048--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 1, 2025

📝 Walkthrough

Walkthrough

Enabled prerendering and expanded prerender filter in the Vite TanStack Start config; added CI-driven skipValidation flag to environment initialization to bypass env validation during CI runs.

Changes

Cohort / File(s) Summary
Vite configuration
apps/web/vite.config.ts
Set prerender from false to true in the tanstackStart config and added path === "/" and path === "/enterprise" to the prerender filter alongside existing static routes.
Environment initialization
apps/web/src/env.ts
Added skipValidation: process.env.CI === "true" to the config passed into createEnv, enabling validation to be skipped during CI. No other config fields changed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review apps/web/vite.config.ts prerender filter logic to ensure only intended routes are emitted and ordering/short-circuit behavior is correct.
  • Verify apps/web/src/env.ts interactions where env validation is expected (local/dev/test) to ensure CI flag won't unintentionally bypass needed checks.
  • Confirm tests or CI pipelines that rely on env validation still behave as intended when CI=true.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: enabling prerender for static pages to improve TTFB, which matches the primary objective and file changes in vite.config.ts.
Description check ✅ Passed The description is directly related to the changeset, explaining why prerender is enabled, what pages are affected, and providing comprehensive testing guidance that aligns with the actual code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch devin/1764582750-enable-prerender

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 69f4f99 and 596cfe3.

📒 Files selected for processing (1)
  • apps/web/src/env.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Agent implementations should use TypeScript and follow the established architectural patterns defined in the agent framework
Agent communication should use defined message protocols and interfaces

Files:

  • apps/web/src/env.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/src/env.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: ci
  • GitHub Check: fmt
  • GitHub Check: Devin
🔇 Additional comments (1)
apps/web/src/env.ts (1)

35-38: CI-gated skipValidation is reasonable; just confirm trade‑off vs losing CI env checks

Using skipValidation: process.env.CI === "true" is compatible with @t3-oss/env-core and will skip schema validation in CI while keeping it for local/staging/prod runs. This matches common usage but means CI will no longer fail fast on missing/invalid env vars, so please confirm that’s acceptable and that another deployment stage still enforces env correctness.


Comment @coderabbitai help to get the list of available commands and usage tips.

Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/web/vite.config.ts (1)

24-32: New filter entries for /, /pricing, /enterprise – semantics and optional tidy‑up

Adding path === "/", path.startsWith("/pricing"), and path === "/enterprise" matches the described prerender targets. A couple of optional considerations:

  • If there’s any chance of other top‑level routes beginning with /pricing or /product that shouldn’t be static, consider using exact+subpath checks instead of raw startsWith, e.g. path === "/pricing" || path.startsWith("/pricing/").
  • For maintainability, you could factor this into a small helper/array of prefixes to avoid a long chain of ||, but that’s style‑only and not required for correctness.

Functionally this filter looks fine as written; the main thing is confirming the matched routes are indeed safe to prerender.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0fb81ff and 69f4f99.

📒 Files selected for processing (1)
  • apps/web/vite.config.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Agent implementations should use TypeScript and follow the established architectural patterns defined in the agent framework
Agent communication should use defined message protocols and interfaces

Files:

  • apps/web/vite.config.ts
**/*.config.{ts,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Agent configuration should be centralized and externalized from implementation logic

Files:

  • apps/web/vite.config.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props, just inline them instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/web/vite.config.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Redirect rules - hyprnote-storybook
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote-storybook
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Pages changed - hyprnote-storybook
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: fmt
  • GitHub Check: Devin
🔇 Additional comments (1)
apps/web/vite.config.ts (1)

18-35: Prerender enablement scope looks right; ensure targeted routes are truly static

Turning prerender.enabled to true with this filter will limit prerendering to the marketing/docs/etc paths and keep /app/* SSR-only, which matches the PR intent. The config wiring with tanstackStart and the Netlify plugin looks consistent.

Please double‑check for the routes matched by this filter (/, /blog/*, /docs/*, /changelog/*, /legal/*, /product/*, /pricing*, /enterprise) that:

  • Their loaders/actions don’t depend on per‑request auth/session or cookies.
  • They don’t assume browser globals at module/loader time (e.g., window, document) without a typeof window !== "undefined" guard.
  • Build time and Netlify function usage remain acceptable after prerendering is enabled.

If all of that holds, the change looks good to ship.

Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
@yujonglee yujonglee merged commit b507af6 into main Dec 1, 2025
13 of 14 checks passed
@yujonglee yujonglee deleted the devin/1764582750-enable-prerender branch December 1, 2025 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant