chore: Replace references to deprecated services

This commit is contained in:
Dries Augustyns
2025-12-31 15:08:26 +01:00
parent 289c633189
commit 7648f6e1eb
51 changed files with 163 additions and 183 deletions
+4 -4
View File
@@ -27,10 +27,10 @@ WIKI_URI=http://localhost:1000
# NEXT_PUBLIC_* variables are used for client-side code and sitemap generation
# Use placeholder URLs that will be replaced at Docker container runtime
NEXT_PUBLIC_API_URI=https://api.useplunk.com
NEXT_PUBLIC_DASHBOARD_URI=https://app.useplunk.com
NEXT_PUBLIC_LANDING_URI=https://www.useplunk.com
NEXT_PUBLIC_WIKI_URI=https://docs.useplunk.com
NEXT_PUBLIC_API_URI=https://next-api.useplunk.com
NEXT_PUBLIC_DASHBOARD_URI=https://next-app.useplunk.com
NEXT_PUBLIC_LANDING_URI=https://next.useplunk.com
NEXT_PUBLIC_WIKI_URI=https://next-wiki.useplunk.com
# Set to 'true' if using HTTPS in production (behind a reverse proxy/load balancer)
# This affects how application URIs are auto-generated from domain names
+3 -3
View File
@@ -67,9 +67,9 @@ to run them separately (e.g., for debugging), use `dev:server` and `dev:worker`
- HTTP API endpoints for the platform
- Background cron jobs (workflow processor, domain verification)
- **Worker process** (separate): BullMQ worker for processing email, campaign, and workflow queues
- **web**: Next.js app (Pages Router) - Main platform (app.useplunk.com)
- **landing**: Next.js app (Pages Router) - Marketing site (www.useplunk.com)
- **wiki**: Next.js app - Documentation site (docs.useplunk.com)
- **web**: Next.js app (Pages Router) - Main platform (next-app.useplunk.com)
- **landing**: Next.js app (Pages Router) - Marketing site (next.useplunk.com)
- **wiki**: Next.js app - Documentation site (next-wiki.useplunk.com)
### Background Job Architecture
+3 -3
View File
@@ -10,8 +10,8 @@ Plunk V2 is built as a modern Turborepo monorepo with the following structure:
- **api**: Express.js API server with background worker process (BullMQ)
- **web**: Next.js dashboard application (app.useplunk.com)
- **landing**: Next.js marketing site (www.useplunk.com)
- **wiki**: Next.js documentation site (docs.useplunk.com)
- **landing**: Next.js marketing site (next.useplunk.com)
- **wiki**: Next.js documentation site (next-wiki.useplunk.com)
### Shared Packages (`packages/`)
@@ -135,7 +135,7 @@ between groups.
## Need Help?
- Check the [documentation](https://docs.useplunk.com)
- Check the [documentation](https://next-wiki.useplunk.com)
- Open an issue for bugs or feature requests
- Join our community discussions
+1 -1
View File
@@ -1,5 +1,5 @@
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: process.env.NEXT_PUBLIC_LANDING_URI || 'https://www.useplunk.com',
siteUrl: process.env.NEXT_PUBLIC_LANDING_URI || 'https://next.useplunk.com',
generateRobotsTxt: true,
};
@@ -25,7 +25,7 @@ export function GuideLayout({
readTime,
children,
canonical,
ogImage = 'https://www.useplunk.com/assets/card.png',
ogImage = 'https://next.useplunk.com/assets/card.png',
}: GuideLayoutProps) {
const [headings, setHeadings] = useState<{id: string; text: string; level: number}[]>([]);
const [activeId, setActiveId] = useState<string>('');
@@ -74,8 +74,8 @@ export function GuideLayout({
// Generate breadcrumb items
const breadcrumbItems = [
{position: 1, name: 'Home', item: 'https://www.useplunk.com'},
{position: 2, name: 'Guides', item: 'https://www.useplunk.com/guides'},
{position: 1, name: 'Home', item: 'https://next.useplunk.com'},
{position: 2, name: 'Guides', item: 'https://next.useplunk.com/guides'},
{position: 3, name: title, item: canonical || ''},
];
+1 -1
View File
@@ -63,7 +63,7 @@ export default function WithProviders(props: AppProps) {
title: 'Plunk | The Open-Source Email Platform',
description:
'Open-source email automation platform with workflows, segments, and developer API. Scale from 0 to millions of emails at $0.001 per email. Self-hostable and privacy-first.',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk'}],
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk'}],
}}
additionalMetaTags={[{property: 'title', content: 'Plunk | The Open-Source Email Platform'}]}
/>
@@ -10,7 +10,7 @@ export default function EmailAPIGuide() {
description="Complete guide to email APIs: how they work, implementation examples, best practices, and choosing the right solution for your application."
lastUpdated="2025-12-20"
readTime="12 min"
canonical="https://www.useplunk.com/guides/email-api-guide"
canonical="https://next.useplunk.com/guides/email-api-guide"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -132,7 +132,7 @@ export default function EmailAPIGuide() {
language="javascript"
title="Node.js Example"
code={`// Using fetch (Node.js 18+ or with node-fetch)
const response = await fetch('https://api.useplunk.com/v1/send', {
const response = await fetch('https://next-api.useplunk.com/v1/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -167,7 +167,7 @@ if (response.ok) {
code={`import requests
response = requests.post(
'https://api.useplunk.com/v1/send',
'https://next-api.useplunk.com/v1/send',
headers={
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
@@ -195,7 +195,7 @@ else:
language="php"
title="PHP Example"
code={`<?php
$ch = curl_init('https://api.useplunk.com/v1/send');
$ch = curl_init('https://next-api.useplunk.com/v1/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@@ -235,7 +235,7 @@ if ($httpCode === 200) {
code={`require 'net/http'
require 'json'
uri = URI('https://api.useplunk.com/v1/send')
uri = URI('https://next-api.useplunk.com/v1/send')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
@@ -295,7 +295,7 @@ func main() {
jsonData, _ := json.Marshal(email)
req, _ := http.NewRequest("POST", "https://api.useplunk.com/v1/send", bytes.NewBuffer(jsonData))
req, _ := http.NewRequest("POST", "https://next-api.useplunk.com/v1/send", bytes.NewBuffer(jsonData))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
@@ -10,7 +10,7 @@ export default function EmailBounceRate() {
description="Understand email bounce rates, the difference between hard and soft bounces, and proven strategies to reduce bounces and protect your sender reputation."
lastUpdated="2025-12-20"
readTime="9 min"
canonical="https://www.useplunk.com/guides/email-bounce-rate"
canonical="https://next.useplunk.com/guides/email-bounce-rate"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -10,7 +10,7 @@ export default function EmailClickThroughRate() {
description="Learn what affects email click-through rates, industry benchmarks, and proven tactics to optimize CTAs and boost engagement."
lastUpdated="2025-12-20"
readTime="10 min"
canonical="https://www.useplunk.com/guides/email-click-through-rate"
canonical="https://next.useplunk.com/guides/email-click-through-rate"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -9,7 +9,7 @@ export default function EmailDeliverability() {
description="Learn proven strategies to improve email deliverability, avoid spam filters, and maximize inbox placement rates. Complete guide with best practices."
lastUpdated="2025-12-20"
readTime="12 min"
canonical="https://www.useplunk.com/guides/email-deliverability"
canonical="https://next.useplunk.com/guides/email-deliverability"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -306,9 +306,7 @@ export default function EmailDeliverability() {
{/* Monitoring */}
<section id="monitoring" className="mb-12">
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Monitoring Email Deliverability</h2>
<p className="text-neutral-700 leading-relaxed mb-6">
Track these metrics to stay on top of deliverability:
</p>
<p className="text-neutral-700 leading-relaxed mb-6">Track these metrics to stay on top of deliverability:</p>
<div className="grid gap-6 md:grid-cols-2">
<div className="rounded-xl border border-neutral-200 bg-white p-6">
@@ -9,7 +9,7 @@ export default function EmailMarketingBestPractices() {
description="Master email marketing with proven best practices for content, design, timing, deliverability, and compliance. Comprehensive guide for 2025."
lastUpdated="2025-12-20"
readTime="15 min"
canonical="https://www.useplunk.com/guides/email-marketing-best-practices"
canonical="https://next.useplunk.com/guides/email-marketing-best-practices"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -10,7 +10,7 @@ export default function EmailOpenRate() {
description="Learn what affects email open rates, industry benchmarks, and proven tactics to improve opens. Complete guide with actionable tips."
lastUpdated="2025-12-20"
readTime="10 min"
canonical="https://www.useplunk.com/guides/email-open-rate"
canonical="https://next.useplunk.com/guides/email-open-rate"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -10,7 +10,7 @@ export default function EmailSenderReputation() {
description="Learn how sender reputation works, what affects it, and proven strategies to build and maintain a positive reputation for maximum deliverability."
lastUpdated="2025-12-20"
readTime="11 min"
canonical="https://www.useplunk.com/guides/email-sender-reputation"
canonical="https://next.useplunk.com/guides/email-sender-reputation"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
+3 -3
View File
@@ -103,13 +103,13 @@ export default function GuidesIndex() {
<NextSeo
title="Email Marketing & Deliverability Guides | Plunk"
description="Learn email best practices, authentication (DKIM, SPF, DMARC), deliverability optimization, and more. Free guides from Plunk."
canonical="https://www.useplunk.com/guides"
canonical="https://next.useplunk.com/guides"
openGraph={{
title: 'Email Marketing & Deliverability Guides | Plunk',
description:
'Learn email best practices, authentication (DKIM, SPF, DMARC), deliverability optimization, and more.',
url: 'https://www.useplunk.com/guides',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk Guides'}],
url: 'https://next.useplunk.com/guides',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk Guides'}],
}}
/>
@@ -9,7 +9,7 @@ export default function TransactionalVsMarketingEmail() {
description="Understand the critical differences between transactional and marketing emails, including legal requirements, deliverability, and best practices."
lastUpdated="2025-12-20"
readTime="10 min"
canonical="https://www.useplunk.com/guides/transactional-vs-marketing-email"
canonical="https://next.useplunk.com/guides/transactional-vs-marketing-email"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -10,7 +10,7 @@ export default function WhatIsDKIM() {
description="Learn how DKIM (DomainKeys Identified Mail) protects your emails from spoofing and improves deliverability. Complete guide with setup examples."
lastUpdated="2025-12-20"
readTime="8 min"
canonical="https://www.useplunk.com/guides/what-is-dkim"
canonical="https://next.useplunk.com/guides/what-is-dkim"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -10,7 +10,7 @@ export default function WhatIsDMARC() {
description="Learn how DMARC works with SPF and DKIM to protect your domain from email spoofing. Complete setup guide with policy examples."
lastUpdated="2025-12-20"
readTime="9 min"
canonical="https://www.useplunk.com/guides/what-is-dmarc"
canonical="https://next.useplunk.com/guides/what-is-dmarc"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -10,7 +10,7 @@ export default function WhatIsSPF() {
description="Learn how SPF records work, prevent email spoofing, and improve deliverability. Complete guide with setup examples and best practices."
lastUpdated="2025-12-20"
readTime="7 min"
canonical="https://www.useplunk.com/guides/what-is-spf"
canonical="https://next.useplunk.com/guides/what-is-spf"
>
{/* Introduction */}
<section id="introduction" className="mb-12">
+2 -2
View File
@@ -110,8 +110,8 @@ export default function Index() {
<span data-custom-class="body_text">
Visit our website <bdt className="block-component" /> at{' '}
<bdt className="question">
<a href="https://www.useplunk.com" target="_blank" data-custom-class="link">
https://www.useplunk.com
<a href="https://next.useplunk.com" target="_blank" data-custom-class="link">
https://next.useplunk.com
</a>
</bdt>
<span style={{fontSize: '15px'}}>
+4 -4
View File
@@ -390,8 +390,8 @@ export default function Index() {
data-id="fdf30452-99b8-c68b-5cdf-34af764cd1fd"
data-type="question"
>
<a href="https://www.useplunk.com" target="_blank" data-custom-class="link">
https://www.useplunk.com
<a href="https://next.useplunk.com" target="_blank" data-custom-class="link">
https://next.useplunk.com
</a>
</bdt>{' '}
website as well as any other media form, media channel, mobile website or mobile application related,
@@ -3165,8 +3165,8 @@ export default function Index() {
data-id="d10c7fd7-0685-12ac-c717-cbc45ff916d1"
data-type="question"
>
<a href="https://www.useplunk.com/privacy" target="_blank" data-custom-class="link">
https://www.useplunk.com/privacy
<a href="https://next.useplunk.com/privacy" target="_blank" data-custom-class="link">
https://next.useplunk.com/privacy
</a>
</bdt>
</strong>
+3 -3
View File
@@ -32,13 +32,13 @@ export default function ToolsIndex() {
<NextSeo
title="Free Email Tools | Markdown to Email & Email Verification | Plunk"
description="Free tools for email developers: Convert markdown to email-safe HTML and verify email addresses instantly. No sign-up required."
canonical="https://www.useplunk.com/tools"
canonical="https://next.useplunk.com/tools"
openGraph={{
title: 'Free Email Tools | Markdown to Email & Email Verification | Plunk',
description:
'Free tools for email developers: Convert markdown to email-safe HTML and verify email addresses instantly.',
url: 'https://www.useplunk.com/tools',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk Email Tools'}],
url: 'https://next.useplunk.com/tools',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk Email Tools'}],
}}
/>
@@ -28,13 +28,13 @@ export default function MarkdownToEmail() {
<NextSeo
title="Free Markdown to Email HTML Converter | Plunk"
description="Convert markdown and rich text to email-safe HTML instantly. Free online tool with live preview. Perfect for email developers and marketers."
canonical="https://www.useplunk.com/tools/markdown-to-email"
canonical="https://next.useplunk.com/tools/markdown-to-email"
openGraph={{
title: 'Free Markdown to Email HTML Converter | Plunk',
description:
'Convert markdown and rich text to email-safe HTML instantly. Free online tool with live preview.',
url: 'https://www.useplunk.com/tools/markdown-to-email',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk Email HTML Converter'}],
url: 'https://next.useplunk.com/tools/markdown-to-email',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk Email HTML Converter'}],
}}
/>
@@ -36,12 +36,12 @@ export default function VerifyEmailPage() {
<NextSeo
title="Free Email Verification Tool | Check Email Validity | Plunk"
description="Verify email addresses instantly. Check for typos, disposable domains, MX records, and more. Free email validation tool with detailed results."
canonical="https://www.useplunk.com/tools/verify-email"
canonical="https://next.useplunk.com/tools/verify-email"
openGraph={{
title: 'Free Email Verification Tool | Check Email Validity | Plunk',
description: 'Verify email addresses instantly. Check for typos, disposable domains, MX records, and more.',
url: 'https://www.useplunk.com/tools/verify-email',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk Email Verification Tool'}],
url: 'https://next.useplunk.com/tools/verify-email',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk Email Verification Tool'}],
}}
/>
+8 -10
View File
@@ -33,7 +33,7 @@ const faqs: FAQ[] = [
'ActiveCampaign starts at $29/month for basic features and quickly scales to $149/month or more for automation features. Plunk uses pay-as-you-go pricing—you only pay for emails sent. For email-focused needs, Plunk typically costs 50-80% less than ActiveCampaign while providing the same email automation capabilities.',
},
{
question: 'Can Plunk match ActiveCampaign\'s automation capabilities?',
question: "Can Plunk match ActiveCampaign's automation capabilities?",
answer:
'For email automation, yes. Plunk supports workflow automation, event-based triggers, and audience segmentation just like ActiveCampaign. The difference is Plunk focuses purely on email, while ActiveCampaign includes CRM, sales automation, and ML-powered recommendations. If you need email automation without sales/CRM features, Plunk delivers the same capability with simpler implementation.',
},
@@ -45,7 +45,7 @@ const faqs: FAQ[] = [
{
question: 'What ActiveCampaign features does Plunk not have?',
answer:
'Plunk focuses on email, so it doesn\'t include ActiveCampaign\'s CRM, sales pipeline management, lead scoring, SMS marketing, or machine learning features. If you need those, ActiveCampaign is better. If you want powerful email automation without the enterprise complexity, Plunk is the simpler choice.',
"Plunk focuses on email, so it doesn't include ActiveCampaign's CRM, sales pipeline management, lead scoring, SMS marketing, or machine learning features. If you need those, ActiveCampaign is better. If you want powerful email automation without the enterprise complexity, Plunk is the simpler choice.",
},
];
@@ -58,13 +58,13 @@ export default function ActiveCampaignComparison() {
<NextSeo
title="ActiveCampaign Alternative: Open-Source & Affordable | Plunk"
description="Powerful email automation without ActiveCampaign's complexity and cost. Open-source, developer-friendly, pay-as-you-go pricing. No CRM bloat."
canonical="https://www.useplunk.com/vs/activecampaign"
canonical="https://next.useplunk.com/vs/activecampaign"
openGraph={{
title: 'ActiveCampaign Alternative: Open-Source & Affordable | Plunk',
description:
"Powerful email automation without ActiveCampaign's complexity and cost. Open-source, developer-friendly, pay-as-you-go pricing.",
url: 'https://www.useplunk.com/vs/activecampaign',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs ActiveCampaign'}],
url: 'https://next.useplunk.com/vs/activecampaign',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs ActiveCampaign'}],
}}
/>
@@ -233,9 +233,7 @@ export default function ActiveCampaignComparison() {
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
className={'mb-20 text-center'}
>
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>
Automation Without Complexity
</h2>
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>Automation Without Complexity</h2>
</motion.div>
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
@@ -318,8 +316,8 @@ export default function ActiveCampaignComparison() {
</div>
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source</h3>
<p className={'mt-3 leading-relaxed text-neutral-600'}>
AGPL-3.0 licensed. Full transparency into how your emails are processed. Contribute features,
understand the system. ActiveCampaign is proprietary.
AGPL-3.0 licensed. Full transparency into how your emails are processed. Contribute features, understand
the system. ActiveCampaign is proprietary.
</p>
</motion.div>
+11 -15
View File
@@ -25,7 +25,7 @@ const faqs: FAQ[] = [
{
question: 'When should I choose Bento over Plunk?',
answer:
'Choose Bento if you need an all-in-one platform with CRM, live chat, and customer relationship features alongside email. Bento is designed for small businesses and creators who want everything in one place. Choose Plunk if you\'re a developer who needs focused email automation without CRM bloat—perfect for integrating email into your product.',
"Choose Bento if you need an all-in-one platform with CRM, live chat, and customer relationship features alongside email. Bento is designed for small businesses and creators who want everything in one place. Choose Plunk if you're a developer who needs focused email automation without CRM bloat—perfect for integrating email into your product.",
},
{
question: 'What is the pricing difference between Plunk and Bento?',
@@ -45,7 +45,7 @@ const faqs: FAQ[] = [
{
question: 'Is migration from Bento to Plunk easy?',
answer:
'For email features, yes. Export your contacts from Bento, import them to Plunk, recreate your workflows using our API or dashboard, and integrate Plunk into your application. If you rely heavily on Bento\'s CRM, live chat, or multi-channel features, you\'ll need separate tools for those. Most email-only migrations take a few hours.',
"For email features, yes. Export your contacts from Bento, import them to Plunk, recreate your workflows using our API or dashboard, and integrate Plunk into your application. If you rely heavily on Bento's CRM, live chat, or multi-channel features, you'll need separate tools for those. Most email-only migrations take a few hours.",
},
];
@@ -58,13 +58,13 @@ export default function BentoComparison() {
<NextSeo
title="Bento Alternative: Developer-First Email Platform | Plunk"
description="Open-source alternative to Bento. API-first email platform without CRM bloat. Self-hostable, pay-as-you-go pricing, built for developers."
canonical="https://www.useplunk.com/vs/bento"
canonical="https://next.useplunk.com/vs/bento"
openGraph={{
title: 'Bento Alternative: Developer-First Email Platform | Plunk',
description:
'Open-source alternative to Bento. API-first email platform without CRM bloat. Self-hostable, pay-as-you-go pricing.',
url: 'https://www.useplunk.com/vs/bento',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs Bento'}],
url: 'https://next.useplunk.com/vs/bento',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs Bento'}],
}}
/>
@@ -233,9 +233,7 @@ export default function BentoComparison() {
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
className={'mb-20 text-center'}
>
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>
Developer-First Email Platform
</h2>
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>Developer-First Email Platform</h2>
</motion.div>
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
@@ -339,8 +337,8 @@ export default function BentoComparison() {
</div>
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
<p className={'mt-3 leading-relaxed text-neutral-600'}>
Deploy on your infrastructure with Docker. Full data control, compliance-ready, no vendor lock-in.
Bento is cloud-only.
Deploy on your infrastructure with Docker. Full data control, compliance-ready, no vendor lock-in. Bento
is cloud-only.
</p>
</motion.div>
@@ -360,8 +358,8 @@ export default function BentoComparison() {
</div>
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Email-Focused</h3>
<p className={'mt-3 leading-relaxed text-neutral-600'}>
Do one thing exceptionally well: email. No feature bloat, no CRM complexity, no multi-channel
confusion. Just powerful email automation.
Do one thing exceptionally well: email. No feature bloat, no CRM complexity, no multi-channel confusion.
Just powerful email automation.
</p>
</motion.div>
</div>
@@ -394,9 +392,7 @@ export default function BentoComparison() {
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
className={'mx-auto max-w-3xl text-center'}
>
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>
Get focused email automation
</h2>
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>Get focused email automation</h2>
<p className={'mt-6 text-lg text-neutral-600'}>
Join developers choosing focused email solutions over all-in-one complexity. Start free, no credit card
required.
+3 -3
View File
@@ -57,13 +57,13 @@ export default function BrevoComparison() {
<NextSeo
title="Brevo (Sendinblue) Alternative: Developer-First & Open Source | Plunk"
description="Plunk offers a simpler, developer-focused alternative to Brevo with pay-as-you-go pricing, open-source code, and self-hosting. No contact limits."
canonical="https://www.useplunk.com/vs/brevo"
canonical="https://next.useplunk.com/vs/brevo"
openGraph={{
title: 'Brevo (Sendinblue) Alternative: Developer-First & Open Source | Plunk',
description:
'Plunk offers a simpler, developer-focused alternative to Brevo with pay-as-you-go pricing, open-source code, and self-hosting.',
url: 'https://www.useplunk.com/vs/brevo',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs Brevo'}],
url: 'https://next.useplunk.com/vs/brevo',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs Brevo'}],
}}
/>
+5 -7
View File
@@ -45,7 +45,7 @@ const faqs: FAQ[] = [
{
question: 'How easy is it to migrate from ConvertKit to Plunk?',
answer:
'Migration is straightforward. Export your subscribers from ConvertKit as CSV, import them to Plunk via our API or dashboard, recreate your email sequences using our workflow builder, and update your forms to use Plunk\'s API. Most migrations can be completed in a few hours. You\'ll need to rebuild landing pages separately if you rely on ConvertKit\'s landing page feature.',
"Migration is straightforward. Export your subscribers from ConvertKit as CSV, import them to Plunk via our API or dashboard, recreate your email sequences using our workflow builder, and update your forms to use Plunk's API. Most migrations can be completed in a few hours. You'll need to rebuild landing pages separately if you rely on ConvertKit's landing page feature.",
},
];
@@ -58,13 +58,13 @@ export default function ConvertkitComparison() {
<NextSeo
title="ConvertKit Alternative for Developers | Plunk"
description="Developer-first alternative to ConvertKit. Pay per email instead of per subscriber. Open-source, self-hostable, with powerful automation—no landing page bloat."
canonical="https://www.useplunk.com/vs/convertkit"
canonical="https://next.useplunk.com/vs/convertkit"
openGraph={{
title: 'ConvertKit Alternative for Developers | Plunk',
description:
'Developer-first alternative to ConvertKit. Pay per email instead of per subscriber. Open-source, self-hostable, with powerful automation.',
url: 'https://www.useplunk.com/vs/convertkit',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs ConvertKit'}],
url: 'https://next.useplunk.com/vs/convertkit',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs ConvertKit'}],
}}
/>
@@ -141,9 +141,7 @@ export default function ConvertkitComparison() {
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
className={'mb-16 text-center'}
>
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>
Pay for Emails, Not Subscribers
</h2>
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>Pay for Emails, Not Subscribers</h2>
<p className={'mt-4 text-lg text-neutral-600'}>Pricing that grows with usage, not list size</p>
</motion.div>
+3 -3
View File
@@ -53,13 +53,13 @@ export default function CustomerioComparison() {
<NextSeo
title="Customer.io Alternative: Open-Source & Developer-Focused | Plunk"
description="Compare Plunk and Customer.io. Customer.io is powerful but complex. Plunk is open-source, developer-friendly, with simple workflows and transparent pricing."
canonical="https://www.useplunk.com/vs/customerio"
canonical="https://next.useplunk.com/vs/customerio"
openGraph={{
title: 'Customer.io Alternative: Open-Source & Developer-Focused | Plunk',
description:
'Compare Plunk and Customer.io. Plunk is open-source, developer-friendly, with simple workflows and transparent pricing.',
url: 'https://www.useplunk.com/vs/customerio',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs Customer.io'}],
url: 'https://next.useplunk.com/vs/customerio',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs Customer.io'}],
}}
/>
+3 -3
View File
@@ -96,13 +96,13 @@ export default function CompetitorsIndex() {
<NextSeo
title="Plunk vs Email Competitors | Compare Email Platforms"
description="Compare Plunk with Postmark, SendGrid, Mailgun, Mailchimp, ConvertKit, ActiveCampaign, Klaviyo, MailerLite, and more. See why Plunk offers transactional emails plus marketing features in one open-source platform."
canonical="https://www.useplunk.com/vs"
canonical="https://next.useplunk.com/vs"
openGraph={{
title: 'Plunk vs Email Competitors | Compare Email Platforms',
description:
'Compare Plunk with 13 leading email platforms. Transactional + marketing emails in one open-source solution.',
url: 'https://www.useplunk.com/vs',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs Competitors'}],
url: 'https://next.useplunk.com/vs',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs Competitors'}],
}}
/>
+4 -4
View File
@@ -45,7 +45,7 @@ const faqs: FAQ[] = [
{
question: 'What Klaviyo features does Plunk not have?',
answer:
'Plunk focuses on email, so it doesn\'t include Klaviyo\'s SMS marketing, native e-commerce platform integrations, AI-powered product recommendations, or predictive analytics. If you need those enterprise features and have the budget, Klaviyo is better. If you want powerful email automation at a fraction of the cost, Plunk delivers.',
"Plunk focuses on email, so it doesn't include Klaviyo's SMS marketing, native e-commerce platform integrations, AI-powered product recommendations, or predictive analytics. If you need those enterprise features and have the budget, Klaviyo is better. If you want powerful email automation at a fraction of the cost, Plunk delivers.",
},
];
@@ -58,13 +58,13 @@ export default function KlaviyoComparison() {
<NextSeo
title="Klaviyo Alternative: Affordable E-commerce Email | Plunk"
description="E-commerce email automation without Klaviyo's price tag. Pay-as-you-go pricing, open-source, self-hostable. Perfect for developers building e-commerce."
canonical="https://www.useplunk.com/vs/klaviyo"
canonical="https://next.useplunk.com/vs/klaviyo"
openGraph={{
title: 'Klaviyo Alternative: Affordable E-commerce Email | Plunk',
description:
"E-commerce email automation without Klaviyo's price tag. Pay-as-you-go pricing, open-source, self-hostable.",
url: 'https://www.useplunk.com/vs/klaviyo',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs Klaviyo'}],
url: 'https://next.useplunk.com/vs/klaviyo',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs Klaviyo'}],
}}
/>
+3 -3
View File
@@ -57,13 +57,13 @@ export default function LoopsComparison() {
<NextSeo
title="Loops Alternative: Open Source & Self-Hostable | Plunk"
description="Plunk offers an open-source alternative to Loops with pay-as-you-go pricing, self-hosting, and no contact limits. Same modern features, full transparency."
canonical="https://www.useplunk.com/vs/loops"
canonical="https://next.useplunk.com/vs/loops"
openGraph={{
title: 'Loops Alternative: Open Source & Self-Hostable | Plunk',
description:
'Plunk offers an open-source alternative to Loops with pay-as-you-go pricing, self-hosting, and no contact limits.',
url: 'https://www.useplunk.com/vs/loops',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs Loops'}],
url: 'https://next.useplunk.com/vs/loops',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs Loops'}],
}}
/>
+3 -3
View File
@@ -58,13 +58,13 @@ export default function MailchimpComparison() {
<NextSeo
title="Mailchimp Alternative for Developers | Plunk"
description="Plunk is Mailchimp for developers: code-first email platform with modern API. Pay per email, not per contact. Transactional + marketing in one platform."
canonical="https://www.useplunk.com/vs/mailchimp"
canonical="https://next.useplunk.com/vs/mailchimp"
openGraph={{
title: 'Mailchimp Alternative for Developers | Plunk',
description:
'Plunk is Mailchimp for developers: code-first email platform with modern API. Pay per email, not per contact.',
url: 'https://www.useplunk.com/vs/mailchimp',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs Mailchimp'}],
url: 'https://next.useplunk.com/vs/mailchimp',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs Mailchimp'}],
}}
/>
+9 -9
View File
@@ -25,7 +25,7 @@ const faqs: FAQ[] = [
{
question: 'What is the main difference between Plunk and MailerLite?',
answer:
'The main difference is that Plunk is open-source and self-hostable, while MailerLite is proprietary SaaS. Plunk uses pay-per-email pricing versus MailerLite\'s pay-per-subscriber model. Both are developer-friendly, but Plunk is API-first with full code transparency, while MailerLite focuses more on visual email builders with good API support.',
"The main difference is that Plunk is open-source and self-hostable, while MailerLite is proprietary SaaS. Plunk uses pay-per-email pricing versus MailerLite's pay-per-subscriber model. Both are developer-friendly, but Plunk is API-first with full code transparency, while MailerLite focuses more on visual email builders with good API support.",
},
{
question: 'Is Plunk more expensive than MailerLite?',
@@ -40,12 +40,12 @@ const faqs: FAQ[] = [
{
question: 'Does Plunk have a drag-and-drop builder like MailerLite?',
answer:
'Plunk has a basic email editor, but most users manage templates using HTML/code for full control, version control, and reusability. MailerLite excels at visual drag-and-drop building for non-technical users. If you\'re a developer who prefers code-based templates, Plunk is better. If you need rich visual builders for marketers, MailerLite is better.',
"Plunk has a basic email editor, but most users manage templates using HTML/code for full control, version control, and reusability. MailerLite excels at visual drag-and-drop building for non-technical users. If you're a developer who prefers code-based templates, Plunk is better. If you need rich visual builders for marketers, MailerLite is better.",
},
{
question: 'How does Plunk\'s API compare to MailerLite?',
question: "How does Plunk's API compare to MailerLite?",
answer:
'Both have modern REST APIs, but Plunk\'s API is designed with developers as the primary user. Plunk prioritizes API-first workflows, making it easier to integrate email into your application. MailerLite has a good API but is built UI-first with API as secondary. For programmatic email sending and automation, Plunk offers a superior developer experience.',
"Both have modern REST APIs, but Plunk's API is designed with developers as the primary user. Plunk prioritizes API-first workflows, making it easier to integrate email into your application. MailerLite has a good API but is built UI-first with API as secondary. For programmatic email sending and automation, Plunk offers a superior developer experience.",
},
];
@@ -58,13 +58,13 @@ export default function MailerliteComparison() {
<NextSeo
title="MailerLite Alternative: Open-Source & Self-Hostable | Plunk"
description="The truly developer-first MailerLite alternative. Open-source, self-hostable, pay per email not per subscriber. Modern API, full transparency."
canonical="https://www.useplunk.com/vs/mailerlite"
canonical="https://next.useplunk.com/vs/mailerlite"
openGraph={{
title: 'MailerLite Alternative: Open-Source & Self-Hostable | Plunk',
description:
'The truly developer-first MailerLite alternative. Open-source, self-hostable, pay per email not per subscriber.',
url: 'https://www.useplunk.com/vs/mailerlite',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs MailerLite'}],
url: 'https://next.useplunk.com/vs/mailerlite',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs MailerLite'}],
}}
/>
@@ -360,8 +360,8 @@ export default function MailerliteComparison() {
</div>
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Unlimited Contacts</h3>
<p className={'mt-3 leading-relaxed text-neutral-600'}>
Store unlimited contacts without additional cost. Your database grows freely, pricing stays
predictable based on emails sent.
Store unlimited contacts without additional cost. Your database grows freely, pricing stays predictable
based on emails sent.
</p>
</motion.div>
</div>
+3 -3
View File
@@ -53,13 +53,13 @@ export default function MailgunComparison() {
<NextSeo
title="Mailgun Alternative: Open-Source with Marketing & Automation | Plunk"
description="Compare Plunk and Mailgun. Mailgun focuses on transactional emails, while Plunk adds marketing campaigns, workflows, and is open-source."
canonical="https://www.useplunk.com/vs/mailgun"
canonical="https://next.useplunk.com/vs/mailgun"
openGraph={{
title: 'Mailgun Alternative: Open-Source with Marketing & Automation | Plunk',
description:
'Compare Plunk and Mailgun. Mailgun is excellent for transactional emails. Plunk adds marketing, workflows, and is open-source.',
url: 'https://www.useplunk.com/vs/mailgun',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs Mailgun'}],
url: 'https://next.useplunk.com/vs/mailgun',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs Mailgun'}],
}}
/>
+3 -3
View File
@@ -54,13 +54,13 @@ export default function PostmarkComparison() {
<NextSeo
title="Postmark Alternative: Transactional + Marketing Emails | Plunk"
description="Plunk offers everything Postmark has for transactional emails, plus marketing campaigns, workflows, and segmentation. Open-source and self-hostable."
canonical="https://www.useplunk.com/vs/postmark"
canonical="https://next.useplunk.com/vs/postmark"
openGraph={{
title: 'Postmark Alternative: Transactional + Marketing Emails | Plunk',
description:
'Plunk offers everything Postmark has for transactional emails, plus marketing campaigns, workflows, and segmentation.',
url: 'https://www.useplunk.com/vs/postmark',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs Postmark'}],
url: 'https://next.useplunk.com/vs/postmark',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs Postmark'}],
}}
/>
+3 -3
View File
@@ -53,13 +53,13 @@ export default function ResendComparison() {
<NextSeo
title="Plunk vs Resend: Open-Source Alternative with Marketing | Plunk"
description="Compare Plunk and Resend. Resend focuses on transactional emails, while Plunk adds marketing campaigns, workflows, and is open-source. Choose based on your needs."
canonical="https://www.useplunk.com/vs/resend"
canonical="https://next.useplunk.com/vs/resend"
openGraph={{
title: 'Plunk vs Resend: Open-Source Alternative with Marketing',
description:
'Compare Plunk and Resend. Resend focuses on transactional emails, while Plunk adds marketing, workflows, and is open-source.',
url: 'https://www.useplunk.com/vs/resend',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs Resend'}],
url: 'https://next.useplunk.com/vs/resend',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs Resend'}],
}}
/>
+3 -3
View File
@@ -57,13 +57,13 @@ export default function SendGridComparison() {
<NextSeo
title="SendGrid Alternative: Pay-As-You-Go & Open Source | Plunk"
description="Plunk offers pay-as-you-go pricing instead of monthly subscriptions, with a modern API and no complex setup. Open source alternative to SendGrid."
canonical="https://www.useplunk.com/vs/sendgrid"
canonical="https://next.useplunk.com/vs/sendgrid"
openGraph={{
title: 'SendGrid Alternative: Pay-As-You-Go & Open Source | Plunk',
description:
'Plunk offers pay-as-you-go pricing instead of monthly subscriptions, with a modern API and no complex setup.',
url: 'https://www.useplunk.com/vs/sendgrid',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk vs SendGrid'}],
url: 'https://next.useplunk.com/vs/sendgrid',
images: [{url: 'https://next.useplunk.com/assets/card.png', alt: 'Plunk vs SendGrid'}],
}}
/>
+1 -1
View File
@@ -1,5 +1,5 @@
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: process.env.NEXT_PUBLIC_DASHBOARD_URI || 'https://app.useplunk.com',
siteUrl: process.env.NEXT_PUBLIC_DASHBOARD_URI || 'https://next-app.useplunk.com',
generateRobotsTxt: true,
};
+1 -1
View File
@@ -26,7 +26,7 @@ export const baseOptions: BaseLayoutProps = {
{
icon: <AppWindowIcon />,
text: 'Dashboard',
url: 'https://app.useplunk.com',
url: 'https://next-app.useplunk.com',
},
{
icon: <GithubIcon />,
+4 -4
View File
@@ -25,23 +25,23 @@ export default function Layout({children}: {children: ReactNode}) {
{/* Open Graph / Facebook */}
<meta property="og:type" content="website" />
<meta property="og:url" content="https://docs.useplunk.com/" />
<meta property="og:url" content="https://next-wiki.useplunk.com/" />
<meta property="og:title" content="Plunk Documentation" />
<meta
property="og:description"
content="Documentation for Plunk, the open-source email platform. Learn how to integrate Plunk into your application and manage your email communications."
/>
<meta property="og:image" content="https://docs.useplunk.com/assets/card.png" />
<meta property="og:image" content="https://next-wiki.useplunk.com/assets/card.png" />
{/* Twitter */}
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content="https://docs.useplunk.com/" />
<meta property="twitter:url" content="https://next-wiki.useplunk.com/" />
<meta property="twitter:title" content="Plunk Documentation" />
<meta
property="twitter:description"
content="Documentation for Plunk, the open-source email platform. Learn how to integrate Plunk into your application and manage your email communications."
/>
<meta property="twitter:image" content="https://docs.useplunk.com/assets/card.png" />
<meta property="twitter:image" content="https://next-wiki.useplunk.com/assets/card.png" />
{/* Fonts */}
<link rel="preconnect" href="https://fonts.googleapis.com" />
+2 -2
View File
@@ -29,7 +29,7 @@ const getRuntimeEnv = (key: keyof NonNullable<typeof window.__ENV__>) => {
};
export function ApiUrl({path = ''}: {path?: string}) {
const baseUrl = getRuntimeEnv('API_URI') || process.env.NEXT_PUBLIC_API_URI || 'https://api.useplunk.com';
const baseUrl = getRuntimeEnv('API_URI') || process.env.NEXT_PUBLIC_API_URI || 'https://next-api.useplunk.com';
return (
<code>
{baseUrl}
@@ -40,7 +40,7 @@ export function ApiUrl({path = ''}: {path?: string}) {
export function DashboardUrl({path = ''}: {path?: string}) {
const baseUrl =
getRuntimeEnv('DASHBOARD_URI') || process.env.NEXT_PUBLIC_DASHBOARD_URI || 'https://app.useplunk.com';
getRuntimeEnv('DASHBOARD_URI') || process.env.NEXT_PUBLIC_DASHBOARD_URI || 'https://next-app.useplunk.com';
return (
<code>
{baseUrl}
@@ -303,7 +303,7 @@ Successful API requests return a standardized format with `success: true` and a
```typescript
try {
const response = await fetch('https://api.useplunk.com/v1/track', {
const response = await fetch('https://next-api.useplunk.com/v1/track', {
method: 'POST',
headers: {
'Authorization': `Bearer ${publicKey}`,
@@ -361,7 +361,7 @@ try {
import requests
response = requests.post(
'https://api.useplunk.com/v1/track',
'https://next-api.useplunk.com/v1/track',
headers={
'Authorization': f'Bearer {public_key}',
'Content-Type': 'application/json'
@@ -426,7 +426,7 @@ Request IDs are included in:
```javascript
// Example: Logging request ID in your application
const response = await fetch('https://api.useplunk.com/v1/send', {
const response = await fetch('https://next-api.useplunk.com/v1/send', {
// ... your request
});
+7 -11
View File
@@ -1,24 +1,20 @@
import { visit } from 'unist-util-visit';
import {visit} from 'unist-util-visit';
// Default URLs that will be replaced at container startup by sed
const API_URL = process.env.NEXT_PUBLIC_API_URI || 'https://api.useplunk.com';
const DASHBOARD_URL = process.env.NEXT_PUBLIC_DASHBOARD_URI || 'https://app.useplunk.com';
const API_URL = process.env.NEXT_PUBLIC_API_URI || 'https://next-api.useplunk.com';
const DASHBOARD_URL = process.env.NEXT_PUBLIC_DASHBOARD_URI || 'https://next-app.useplunk.com';
export function remarkReplaceEnv() {
return (tree) => {
visit(tree, ['code', 'inlineCode', 'text', 'link'], (node) => {
return tree => {
visit(tree, ['code', 'inlineCode', 'text', 'link'], node => {
// Replace in text values
if (node.value && typeof node.value === 'string') {
node.value = node.value
.replace(/\{\{API_URL\}\}/g, API_URL)
.replace(/\{\{DASHBOARD_URL\}\}/g, DASHBOARD_URL);
node.value = node.value.replace(/\{\{API_URL\}\}/g, API_URL).replace(/\{\{DASHBOARD_URL\}\}/g, DASHBOARD_URL);
}
// Replace in link URLs
if (node.url && typeof node.url === 'string') {
node.url = node.url
.replace(/\{\{API_URL\}\}/g, API_URL)
.replace(/\{\{DASHBOARD_URL\}\}/g, DASHBOARD_URL);
node.url = node.url.replace(/\{\{API_URL\}\}/g, API_URL).replace(/\{\{DASHBOARD_URL\}\}/g, DASHBOARD_URL);
}
});
};
+3 -3
View File
@@ -13,7 +13,7 @@ const __dirname = path.dirname(__filename);
function findMdxFiles(dir, fileList = []) {
const files = fs.readdirSync(dir);
files.forEach((file) => {
files.forEach(file => {
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);
@@ -46,7 +46,7 @@ function filePathToUrl(filePath) {
}
const config = {
siteUrl: process.env.NEXT_PUBLIC_WIKI_URI || 'https://docs.useplunk.com',
siteUrl: process.env.NEXT_PUBLIC_WIKI_URI || 'https://next-wiki.useplunk.com',
generateRobotsTxt: true,
additionalPaths: async () => {
const contentDocsPath = path.join(__dirname, 'content', 'docs');
@@ -55,7 +55,7 @@ const config = {
const mdxFiles = findMdxFiles(contentDocsPath);
// Convert to sitemap entries
return mdxFiles.map((filePath) => ({
return mdxFiles.map(filePath => ({
loc: filePathToUrl(filePath),
changefreq: 'weekly',
priority: 0.7,
+15 -13
View File
@@ -6,12 +6,12 @@
"version": "1.0.0",
"contact": {
"name": "Plunk Support",
"url": "https://useplunk.com"
"url": "https://next.useplunk.com"
}
},
"servers": [
{
"url": "https://api.useplunk.com",
"url": "https://next-api.useplunk.com",
"description": "Production server"
}
],
@@ -694,7 +694,16 @@
"description": "Array of human-readable reasons describing the verification results"
}
},
"required": ["email", "valid", "isDisposable", "isTypo", "isPlusAddressed", "domainExists", "hasMxRecords", "reasons"]
"required": [
"email",
"valid",
"isDisposable",
"isTypo",
"isPlusAddressed",
"domainExists",
"hasMxRecords",
"reasons"
]
}
}
},
@@ -711,9 +720,7 @@
"isPlusAddressed": false,
"domainExists": true,
"hasMxRecords": true,
"reasons": [
"Email appears to be valid"
]
"reasons": ["Email appears to be valid"]
}
}
},
@@ -730,10 +737,7 @@
"domainExists": false,
"hasMxRecords": false,
"suggestedEmail": "user@gmail.com",
"reasons": [
"Possible typo detected, did you mean gmail.com?",
"Domain does not exist"
]
"reasons": ["Possible typo detected, did you mean gmail.com?", "Domain does not exist"]
}
}
},
@@ -749,9 +753,7 @@
"isPlusAddressed": false,
"domainExists": true,
"hasMxRecords": true,
"reasons": [
"Email appears to be valid"
]
"reasons": ["Email appears to be valid"]
}
}
}
+3 -9
View File
@@ -6,7 +6,7 @@ interface FooterProps {
landingUrl?: string;
}
export function Footer({projectId, landingUrl = 'https://www.useplunk.com'}: FooterProps) {
export function Footer({projectId, landingUrl = 'https://next.useplunk.com'}: FooterProps) {
return (
<Section className="border-t border-gray-100 bg-gray-50 px-8 py-8">
<Text className="mb-4 mt-0 text-center text-xs leading-relaxed text-gray-600">
@@ -22,17 +22,11 @@ export function Footer({projectId, landingUrl = 'https://www.useplunk.com'}: Foo
Plunk
</Link>
{' • '}
<Link
href={`${landingUrl}/privacy`}
className="text-gray-500 no-underline hover:text-gray-700"
>
<Link href={`${landingUrl}/privacy`} className="text-gray-500 no-underline hover:text-gray-700">
Privacy
</Link>
{' • '}
<Link
href={`${landingUrl}/terms`}
className="text-gray-500 no-underline hover:text-gray-700"
>
<Link href={`${landingUrl}/terms`} className="text-gray-500 no-underline hover:text-gray-700">
Terms
</Link>
</Text>
@@ -20,8 +20,8 @@ export function BillingLimitExceededEmail({
usage = 10000,
limit = 10000,
sourceType = 'Transactional',
dashboardUrl = 'https://app.useplunk.com',
landingUrl = 'https://www.useplunk.com',
dashboardUrl = 'https://next-app.useplunk.com',
landingUrl = 'https://next.useplunk.com',
}: BillingLimitExceededEmailProps) {
return (
<EmailLayout>
@@ -22,8 +22,8 @@ export function BillingLimitWarningEmail({
limit = 10000,
percentage = 85,
sourceType = 'Transactional',
dashboardUrl = 'https://app.useplunk.com',
landingUrl = 'https://www.useplunk.com',
dashboardUrl = 'https://next-app.useplunk.com',
landingUrl = 'https://next.useplunk.com',
}: BillingLimitWarningEmailProps) {
const percentageRounded = Math.round(percentage);
const remaining = limit - usage;
@@ -13,7 +13,7 @@ interface EmailVerificationEmailProps {
export function EmailVerificationEmail({
email = 'user@example.com',
verificationUrl = 'https://api.useplunk.com/auth/verify-email?token=abc123',
landingUrl = 'https://www.useplunk.com',
landingUrl = 'https://next.useplunk.com',
}: EmailVerificationEmailProps) {
return (
<EmailLayout>
+3 -5
View File
@@ -12,17 +12,15 @@ interface PasswordResetEmailProps {
export function PasswordResetEmail({
email = 'user@example.com',
resetUrl = 'https://app.useplunk.com/auth/reset-password?token=abc123',
landingUrl = 'https://www.useplunk.com',
resetUrl = 'https://next-app.useplunk.com/auth/reset-password?token=abc123',
landingUrl = 'https://next.useplunk.com',
}: PasswordResetEmailProps) {
return (
<EmailLayout>
<Header />
<Section className="px-8 pb-10 pt-10">
<Heading className="mb-2 mt-0 text-2xl font-semibold tracking-tight text-gray-900">
Reset your password
</Heading>
<Heading className="mb-2 mt-0 text-2xl font-semibold tracking-tight text-gray-900">Reset your password</Heading>
<Text className="mb-8 mt-0 text-base leading-relaxed text-gray-600">
We received a request to reset your password. Click the button below to create a new password.
@@ -16,8 +16,8 @@ export function ProjectDisabledEmail({
projectName = 'My Project',
projectId = 'proj_example123',
violations = ['Bounce rate exceeded 10% threshold', 'Complaint rate exceeded 0.5% threshold'],
dashboardUrl = 'https://app.useplunk.com',
landingUrl = 'https://www.useplunk.com',
dashboardUrl = 'https://next-app.useplunk.com',
landingUrl = 'https://next.useplunk.com',
}: ProjectDisabledEmailProps) {
return (
<EmailLayout>