Skip to content

feat(docs): DR-7574 Add page feedback widget#7613

Open
ArthurGamby wants to merge 2 commits intomainfrom
dr-7574-docs-add-page-feedback
Open

feat(docs): DR-7574 Add page feedback widget#7613
ArthurGamby wants to merge 2 commits intomainfrom
dr-7574-docs-add-page-feedback

Conversation

@ArthurGamby
Copy link
Contributor

@ArthurGamby ArthurGamby commented Mar 10, 2026

Summary

  • Add a "Was this page helpful?" feedback widget at the bottom of every docs page
  • Thumbs up submits immediately, thumbs down expands an optional comment textarea with cancel/send buttons
  • Feedback is tracked via PostHog (docs:page_feedback) and persisted in localStorage to avoid re-prompting

Linear

https://linear.app/prisma-company/issue/DR-7574/docs-add-new-widget

Test plan

  • Visit any docs page and verify the widget appears below the "Edit on GitHub" footer
  • Click "Yes" — verify "Thanks for your feedback!" message appears
  • Refresh the page — verify the submitted state persists
  • Click "No" — verify textarea expands with Cancel and Send feedback buttons
  • Click "Cancel" — verify it collapses back to the initial state
  • Click "Send feedback" — verify submitted state
  • Verify PostHog event docs:page_feedback fires with path, vote, and comment

UI changes

posthog-review-widget.mov

Summary by CodeRabbit

  • New Features
    • Documentation pages now include a feedback panel to upvote or downvote content.
    • Downvotes can include an optional comment to explain issues.
    • Feedback is persisted per page (survives reloads) and shows a thank-you confirmation after submission.
    • Submissions are logged non-blockingly for analytics without interrupting the user experience.

@vercel
Copy link

vercel bot commented Mar 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
blog Ready Ready Preview, Comment Mar 10, 2026 3:24pm
docs Ready Ready Preview, Comment Mar 10, 2026 3:24pm
eclipse Ready Ready Preview, Comment Mar 10, 2026 3:24pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 10, 2026

Walkthrough

Adds a new client-side PageFeedback component to the docs app that captures per-page upvotes/downvotes (with optional comment), persists state to localStorage keyed by pathname, and emits PostHog analytics; integrates the component into the DocsPage layout after the header.

Changes

Cohort / File(s) Summary
Docs Page Integration
apps/docs/src/app/(docs)/(default)/[[...slug]]/page.tsx
Consolidates schema imports and renders the new PageFeedback component inside the DocsPage layout after the header.
Feedback Component
apps/docs/src/components/page-feedback.tsx
Adds a new client-side React component that manages per-path feedback state (idle/downvoted/submitted) in localStorage, supports upvote/downvote flows with optional comment on downvote, and logs docs:page_feedback events to PostHog. Includes storage error handling and non-blocking analytics calls.

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant Page as DocsPage / PageFeedback
  participant Storage as localStorage
  participant PH as PostHog

  User->>Page: View page (usePathname)
  Page->>Storage: read(getStorageKey(path))
  Storage-->>Page: stored state (idle/downvoted/submitted)
  User->>Page: Click Upvote
  Page->>Storage: write(vote=up)
  Page->>PH: send event {path, vote:"up", comment:null}
  PH-->>Page: ack (async)
  Page-->>User: show "Thanks for your feedback!"
  User->>Page: Click Downvote
  Page-->>User: show comment textarea
  User->>Page: Submit comment
  Page->>Storage: write(vote=down, comment)
  Page->>PH: send event {path, vote:"down", comment}
  PH-->>Page: ack (async)
  Page-->>User: show "Thanks for your feedback!"
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat(docs): DR-7574 Add page feedback widget' clearly summarizes the main change: adding a feedback widget to documentation pages. It is concise, specific, and directly related to the primary objective of the changeset.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

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

@argos-ci
Copy link

argos-ci bot commented Mar 10, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ⚠️ Changes detected (Review) 1 removed Mar 10, 2026, 3:27 PM

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: 2

🧹 Nitpick comments (2)
apps/docs/src/components/page-feedback.tsx (2)

21-26: Consider logging localStorage errors rather than swallowing them silently.

Empty catch blocks make debugging difficult when things go wrong in production. While localStorage failures are typically non-critical, having visibility into them helps diagnose user-reported issues.

🔧 Proposed improvement
   useEffect(() => {
     try {
       const stored = localStorage.getItem(getStorageKey(pathname));
       if (stored) setState("submitted");
-    } catch {}
+    } catch (e) {
+      console.warn("[PageFeedback] localStorage read failed:", e);
+    }
   }, [pathname]);

Apply similarly to the persist function's localStorage write.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/docs/src/components/page-feedback.tsx` around lines 21 - 26, The catch
block in the useEffect that reads from localStorage (around
getStorageKey(pathname) and setState("submitted")) silently swallows errors;
update it to catch the error as e and log a helpful message (including e) via
the app logger or console.error so failures are visible; also apply the same
pattern to the persist function where localStorage writes occur so both read and
write paths surface errors rather than using empty catch blocks.

97-103: Add accessibility attributes to the textarea.

The textarea lacks an id and associated <label>, which makes it harder for screen reader users to understand its purpose. The placeholder alone isn't sufficient for accessibility.

♿ Proposed accessibility improvement
+         <label htmlFor="feedback-comment" className="sr-only">
+           What was missing or unclear?
+         </label>
          <textarea
+           id="feedback-comment"
            value={comment}
            onChange={(e) => setComment(e.target.value)}
            placeholder="What was missing or unclear? (optional)"
+           aria-label="Feedback comment"
            rows={3}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/docs/src/components/page-feedback.tsx` around lines 97 - 103, The
textarea in the PageFeedback component is missing an id and an associated label
which hurts screen-reader accessibility; add a unique id (e.g.,
feedbackCommentId) and provide a corresponding <label
htmlFor={feedbackCommentId}> that describes the field (or use a visually-hidden
label if you don't want visible text), or alternatively add an explicit
aria-label/aria-labelledby tied to that id, and update the textarea to include
id={feedbackCommentId} so the label and textarea are programmatically associated
(reference the textarea using the existing state handlers comment and setComment
to locate the element).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/docs/src/components/page-feedback.tsx`:
- Around line 15-26: The component can flash "idle" before the client-side
localStorage check runs; change the initial feedback state in PageFeedback from
"idle" to a sentinel like "loading" (or null), update the useEffect that reads
localStorage/getStorageKey(pathname) to setState to either "submitted" or "idle"
when the check completes, and ensure the render logic returns nothing (or a
skeleton) while state === "loading" so users who already submitted won't see the
prompt during hydration; keep references to usePathname, state/setState,
useEffect and getStorageKey to locate the changes.
- Line 7: The PostHog SDK is never initialized before posthog.capture() is
called; import or run the posthog.init() initialization so captures aren't
dropped. Fix by ensuring instrumentation-client.ts (which calls posthog.init())
is imported and executed on the client before app render (e.g., import it from
the root layout or Provider), or move the posthog.init() call into the existing
instrumentation.ts initialization flow, or create a client-side PostHog provider
that runs posthog.init() during its mount before rendering children; refer to
instrumentation-client.ts, instrumentation.ts, posthog.init, and posthog.capture
when applying the change.

---

Nitpick comments:
In `@apps/docs/src/components/page-feedback.tsx`:
- Around line 21-26: The catch block in the useEffect that reads from
localStorage (around getStorageKey(pathname) and setState("submitted")) silently
swallows errors; update it to catch the error as e and log a helpful message
(including e) via the app logger or console.error so failures are visible; also
apply the same pattern to the persist function where localStorage writes occur
so both read and write paths surface errors rather than using empty catch
blocks.
- Around line 97-103: The textarea in the PageFeedback component is missing an
id and an associated label which hurts screen-reader accessibility; add a unique
id (e.g., feedbackCommentId) and provide a corresponding <label
htmlFor={feedbackCommentId}> that describes the field (or use a visually-hidden
label if you don't want visible text), or alternatively add an explicit
aria-label/aria-labelledby tied to that id, and update the textarea to include
id={feedbackCommentId} so the label and textarea are programmatically associated
(reference the textarea using the existing state handlers comment and setComment
to locate the element).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6bb6c769-5310-4b05-a75d-5f7c178d5bd5

📥 Commits

Reviewing files that changed from the base of the PR and between e867ae3 and ae1270d.

📒 Files selected for processing (2)
  • apps/docs/src/app/(docs)/(default)/[[...slug]]/page.tsx
  • apps/docs/src/components/page-feedback.tsx

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.

🧹 Nitpick comments (1)
apps/docs/src/components/page-feedback.tsx (1)

101-107: Consider adding an accessible label for the textarea.

The textarea uses a placeholder for hint text, but placeholders disappear when users start typing and aren't reliably announced by all screen readers as labels. Adding an aria-label would improve accessibility for assistive technology users.

♿ Suggested accessibility improvement
          <textarea
            value={comment}
            onChange={(e) => setComment(e.target.value)}
            placeholder="What was missing or unclear? (optional)"
+           aria-label="Optional feedback comment"
            rows={3}
            className="w-full resize-none rounded-md border border-fd-border bg-fd-background px-3 py-2 text-sm text-fd-foreground placeholder:text-fd-muted-foreground focus:outline-none focus:ring-2 focus:ring-fd-ring"
          />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/docs/src/components/page-feedback.tsx` around lines 101 - 107, The
textarea in the PageFeedback component currently only uses a placeholder which
is not a reliable accessible label; update the textarea element (the one using
value={comment} and onChange={(e) => setComment(e.target.value)}) to include an
accessible label by adding either an aria-label (e.g., aria-label="Feedback
comment") or aria-labelledby pointing to a visible <label> element; ensure the
label text matches the placeholder intent ("What was missing or unclear?
(optional)") so screen readers receive the same hint.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/docs/src/components/page-feedback.tsx`:
- Around line 101-107: The textarea in the PageFeedback component currently only
uses a placeholder which is not a reliable accessible label; update the textarea
element (the one using value={comment} and onChange={(e) =>
setComment(e.target.value)}) to include an accessible label by adding either an
aria-label (e.g., aria-label="Feedback comment") or aria-labelledby pointing to
a visible <label> element; ensure the label text matches the placeholder intent
("What was missing or unclear? (optional)") so screen readers receive the same
hint.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4dc18de0-5a8c-4173-9855-f59ac9336087

📥 Commits

Reviewing files that changed from the base of the PR and between ae1270d and 754cc02.

📒 Files selected for processing (1)
  • apps/docs/src/components/page-feedback.tsx

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