Skip to content

feat: add Product Hunt integration to hero component.#163

Merged
izadoesdev merged 1 commit intodatabuddy-analytics:mainfrom
sbansal1999:product-hunt-badge
Oct 1, 2025
Merged

feat: add Product Hunt integration to hero component.#163
izadoesdev merged 1 commit intodatabuddy-analytics:mainfrom
sbansal1999:product-hunt-badge

Conversation

@sbansal1999
Copy link
Contributor

@sbansal1999 sbansal1999 commented Oct 1, 2025

Screenshot 2025-10-01 at 5 29 00 PM Screenshot 2025-10-01 at 5 29 12 PM

Summary by CodeRabbit

  • New Features

    • Added a Product Hunt badge to the landing Hero that links to the product page.
    • Badge theme-syncs with the user's light/dark mode so it matches the site theme.
    • Badge is clickable and placed above the existing "Rejected by" badge.
  • Chores

    • Updated image optimization settings to allow remote images from Product Hunt so the badge loads reliably.

@graphite-app
Copy link
Contributor

graphite-app bot commented Oct 1, 2025

How to use the Graphite Merge Queue

Add the label Main to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

@vercel
Copy link

vercel bot commented Oct 1, 2025

@sbansal1999 is attempting to deploy a commit to the Databuddy Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 1, 2025

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a theme-aware Product Hunt badge to the docs landing Hero component using next-themes and next/image, and updates Next.js image config to allow remote images from api.producthunt.com for the new badge asset.

Changes

Cohort / File(s) Summary of Changes
Docs Hero theming & Product Hunt badge
apps/docs/components/landing/hero.tsx
Imported next/image and next-themes, derived isDarkMode from resolvedTheme, and rendered a clickable Product Hunt featured image/badge that switches embed theme (dark/light) based on current theme above the existing badge block.
Next.js image remote patterns
apps/docs/next.config.mjs
Added a remote image pattern allowing https://api.producthunt.com in images.remotePatterns so Next.js can optimize the external Product Hunt badge image.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant B as Browser
  participant H as Hero Component
  participant T as ThemeProvider
  participant PH as ProductHunt (api.producthunt.com)
  participant NI as Next Image Optimizer

  U->>B: Open docs landing page
  B->>H: Render Hero
  H->>T: read resolvedTheme
  T-->>H: theme (light/dark)
  alt theme is dark
    H->>PH: request dark embed/image URL
  else theme is light
    H->>PH: request light embed/image URL
  end
  PH-->>NI: serve remote image
  NI-->>B: optimized image response
  Note over H,B: Clickable Product Hunt badge rendered above existing badge
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

I hop through code, both dusk and sun,
A badge that flips when day is done.
Product Hunt gleams, dark or bright,
I nibble bugs and get it right.
Docs adorned — a happy bite. 🐇✨

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and concisely summarizes the main change—the addition of a Product Hunt integration to the hero component—using conventional commit style and avoiding unnecessary detail or ambiguity. It accurately reflects the primary focus of the changeset and is immediately understandable to reviewers.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cdd3762 and 0705963.

📒 Files selected for processing (2)
  • apps/docs/components/landing/hero.tsx (3 hunks)
  • apps/docs/next.config.mjs (1 hunks)

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.

@sbansal1999
Copy link
Contributor Author

@izadoesdev

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

🧹 Nitpick comments (1)
apps/docs/components/landing/hero.tsx (1)

42-56: Consider SSR hydration and add a fallback for undefined theme.

The useTheme hook may return undefined during initial SSR/hydration, which could cause a hydration mismatch. Consider adding a fallback to prevent layout shift:

-	const isDarkMode = resolvedTheme === 'dark';
+	const isDarkMode = resolvedTheme === 'dark' || false;

Or more defensively, handle the undefined case in the template literal:

 	src={`https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1021633&theme=${isDarkMode ? 'dark' : 'light'}`}

could be:

-	src={`https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1021633&theme=${isDarkMode ? 'dark' : 'light'}`}
+	src={`https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1021633&theme=${resolvedTheme === 'dark' ? 'dark' : 'light'}`}

However, the structure and accessibility are excellent:

  • Proper use of Next.js Image component with explicit dimensions
  • Descriptive alt text for screen readers
  • Correct security attributes (rel="noopener noreferrer")
  • Appropriate hover interaction

Based on learnings.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ebdf219 and cdd3762.

📒 Files selected for processing (2)
  • apps/docs/components/landing/hero.tsx (3 hunks)
  • apps/docs/next.config.mjs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{jsx,tsx}: Don't use elements in Next.js projects.
Don't use elements in Next.js projects.
Don't pass children as props.
Don't use the return value of React.render.
Make sure all dependencies are correctly specified in React hooks.
Make sure all React hooks are called from the top level of component functions.
Don't forget key props in iterators and collection literals.
Don't destructure props inside JSX components in Solid projects.
Don't define React components inside other components.
Don't use event handlers on non-interactive elements.
Don't assign to React component props.
Don't use both children and dangerouslySetInnerHTML props on the same element.
Don't use dangerous JSX props.
Don't use Array index in keys.
Don't insert comments as text nodes.
Don't assign JSX properties multiple times.
Don't add extra closing tags for components without children.
Use <>...</> instead of ....
Watch out for possible "wrong" semicolons inside JSX elements.
Don't use accessKey attribute on any HTML element.
Don't set aria-hidden="true" on focusable elements.
Don't add ARIA roles, states, and properties to elements that don't support them.
Don't use distracting elements like or .
Only use the scope prop on elements.
Don't assign non-interactive ARIA roles to interactive HTML elements.
Make sure label elements have text content and are associated with an input.
Don't assign interactive ARIA roles to non-interactive HTML elements.
Don't assign tabIndex to non-interactive HTML elements.
Don't use positive integers for tabIndex property.
Don't include "image", "picture", or "photo" in img alt prop.
Don't use explicit role property that's the same as the implicit/default role.
Make static elements with click handlers use a valid role attribute.
Always include a title element for SVG elements.
Give all elements requiring alt text meaningful information for screen readers.
Make sure anchors have content that's accessible ...

Files:

  • apps/docs/components/landing/hero.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{js,ts,jsx,tsx}: Don't import next/document outside of pages/_document.jsx in Next.js projects.
Don't use global eval().
Don't use var.
Don't use console.
Don't use debugger.
Don't assign directly to document.cookie.
Don't use duplicate case labels.
Don't use duplicate class members.
Don't use duplicate function parameter names.
Don't use empty block statements and static blocks.
Don't use with statements in non-strict contexts.
Don't use the arguments object.
Don't use the comma operator.
Don't use unnecessary boolean casts.
Use for...of statements instead of Array.forEach.
Use arrow functions instead of function expressions.
Use Date.now() to get milliseconds since the Unix Epoch.
Use .flatMap() instead of map().flat() when possible.
Use literal property access instead of computed property access.
Don't use parseInt() or Number.parseInt() when binary, octal, or hexadecimal literals work.
Use concise optional chaining instead of chained logical expressions.
Use regular expression literals instead of the RegExp constructor when possible.
Don't use number literal object member names that aren't base 10 or use underscore separators.
Remove redundant terms from logical expressions.
Use while loops instead of for loops when you don't need initializer and update expressions.
Don't reassign const variables.
Don't use constant expressions in conditions.
Don't use Math.min and Math.max to clamp values when the result is constant.
Don't return a value from a constructor.
Don't use empty character classes in regular expression literals.
Don't use empty destructuring patterns.
Don't call global object properties as functions.
Don't declare functions and vars that are accessible outside their block.
Don't use variables and function parameters before they're declared.
Don't use 8 and 9 escape sequences in string literals.
Don't use literal numbers that lose precision.
Don't use duplicate conditions in if-else-if chains.
Don't use two keys with the same name inside objects...

Files:

  • apps/docs/components/landing/hero.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ultracite.mdc)

**/*.{ts,tsx}: Don't use TypeScript enums.
Don't use TypeScript const enum.
Don't use TypeScript namespaces.
Don't use the TypeScript directive @ts-ignore.
Don't use any type.
Don't use implicit any type on variable declarations.
Don't use non-null assertions with the ! postfix operator.
Don't misuse the non-null assertion operator (!) in TypeScript files.
Don't declare empty interfaces.
Use export type for types.
Use import type for types.
Don't use primitive type aliases or misleading types.
Don't use empty type parameters in type aliases and interfaces.

**/*.{ts,tsx}: Avoid using the types any, unknown, or never; use explicit, correct types
Create and use proper interfaces for APIs, responses, and components

Files:

  • apps/docs/components/landing/hero.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{js,jsx,ts,tsx}: Use bun <file> instead of node <file> or ts-node <file>
Do not use dotenv; Bun automatically loads .env files
Do not use express; use Bun.serve() for HTTP servers
Do not use better-sqlite3; use bun:sqlite for SQLite
Do not use ioredis; use Bun.redis for Redis
Do not use pg or postgres.js; use Bun.sql for Postgres
Do not use ws; use built-in WebSocket
Prefer Bun.file over node:fs's readFile/writeFile
Use Bun.$ instead of execa for running shell commands

Files:

  • apps/docs/components/landing/hero.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/01-MUST-DO.mdc)

**/*.{ts,tsx,js,jsx}: Use Dayjs; do not use date-fns
Use TanStack Query for hooks; do not use SWR
Use console APIs appropriately (console.error, console.time, console.table, etc.)
Use JSON.stringify() when adding debugging output

Files:

  • apps/docs/components/landing/hero.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/01-MUST-DO.mdc)

**/*.{tsx,jsx}: Use Phosphor React icons; do not use Lucide
Name Phosphor icon components with the Icon suffix (e.g., CaretIcon) and use default imports (not as)
For Phosphor icons, use weight="duotone" by default; use fill for arrows; for plus icons omit weight
Minimize useEffect; only use when truly critical

Files:

  • apps/docs/components/landing/hero.tsx
**/*.{tsx,jsx,html}

📄 CodeRabbit inference engine (.cursor/rules/01-MUST-DO.mdc)

Use Tailwind class rounded; do not use rounded-md or rounded-xl

Files:

  • apps/docs/components/landing/hero.tsx
**/*.{html,htm,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)

**/*.{html,htm,jsx,tsx}: Inputs must set appropriate autocomplete, semantic name, correct type, and inputmode
Associate labels and controls so checkboxes/radios and their labels share one generous hit target
Use or framework for navigation to support Cmd/Ctrl/middle-click
Use polite aria-live for toasts and inline validation feedback
Provide redundant status cues; icons must have visible text labels (not color-only)
Do not ship visual-only schema—ensure accessible names exist even if labels are visually omitted
Use the ellipsis character … for ellipses in UI copy
Include a 'Skip to content' link and use a proper hierarchical <h1–h6> structure
Provide accurate accessible names; mark decorative elements aria-hidden; verify Accessibility Tree
Icon-only buttons must have descriptive aria-label
Prefer native semantics (button, a, label, table) before adding ARIA
Use non-breaking spaces to glue terms (e.g., 10 MB, ⌘ + K)
Preload only above-the-fold images and lazy-load the rest
Prevent CLS from images by specifying explicit dimensions or reserving space

Files:

  • apps/docs/components/landing/hero.tsx
**/*.{jsx,tsx,html,htm}

📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)

Virtualize large lists

Files:

  • apps/docs/components/landing/hero.tsx
🧬 Code graph analysis (1)
apps/docs/components/landing/hero.tsx (1)
apps/dashboard/components/ai-elements/image.tsx (1)
  • Image (9-24)
⏰ 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). (2)
  • GitHub Check: Vercel Agent Review
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (2)
apps/docs/next.config.mjs (1)

95-98: LGTM! Remote pattern correctly configured.

The Product Hunt API remote pattern is properly configured to support the badge images used in the hero component.

apps/docs/components/landing/hero.tsx (1)

4-5: LGTM! Imports are correct.

Properly imports Next.js Image component and next-themes hook as needed for theme-aware badge rendering.

@izadoesdev izadoesdev merged commit 139653b into databuddy-analytics:main Oct 1, 2025
3 of 6 checks passed
@sbansal1999 sbansal1999 deleted the product-hunt-badge branch October 1, 2025 12:13
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