Product Hunt Button

Link button showing a Product Hunt post's upvote count with the PH cat icon. Async server component — fetches data at build time with ISR.

class-variance-authority

Preview

Installation

$ shadcn add jalco/producthunt-button

Usage

import { ProductHuntButton } from "@/components/producthunt-button"
<ProductHuntButton slug="my-product" />

Async server component. Fetches the Product Hunt GraphQL API at build time and caches the result for 1 hour via Next.js ISR. Requires PRODUCTHUNT_TOKEN — get one at producthunt.com/v2/oauth/applications. Alternatively, pass pre-fetched data via upvotes and name props to skip the API call entirely.

Playground

Props

import { ProductHuntButton } from "@/components/producthunt-button"

<ProductHuntButton slug="notion" />

Examples

Variants

Default

Product Hunt

Primary

Secondary

Outline

Ghost

Subtle

Sizes

Small

Default

Large

With product name

Default + Name

Product Hunt + Name

Outline + Name + Brand

Icon styles

Current Color

Brand Orange

Muted

API Reference

ProductHuntButton

PropType

Getting a Product Hunt Token

The component fetches live data from the Product Hunt GraphQL API. To enable this, you need a developer token.

  1. Go to the Product Hunt API Dashboard.
  2. Click Add an Application. Enter any name and redirect URI (e.g. your site URL).
  3. After creating the app, scroll down to the Developer Token section. Copy the token value.
  4. Add it to your environment:
PRODUCTHUNT_TOKEN=your_developer_token_here

The developer token never expires and requires no OAuth flow. No API key or secret exchange needed — the token from the dashboard works directly as a bearer token.

Notes

  • No token? No problem. Pass upvotes and name props to skip the API call entirely — useful for static sites or when you already have the data.
  • ISR caching. Results cached for 1 hour via next.revalidate.
  • Graceful fallback. Returns nothing when the post doesn't exist or the token is missing — no broken UI.