We released MonaKiosk yesterday, a modern Astro integration for monetizing your content with Polar.sh.
With MonaKiosk, you can easily add paywalls and monetization to your Astro-powered projects. Whether youβre selling blog posts, courses, templates, or subscriptions, MonaKiosk takes care of the heavy lifting so you can focus on creating great content.
Key Features
- Content Paywalls - Protect your premium content with automatic paywall generation
- Flexible Pricing - Support for both one-time purchases and subscriptions
- Simple Setup - Add a few lines to your Astro config and you're ready to go
- Automatic Sync - Your content automatically syncs to Polar at build time
- Built-in Auth - Email-based authentication and session management included
Installation
npm install mona-kiosk
Quick Start
You can find the whole project in demo.
1. Setup Polar
In Polar, configure the environment values required by .env:
POLAR_ACCESS_TOKEN=polar_oat_xxxxxxxxxxxxx
POLAR_ORG_SLUG=your-org-slug
POLAR_ORG_ID=your-org-id
POLAR_SERVER=sandbox # or 'production'
2. Create an Astro Project
For example, run pnpm create astro@latest and choose the blog template.
Then install the required packages:
-
@astrojs/node// or other server adapters mona-kiosk
The following steps use the Astro blog template as the reference.
3. Update Contents
Import PayableMetadata and merge it into the collection you want to protect.
import { PayableMetadata } from "mona-kiosk";
const blog = defineCollection({
...
schema: ({ image }) =>
z.object(...)
.merge(PayableMetadata),
});
Then, update the metadata in a specific content:
---
title: 'Markdown Style Guide'
description: 'Here is a sample of some basic Markdown syntax that can be used when writing Markdown content in Astro.'
pubDate: 'Jun 19 2024'
heroImage: '../../assets/blog-placeholder-1.jpg'
price: 100 # Price in cents ($1)
---
Note: the currency field defaults to usd. Polar currently supports USD only, so you can leave it unset for now.
4. Add Integration
In astro.config.mjs:
import { defineConfig } from "astro/config";
import { monaKiosk } from "mona-kiosk";
export default defineConfig({
output: "server", // Required - MonaKiosk needs SSR
integrations: [
monaKiosk({
polar: {
accessToken: process.env.POLAR_ACCESS_TOKEN,
organizationSlug: process.env.POLAR_ORG_SLUG,
organizationId: process.env.POLAR_ORG_ID,
server: (process.env.POLAR_SERVER as "production" | "sandbox") || "sandbox",
},
collections: [
{ include: "src/content/blog/**/*.md" },
],
}),
],
adapter: node({
mode: "standalone",
}),
});
What gets injected:
-
/api/mona-kiosk/checkout- Create checkout session -
/api/mona-kiosk/auth/signin- Email-based sign-in (For internal calling, protect it.) -
/api/mona-kiosk/auth/signout- Sign out -
/api/mona-kiosk/portal- Redirect to Polar customer portal -
/mona-kiosk/signin- Default signin page (Test only, not secure for production)
π¨ SECURITY WARNING: The default
/mona-kiosk/signinpage is provided ONLY for sandbox testing and is NOT secure for production use.It will only be injected when
server: "sandbox"is set AND no customsigninPagePathis configured.For production, you MUST create your own secure sign-in page or use a third-party authentication provider like BetterAuth.
5. Update Page Template
In src/pages/blog/[...slug].astro:
---
import { getEntry, render } from "astro:content";
const { slug } = Astro.params;
const post = await getEntry("blog", slug);
if (!post) return Astro.redirect("/404");
const { Content } = await render(post);
---
<BlogPost {...post.data}>
{!Astro.locals.paywall?.hasAccess && Astro.locals.paywall?.preview ? (
<div set:html={Astro.locals.paywall.preview} />
) : (
<Content />
)}
</BlogPost>
Note: The middleware automatically detects payable content, checks authentication/access, generates previews, and sets Astro.locals.paywall.
6. Build and Preview
npm run dev
Test card: 4242 4242 4242 4242 (any future date, any CVC)
Support Us
You can check out our live paywalled post: MonaKiosk + BetterAuth Integration Guide. It provides a detailed walkthrough on integrating MonaKiosk with BetterAuth and Polar β a valuable resource for advanced users.
If youβd like to support our work, consider purchasing the guide π.
Thank you in advance for your support!
For more information, please visit its github repo.
Top comments (0)