Skip to main content
Mantlz integrates with several third-party services to provide authentication, payments, email delivery, and more. This guide covers the setup and configuration for each integration.

Clerk Authentication

Clerk provides authentication, user management, and session handling for Mantlz.

Features

  • Email/password authentication
  • Social login (Google, GitHub, etc.)
  • Multi-factor authentication
  • User profile management
  • Session management
  • Organization support

Setup

1

Create a Clerk application

  1. Sign up at clerk.com
  2. Create a new application
  3. Choose a name for your application
  4. Select authentication methods
2

Configure authentication methods

In your Clerk dashboard:
  1. Go to User & AuthenticationEmail, Phone, Username
  2. Enable email addresses
  3. Configure password requirements
  4. (Optional) Enable social providers under Social Connections
3

Get your API keys

Navigate to DevelopersAPI Keys:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_test_..."
CLERK_SECRET_KEY="sk_test_..."
4

Configure redirect URLs

Set these environment variables:
NEXT_PUBLIC_CLERK_SIGN_IN_URL="/sign-in"
NEXT_PUBLIC_CLERK_SIGN_UP_URL="/sign-up"
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL="/dashboard"
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL="/dashboard"
5

Configure allowed origins

In Clerk dashboard, go to DevelopersAllowed Origins:
  • Add http://localhost:3000 for development
  • Add your production domain (e.g., https://yourdomain.com)

Middleware Configuration

Mantlz uses Clerk middleware for route protection:
src/middleware.ts
import { clerkMiddleware } from "@clerk/nextjs/server";

export default clerkMiddleware(async (auth, req) => {
  // Protected routes require authentication
  if (isProtectedRoute(req)) {
    if (!auth.userId) {
      return auth.redirectToSignIn();
    }
  }
  
  return NextResponse.next();
});

Protected Routes

The following routes are protected by default:
  • /dashboard/* - Main dashboard
  • /api/trpc/* - tRPC API routes
  • /api/webhooks/* (except Stripe webhooks)
See src/utils/routes.ts for the complete list of protected routes.

Stripe Payment Integration

Stripe handles subscription billing, payment processing, and customer management.

Features

  • Subscription management
  • Payment processing
  • Customer portal
  • Webhook events
  • Invoice generation
  • Failed payment handling

Setup

1

Create a Stripe account

Sign up at stripe.com and complete account verification.
2

Create subscription products

In your Stripe dashboard:
  1. Go to ProductsAdd product
  2. Create a “Standard” plan:
    • Name: Standard
    • Recurring billing: Monthly
    • Price: Your chosen amount
  3. Create a “Pro” plan:
    • Name: Pro
    • Recurring billing: Monthly
    • Price: Your chosen amount
  4. Copy the price IDs for each plan
3

Configure environment variables

STRIPE_SECRET_KEY="sk_test_..."
NEXT_PUBLIC_STRIPE_STANDARD_PRICE_ID="price_..."
NEXT_PUBLIC_STRIPE_PRO_PRICE_ID="price_..."
4

Set up webhooks

See the Webhooks Guide for detailed webhook configuration.

Checkout Session Creation

Mantlz creates Stripe checkout sessions for subscription upgrades:
import { stripe } from "@/lib/stripe";

const session = await stripe.checkout.sessions.create({
  customer_email: userEmail,
  line_items: [
    {
      price: priceId,
      quantity: 1,
    },
  ],
  mode: "subscription",
  success_url: `${process.env.NEXT_PUBLIC_APP_URL}/dashboard?payment=success`,
  cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/pricing?canceled=true`,
  metadata: {
    userId,
    userEmail,
    plan,
  },
});

Subscription Plans

Mantlz supports three subscription tiers:
const FREE_PLAN = {
  name: "FREE",
  maxForms: 1,
  maxSubmissionsPerMonth: 200,
  price: 0,
  features: [
    "1 Form",
    "200 submissions per month",
    "Basic form analytics",
    "Form validation",
    "Standard support"
  ]
};

Customer Portal

Mantlz provides access to the Stripe customer portal for subscription management:
import { createPortalSession } from "@/lib/stripe";

const session = await createPortalSession({ userId });

// Redirect user to portal
window.location.href = session.url;

Resend Email Service

Resend handles all transactional emails from Mantlz.

Email Types

  • Welcome emails for new users
  • Form submission notifications
  • Campaign emails
  • Payment receipts
  • Subscription updates
  • Password resets

Setup

1

Create a Resend account

Sign up at resend.com
2

Get your API key

  1. Navigate to API Keys
  2. Click Create API Key
  3. Copy the key (starts with re_)
RESEND_API_KEY="re_..."
3

Add and verify your domain

  1. Go to DomainsAdd Domain
  2. Enter your domain (e.g., mantlz.app)
  3. Add the provided DNS records to your domain:
    • SPF record
    • DKIM record
    • Custom domain MX records
  4. Wait for verification (usually takes a few minutes)
4

Configure from addresses

DEFAULT_FROM_EMAIL="[email protected]"
RESEND_FROM_EMAIL="[email protected]"
NEXT_PUBLIC_APP_DOMAIN="yourdomain.com"

Sending Emails

Example email sending with Resend:
import { resend } from "@/services/email-service";

await resend.emails.send({
  from: '[email protected]',
  to: userEmail,
  subject: 'Form Submission Received',
  html: emailHtml,
});

Email Templates

Mantlz uses React Email for email templates:
import { 
  Html, 
  Head, 
  Body, 
  Container, 
  Section, 
  Text,
  Button 
} from '@react-email/components';

export function WelcomeEmail({ userName }: { userName: string }) {
  return (
    <Html>
      <Head />
      <Body>
        <Container>
          <Section>
            <Text>Welcome to Mantlz, {userName}!</Text>
            <Button href="https://mantlz.app/dashboard">
              Get Started
            </Button>
          </Section>
        </Container>
      </Body>
    </Html>
  );
}

Sanity CMS

Sanity provides headless CMS functionality for blog posts and marketing content.

Configuration

NEXT_PUBLIC_SANITY_PROJECT_ID="vsce8bkp"
NEXT_PUBLIC_SANITY_DATASET="production"
NEXT_PUBLIC_SANITY_API_VERSION="2025-05-08"

Client Setup

src/sanity/env.ts
export const apiVersion = 
  process.env.NEXT_PUBLIC_SANITY_API_VERSION || '2025-05-08';

export const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET;
export const projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID;
Sanity is optional. If you’re not using the blog/marketing features, you can skip this integration.

Upstash Redis (Rate Limiting)

Upstash Redis provides serverless rate limiting.

Setup

1

Create an Upstash account

Sign up at upstash.com
2

Create a Redis database

  1. Click Create Database
  2. Choose a name
  3. Select a region (choose closest to your deployment)
  4. Click Create
3

Get connection details

Copy the REST API credentials:
UPSTASH_REDIS_REST_URL="https://your-redis.upstash.io"
UPSTASH_REDIS_REST_TOKEN="your_token"
4

Configure rate limits (optional)

RATE_LIMIT_REQUESTS="100"  # Requests per window
RATE_LIMIT_WINDOW="60"     # Window in seconds
RATE_LIMIT_TIMEOUT="5000"  # Timeout in ms

Rate Limit Configuration

src/lib/ratelimiter.ts
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";

const redis = new Redis({
  url: process.env.UPSTASH_REDIS_REST_URL,
  token: process.env.UPSTASH_REDIS_REST_TOKEN,
});

export const ratelimit = new Ratelimit({
  redis,
  limiter: Ratelimit.slidingWindow(
    parseInt(process.env.RATE_LIMIT_REQUESTS || "100"),
    `${process.env.RATE_LIMIT_WINDOW || "60"}s`
  ),
});

PostHog Analytics

PostHog provides product analytics and feature flags.

Setup

1

Create a PostHog account

Sign up at posthog.com or use PostHog Cloud
2

Get your project API key

NEXT_PUBLIC_POSTHOG_KEY="phc_..."
NEXT_PUBLIC_POSTHOG_HOST="https://app.posthog.com"

Client Configuration

src/lib/posthog.ts
import posthog from 'posthog-js';

if (typeof window !== 'undefined') {
  posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY || '', {
    api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com',
    loaded: (posthog) => {
      if (process.env.NODE_ENV === 'development') posthog.debug();
    },
  });
}

Sentry Error Tracking

Sentry provides error tracking and performance monitoring.

Setup

1

Create a Sentry project

  1. Sign up at sentry.io
  2. Create a new project
  3. Select Next.js as the platform
2

Get your DSN

NEXT_PUBLIC_SENTRY_DSN="https://[email protected]/xxx"

Configuration Files

Sentry configuration is already set up in:
  • sentry.edge.config.ts - Edge runtime configuration
  • sentry.server.config.ts - Server runtime configuration

Uploadcare (File Uploads)

Uploadcare handles file uploads for form submissions.

Setup

NEXT_PUBLIC_UPLOADCARE_PUBLIC_KEY="your_public_key"
File uploads are optional. Forms will still work without Uploadcare, but file upload fields will be disabled.

Integration Checklist

Required for Core Functionality

  • Clerk - User authentication
  • Stripe - Payment processing
  • Resend - Email delivery
  • PostgreSQL - Database

Optional Enhancements

  • Upstash Redis - Rate limiting
  • PostHog - Product analytics
  • Sentry - Error tracking
  • Sanity - Blog/marketing content
  • Uploadcare - File uploads

Troubleshooting

  1. Verify NEXT_PUBLIC_APP_URL is set correctly
  2. Check that redirect URLs in Clerk dashboard match your environment variables
  3. Ensure allowed origins include your domain
  4. Clear browser cookies and try again
  1. Verify you’re using the correct API keys (test vs production)
  2. Check that price IDs match your Stripe products
  3. Ensure NEXT_PUBLIC_APP_URL is set correctly for callbacks
  4. Check Stripe dashboard logs for error details
  1. Verify Resend API key is correct
  2. Check that your domain is verified in Resend
  3. Ensure from address uses your verified domain
  4. Check Resend dashboard for delivery logs
  5. Verify DNS records are correctly configured
  1. Confirm Upstash Redis credentials are correct
  2. Test Redis connection
  3. Check that middleware is properly configured
  4. Verify rate limit values are set correctly

Next Steps

Webhooks

Configure webhook endpoints for Stripe and other services

Environment Setup

Complete environment variable reference

Self-Hosting

Deploy Mantlz on your infrastructure

API Reference

Explore the Mantlz API

Build docs developers (and LLMs) love