A super lightweight Next.js demo showing how to integrate Polar.sh subscriptions with just a few simple functions.
- 5 Simple Functions - All you need to manage subscriptions
- Real-time Data - Always fetches fresh data from Polar.sh
- Automatic Upgrades - Seamlessly switch between plans
- Price Display - Shows formatted pricing with currency
- Success Redirects - Handles payment success gracefully
- Ultra Lightweight - Minimal dependencies and files
├── app/
│ ├── api/polar/route.ts # Single API endpoint for all Polar operations
│ ├── layout.tsx # Basic app layout
│ └── page.tsx # Main page
├── components/
│ └── SimplePolar.tsx # Main subscription dashboard component
├── lib/
│ ├── polar.ts # 5 simple functions for everything
│ └── polar-client.ts # Polar.sh API client (internal)
└── .env.local # Configuration
git clone <your-repo>
cd nextjs
npm installCreate .env.local:
# Your Polar.sh access token (get from dashboard)
POLAR_ACCESS_TOKEN=polar_oat_your_token_here
# Where users return after successful payment
POLAR_SUCCESS_URL=http://localhost:3000?success=true
# Email to test subscriptions with (any email works)
DEMO_USER_EMAIL=your-email@example.com- Go to Polar.sh Dashboard
- Navigate to Settings → API Keys
- Create a new Personal Access Token
- Copy it to
POLAR_ACCESS_TOKENin your.env.local
npm run devOpen http://localhost:3000 in your browser.
The demo shows a subscription dashboard that:
- Shows Current Plan - Displays any active subscription for the configured email
- Lists Available Plans - Shows all your Polar.sh products with prices
- Handle Upgrades - Automatically cancels old subscription and creates new one
- Success Messages - Shows confirmation when payments succeed
Simply update DEMO_USER_EMAIL in .env.local and restart the server. The dashboard will show subscription data for that email address.
All subscription management is handled by these functions in lib/polar.ts:
// Get user's current subscription
const subscription = await getUserSubscription()
// Get all available products/plans
const products = await getProducts()
// Start checkout process for a product
await startCheckout(productId)
// Cancel an active subscription
await cancelSubscription(subscriptionId)
// Check if payment was successful from URL
const success = checkPaymentSuccess()The single API endpoint handles everything:
GET /api/polar?action=products- Get all productsGET /api/polar?action=subscription- Get user's subscriptionPOST /api/polar?action=checkout- Create checkout sessionPOST /api/polar?action=cancel- Cancel subscription
-
Copy these files to your project:
lib/polar.ts- The 5 simple functionslib/polar-client.ts- Internal API clientapp/api/polar/route.ts- API endpoint
-
Install dependencies:
npm install next react
-
Set up environment variables (see above)
-
Use the functions in your components:
import { getProducts, startCheckout } from './lib/polar' // In your component const products = await getProducts() // Show products, then on click: await startCheckout(productId)
The SimplePolar.tsx component is just an example. You can:
- Replace it with your own design
- Use the 5 functions in
lib/polar.tsanywhere in your app - Style it to match your brand
- Add additional features like trial periods, etc.
- Update
POLAR_SUCCESS_URLto your production domain - Make sure your Polar.sh products are published
- Test with real email addresses
- Deploy normally (Vercel, Netlify, etc.)
The code includes helpful comments showing where to add database logic. Here are complete examples:
"Checkout failed"
- Check your
POLAR_ACCESS_TOKENis correct - Verify the product exists and is published in Polar.sh
"No subscription found"
- The email in
DEMO_USER_EMAILdoesn't have an active subscription - Try subscribing to a plan first
Redirect not working
- Check
POLAR_SUCCESS_URLmatches your domain - Make sure the URL includes
?success=true
- Polar.sh Documentation
- Polar.sh Discord
- Check the browser console for detailed error messages
MIT - Use this however you want!
Built with ❤️ for the Polar.sh community
