Skip to content

feat: add Next.js server-side Convex baseline#67

Merged
BASIC-BIT merged 3 commits into
mainfrom
issue-64-next-server-convex
May 8, 2026
Merged

feat: add Next.js server-side Convex baseline#67
BASIC-BIT merged 3 commits into
mainfrom
issue-64-next-server-convex

Conversation

@BASIC-BIT
Copy link
Copy Markdown
Owner

Summary

  • add a dedicated /server-status route that demonstrates the first App Router server-side Convex read with fetchQuery
  • keep the homepage on the existing reactive client baseline and document when to use server reads versus client useQuery
  • update backend and strategy docs so later app work has one clear copyable server-side pattern

Testing

  • pnpm lint:web
  • pnpm typecheck:web
  • pnpm typecheck (from apps/web)
  • pnpm build:web
  • pnpm verify:backend:local
  • browser smoke check of /server-status showing live health:status data from local Convex

Introduce a dedicated App Router server-read path so follow-on work has one clear fetchQuery pattern without disturbing the existing reactive client baseline.
Copilot AI review requested due to automatic review settings May 8, 2026 20:36
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 8, 2026

Greptile Summary

This PR adds a /server-status route as the first App Router server-side Convex read, using fetchQuery from convex/nextjs inside a dedicated server component, while keeping the existing reactive useQuery path on the homepage untouched.

  • apps/web/src/convex/server.ts: New helper fetchBackendStatus guards for a missing NEXT_PUBLIC_CONVEX_URL, wraps fetchQuery(api.health.status) in a typed discriminated-union result (live | missing-url | error), and catches SDK exceptions cleanly.
  • apps/web/src/app/server-status/page.tsx: New force-dynamic server component renders all three result states and documents the three-tier pattern rule (fetchQuery / useQuery / preloadQuery). The raw SDK error message is surfaced in the error branch with no access guard, which could expose internal detail if the route ships to production.
  • Documentation: READMEs and docs/ files are updated consistently to reflect the new baseline and pattern guidance.

Confidence Score: 4/5

Safe to merge; the new route is a narrow, additive baseline that does not touch existing auth or data paths.

The implementation is clean and the discriminated-union error handling is solid. The one thing worth a second look before this route sees production traffic is the error branch, which renders the raw Convex SDK error message without any access control on /server-status.

apps/web/src/app/server-status/page.tsx — specifically the error-state branch that renders the raw SDK message.

Important Files Changed

Filename Overview
apps/web/src/convex/server.ts New server-side Convex helper: guards for missing NEXT_PUBLIC_CONVEX_URL, wraps fetchQuery in a typed discriminated-union result, and catches errors cleanly. Logic is correct.
apps/web/src/app/server-status/page.tsx New dynamic server component rendering three states (live, missing-url, error). force-dynamic is correct; raw error.message rendered in the error branch could expose internal SDK detail if the route reaches production without an auth guard.
apps/web/src/app/page.tsx Adds a Link to /server-status and updates homepage copy; no functional changes to the existing client-side data path.
docs/backend/convex-bootstrap.md Documents the new /server-status route and the three-tier App Router pattern rule (fetchQuery / useQuery / preloadQuery). Accurate and consistent with the implementation.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant NextServer as Next.js Server
    participant fetchBackendStatus as fetchBackendStatus()
    participant Convex as Convex Backend

    Browser->>NextServer: GET /server-status
    NextServer->>fetchBackendStatus: call fetchBackendStatus()
    alt NEXT_PUBLIC_CONVEX_URL not set
        fetchBackendStatus-->>NextServer: "{ kind: "missing-url" }"
    else fetchQuery succeeds
        fetchBackendStatus->>Convex: "fetchQuery(api.health.status, {})"
        Convex-->>fetchBackendStatus: "{ status, scope, backend, note }"
        fetchBackendStatus-->>NextServer: "{ kind: "live", data }"
    else fetchQuery throws
        fetchBackendStatus->>Convex: "fetchQuery(api.health.status, {})"
        Convex-->>fetchBackendStatus: Error
        fetchBackendStatus-->>NextServer: "{ kind: "error", message }"
    end
    NextServer-->>Browser: Rendered HTML (server component, force-dynamic)
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
apps/web/src/app/server-status/page.tsx:112-114
**Raw SDK error rendered in production HTML**

`status.message` is the raw `error.message` from the caught Convex SDK exception. While Convex connection errors typically say things like "Network request failed", they can also include the deployment URL, request IDs, or internal SDK paths depending on the SDK version and error type. Since `/server-status` carries no auth guard and may ship to a production deployment, the full error string is visible to any visitor in the rendered HTML. Consider truncating long messages or limiting to a fixed set of user-friendly strings for the error branch.

Reviews (1): Last reviewed commit: "feat: add Next.js server-side Convex bas..." | Re-trigger Greptile

Comment thread apps/web/src/app/server-status/page.tsx Outdated
Avoid rendering raw Convex SDK failures into public HTML while still surfacing a clear recovery path for the server-side baseline route.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an explicit App Router server-side Convex read example alongside the existing client-side reactive baseline, and updates docs to clarify when to use each approach.

Changes:

  • Introduces /server-status as the first server-rendered fetchQuery example against api.health.status.
  • Adds a small server helper (fetchBackendStatus) to centralize the server-side Convex read + error shaping.
  • Updates repo/web/backend docs to document the client (useQuery) vs server (fetchQuery) baseline decision.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
README.md Documents the new /server-status server-side baseline route.
docs/planning/engineering-strategy.md Adds guidance on choosing fetchQuery vs deferring preloadQuery.
docs/backend/convex-bootstrap.md Updates Convex bootstrap docs to include the server-side read baseline and pattern rule.
apps/web/src/convex/server.ts Adds a server helper to run fetchQuery(api.health.status) with basic error shaping.
apps/web/src/app/server-status/page.tsx Adds the new server-rendered status page demonstrating fetchQuery.
apps/web/src/app/page.tsx Adds navigation to /server-status and updates homepage copy to reflect the new baselines.
apps/web/README.md Notes the new server-side baseline route and how it fits with the client baseline.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md Outdated
Comment thread apps/web/src/app/server-status/page.tsx Outdated
Comment thread apps/web/src/app/server-status/page.tsx Outdated
Clarify the dedicated server route description and align the bootstrap copy with the actual NEXT_PUBLIC_CONVEX_URL mirroring flow.
@BASIC-BIT BASIC-BIT merged commit 3011b63 into main May 8, 2026
5 checks passed
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.

2 participants