chore: Add guides and comparison pages to landing site
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/** @type {import('next-sitemap').IConfig} */
|
||||
module.exports = {
|
||||
siteUrl: process.env.NEXT_PUBLIC_LANDING_URI || 'https://www.swyp.be',
|
||||
siteUrl: process.env.NEXT_PUBLIC_LANDING_URI || 'https://www.useplunk.com',
|
||||
generateRobotsTxt: true,
|
||||
};
|
||||
|
||||
@@ -1,31 +1,63 @@
|
||||
import {motion} from 'framer-motion';
|
||||
import React from 'react';
|
||||
import React, {useState} from 'react';
|
||||
import {Check, Copy} from 'lucide-react';
|
||||
|
||||
interface CodeBlockProps {
|
||||
code: string;
|
||||
language?: string;
|
||||
title?: string;
|
||||
showCopy?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable code block component with syntax highlighting styling
|
||||
* Reusable code block component with syntax highlighting styling and copy functionality
|
||||
*/
|
||||
export function CodeBlock({code, language = 'javascript', title}: CodeBlockProps) {
|
||||
export function CodeBlock({code, language = 'javascript', title, showCopy = true}: CodeBlockProps) {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleCopy = async () => {
|
||||
await navigator.clipboard.writeText(code);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'overflow-hidden rounded-xl border border-neutral-200 bg-neutral-50'}
|
||||
className={'group relative overflow-hidden rounded-xl border border-neutral-200 bg-neutral-900'}
|
||||
>
|
||||
{title && (
|
||||
<div className={'border-b border-neutral-200 bg-white px-6 py-3'}>
|
||||
<span className={'text-sm font-medium text-neutral-900'}>{title}</span>
|
||||
{(title || showCopy) && (
|
||||
<div className={'flex items-center justify-between border-b border-neutral-800 bg-neutral-900 px-6 py-3'}>
|
||||
{title && <span className={'text-sm font-medium text-neutral-400'}>{title}</span>}
|
||||
{!title && <span className={'text-xs font-medium text-neutral-500 uppercase'}>{language}</span>}
|
||||
{showCopy && (
|
||||
<button
|
||||
onClick={handleCopy}
|
||||
className={
|
||||
'flex items-center gap-2 rounded-lg border border-neutral-700 bg-neutral-800 px-3 py-1.5 text-xs font-medium text-neutral-300 transition hover:bg-neutral-700 hover:text-white'
|
||||
}
|
||||
aria-label="Copy code"
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
<Check className="h-3 w-3" />
|
||||
Copied!
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Copy className="h-3 w-3" />
|
||||
Copy
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<pre className={'overflow-x-auto p-6'}>
|
||||
<code className={'font-mono text-sm text-neutral-900'}>{code}</code>
|
||||
<pre className={'overflow-x-auto p-6 text-neutral-100'}>
|
||||
<code className={'font-mono text-sm leading-relaxed'}>{code}</code>
|
||||
</pre>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ export function FAQSection({faqs, schemaId = 'faq-schema'}: FAQSectionProps) {
|
||||
__html: JSON.stringify({
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'FAQPage',
|
||||
'mainEntity': faqs.map((faq) => ({
|
||||
'mainEntity': faqs.map(faq => ({
|
||||
'@type': 'Question',
|
||||
'name': faq.question,
|
||||
'acceptedAnswer': {
|
||||
|
||||
@@ -67,7 +67,10 @@ export default function Footer() {
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={'/made-by-humans'} className="text-sm text-neutral-600 transition hover:text-neutral-900">
|
||||
<Link
|
||||
href={'/made-by-humans'}
|
||||
className="text-sm text-neutral-600 transition hover:text-neutral-900"
|
||||
>
|
||||
Made by humans
|
||||
</Link>
|
||||
</li>
|
||||
@@ -131,9 +134,7 @@ export default function Footer() {
|
||||
</div>
|
||||
|
||||
<div className="mt-16 border-t border-neutral-200 pt-8">
|
||||
<p className="text-sm text-neutral-500">
|
||||
© {new Date().getFullYear()} Plunk. All rights reserved.
|
||||
</p>
|
||||
<p className="text-sm text-neutral-500">© {new Date().getFullYear()} Plunk. All rights reserved.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -25,19 +25,34 @@ export default function Navbar() {
|
||||
</Link>
|
||||
</div>
|
||||
<div className="hidden items-center gap-8 md:flex">
|
||||
<Link href={'/made-by-humans'} className={'text-sm font-medium text-neutral-600 transition hover:text-neutral-900'}>
|
||||
<Link
|
||||
href={'/made-by-humans'}
|
||||
className={'text-sm font-medium text-neutral-600 transition hover:text-neutral-900'}
|
||||
>
|
||||
By humans
|
||||
</Link>
|
||||
|
||||
<Link href={'/pricing'} className={'text-sm font-medium text-neutral-600 transition hover:text-neutral-900'}>
|
||||
<Link
|
||||
href={'/pricing'}
|
||||
className={'text-sm font-medium text-neutral-600 transition hover:text-neutral-900'}
|
||||
>
|
||||
Pricing
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href={'/guides'}
|
||||
className={'text-sm font-medium text-neutral-600 transition hover:text-neutral-900'}
|
||||
>
|
||||
Guides
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
rel={'noreferrer'}
|
||||
className={'flex items-center gap-x-1.5 text-sm font-medium text-neutral-600 transition hover:text-neutral-900'}
|
||||
className={
|
||||
'flex items-center gap-x-1.5 text-sm font-medium text-neutral-600 transition hover:text-neutral-900'
|
||||
}
|
||||
>
|
||||
Docs
|
||||
<svg className={'h-3.5 w-3.5'} fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@@ -47,32 +62,27 @@ export default function Navbar() {
|
||||
strokeWidth="2"
|
||||
d="M9.25 4.75H6.75C5.64543 4.75 4.75 5.64543 4.75 6.75V17.25C4.75 18.3546 5.64543 19.25 6.75 19.25H17.25C18.3546 19.25 19.25 18.3546 19.25 17.25V14.75"
|
||||
/>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M19.25 9.25V4.75H14.75"
|
||||
/>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M19 5L11.75 12.25"
|
||||
/>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19.25 9.25V4.75H14.75" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 5L11.75 12.25" />
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hidden items-center gap-6 md:flex">
|
||||
<a href={`${DASHBOARD_URI}/auth/login`} className={'text-sm font-medium text-neutral-600 transition hover:text-neutral-900'}>
|
||||
<a
|
||||
href={`${DASHBOARD_URI}/auth/login`}
|
||||
className={'text-sm font-medium text-neutral-600 transition hover:text-neutral-900'}
|
||||
>
|
||||
Sign in
|
||||
</a>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={'rounded-lg bg-neutral-900 px-6 py-2.5 text-sm font-semibold text-white shadow-sm transition hover:bg-neutral-800'}
|
||||
className={
|
||||
'rounded-lg bg-neutral-900 px-6 py-2.5 text-sm font-semibold text-white shadow-sm transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
Get started
|
||||
</motion.a>
|
||||
@@ -146,6 +156,14 @@ export default function Navbar() {
|
||||
Pricing
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href={'/guides'}
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className="block rounded-lg px-4 py-3 text-sm font-medium text-neutral-600 transition hover:bg-neutral-100 hover:text-neutral-900"
|
||||
>
|
||||
Guides
|
||||
</Link>
|
||||
|
||||
<a
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
|
||||
@@ -38,16 +38,14 @@ export function PricingCalculator({competitors, defaultVolume = 100000}: Pricing
|
||||
{/* Header */}
|
||||
<div className={'border-b border-neutral-200 bg-neutral-50 p-8'}>
|
||||
<h3 className={'text-2xl font-bold text-neutral-900'}>Pricing Calculator</h3>
|
||||
<p className={'mt-2 text-sm text-neutral-600'}>
|
||||
Compare costs across platforms at different email volumes
|
||||
</p>
|
||||
<p className={'mt-2 text-sm text-neutral-600'}>Compare costs across platforms at different email volumes</p>
|
||||
</div>
|
||||
|
||||
{/* Volume Selector */}
|
||||
<div className={'p-8'}>
|
||||
<label className={'block text-sm font-semibold text-neutral-900'}>Monthly Email Volume</label>
|
||||
<div className={'mt-4 grid grid-cols-2 gap-3 sm:grid-cols-4'}>
|
||||
{volumeOptions.map((option) => (
|
||||
{volumeOptions.map(option => (
|
||||
<button
|
||||
key={option.value}
|
||||
onClick={() => setVolume(option.value)}
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
import {Footer, Navbar} from '../';
|
||||
import {motion} from 'framer-motion';
|
||||
import React, {ReactNode, useEffect, useState} from 'react';
|
||||
import Link from 'next/link';
|
||||
import {ArticleJsonLd, BreadcrumbJsonLd, NextSeo} from 'next-seo';
|
||||
import {Calendar, Clock} from 'lucide-react';
|
||||
|
||||
interface GuideLayoutProps {
|
||||
title: string;
|
||||
description: string;
|
||||
lastUpdated: string;
|
||||
readTime: string;
|
||||
children: ReactNode;
|
||||
canonical?: string;
|
||||
ogImage?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable layout for educational guide pages
|
||||
*/
|
||||
export function GuideLayout({
|
||||
title,
|
||||
description,
|
||||
lastUpdated,
|
||||
readTime,
|
||||
children,
|
||||
canonical,
|
||||
ogImage = 'https://www.useplunk.com/assets/card.png',
|
||||
}: GuideLayoutProps) {
|
||||
const [headings, setHeadings] = useState<{id: string; text: string; level: number}[]>([]);
|
||||
const [activeId, setActiveId] = useState<string>('');
|
||||
|
||||
// Extract headings for table of contents
|
||||
useEffect(() => {
|
||||
const elements = Array.from(document.querySelectorAll('h2, h3'));
|
||||
|
||||
// Generate IDs for headings that don't have them
|
||||
const headingData = elements.map(element => {
|
||||
let id = element.id;
|
||||
if (!id) {
|
||||
// Generate ID from text content
|
||||
id = (element.textContent || '')
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/(^-|-$)/g, '');
|
||||
element.id = id;
|
||||
}
|
||||
return {
|
||||
id,
|
||||
text: element.textContent || '',
|
||||
level: parseInt(element.tagName.substring(1)),
|
||||
};
|
||||
});
|
||||
setHeadings(headingData);
|
||||
|
||||
// Set up intersection observer for active heading
|
||||
const observer = new IntersectionObserver(
|
||||
entries => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
setActiveId(entry.target.id);
|
||||
}
|
||||
});
|
||||
},
|
||||
{rootMargin: '-100px 0px -80% 0px'},
|
||||
);
|
||||
|
||||
elements.forEach(element => observer.observe(element));
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, [children]);
|
||||
|
||||
// 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: 3, name: title, item: canonical || ''},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<NextSeo
|
||||
title={`${title} | Plunk`}
|
||||
description={description}
|
||||
canonical={canonical}
|
||||
openGraph={{
|
||||
title: `${title} | Plunk`,
|
||||
description: description,
|
||||
url: canonical,
|
||||
type: 'article',
|
||||
images: [{url: ogImage, alt: title}],
|
||||
article: {
|
||||
publishedTime: lastUpdated,
|
||||
modifiedTime: lastUpdated,
|
||||
authors: ['Plunk'],
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
<ArticleJsonLd
|
||||
type="Article"
|
||||
url={canonical || ''}
|
||||
title={title}
|
||||
images={[ogImage]}
|
||||
datePublished={lastUpdated}
|
||||
dateModified={lastUpdated}
|
||||
authorName="Plunk"
|
||||
description={description}
|
||||
/>
|
||||
|
||||
<BreadcrumbJsonLd itemListElements={breadcrumbItems} />
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
<div className={'flex gap-12 py-16'}>
|
||||
{/* Main Content */}
|
||||
<article className={'flex-1 max-w-4xl'}>
|
||||
{/* Breadcrumbs */}
|
||||
<nav className={'mb-8'}>
|
||||
<ol className={'flex items-center gap-2 text-sm text-neutral-600'}>
|
||||
<li>
|
||||
<Link href="/" className={'hover:text-neutral-900'}>
|
||||
Home
|
||||
</Link>
|
||||
</li>
|
||||
<li>/</li>
|
||||
<li>
|
||||
<Link href="/guides" className={'hover:text-neutral-900'}>
|
||||
Guides
|
||||
</Link>
|
||||
</li>
|
||||
<li>/</li>
|
||||
<li className={'text-neutral-900 font-medium'}>{title}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
{/* Header */}
|
||||
<motion.header
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mb-12'}
|
||||
>
|
||||
<h1 className={'text-4xl font-bold tracking-tight text-neutral-900 sm:text-5xl'}>{title}</h1>
|
||||
<p className={'mt-6 text-lg text-neutral-600 leading-relaxed'}>{description}</p>
|
||||
|
||||
<div className={'mt-8 flex items-center gap-6 text-sm text-neutral-600'}>
|
||||
<div className={'flex items-center gap-2'}>
|
||||
<Calendar className="h-4 w-4" />
|
||||
<span>
|
||||
Updated{' '}
|
||||
{new Date(lastUpdated).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-2'}>
|
||||
<Clock className="h-4 w-4" />
|
||||
<span>{readTime} read</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.header>
|
||||
|
||||
{/* Content */}
|
||||
<div className={'prose prose-neutral max-w-none'}>{children}</div>
|
||||
</article>
|
||||
|
||||
{/* Table of Contents - Desktop Only */}
|
||||
{headings.length > 0 && (
|
||||
<aside className={'hidden lg:block w-64 shrink-0 sticky top-24 self-start'}>
|
||||
<div className={'rounded-xl border border-neutral-200 bg-white p-6 shadow-sm'}>
|
||||
<h2 className={'text-sm font-semibold text-neutral-900 mb-4 uppercase tracking-wide'}>
|
||||
On this page
|
||||
</h2>
|
||||
<nav>
|
||||
<ul className={'space-y-1'}>
|
||||
{headings.map(heading => (
|
||||
<li key={heading.id} className={heading.level === 3 ? 'ml-4 mt-0.5' : 'mt-2 first:mt-0'}>
|
||||
<a
|
||||
href={`#${heading.id}`}
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
const element = document.getElementById(heading.id);
|
||||
if (element) {
|
||||
const offset = 100; // Account for fixed header
|
||||
const elementPosition = element.getBoundingClientRect().top + window.scrollY;
|
||||
window.scrollTo({
|
||||
top: elementPosition - offset,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
}
|
||||
}}
|
||||
className={`block py-1 border-l-2 -ml-px pl-3 transition-all duration-200 ${
|
||||
heading.level === 2
|
||||
? activeId === heading.id
|
||||
? 'border-neutral-900 text-neutral-900 font-semibold text-sm'
|
||||
: 'border-transparent text-neutral-600 hover:text-neutral-900 hover:border-neutral-300 font-medium text-sm'
|
||||
: activeId === heading.id
|
||||
? 'border-neutral-700 text-neutral-800 font-medium text-xs'
|
||||
: 'border-transparent text-neutral-500 hover:text-neutral-700 hover:border-neutral-200 text-xs'
|
||||
}`}
|
||||
>
|
||||
{heading.text}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</aside>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import React, {ReactNode} from 'react';
|
||||
import {AlertTriangle, CheckCircle2, Info, Lightbulb} from 'lucide-react';
|
||||
|
||||
type InfoBoxType = 'info' | 'warning' | 'tip' | 'success';
|
||||
|
||||
interface InfoBoxProps {
|
||||
type?: InfoBoxType;
|
||||
title?: string;
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const infoBoxConfig: Record<
|
||||
InfoBoxType,
|
||||
{
|
||||
icon: React.ComponentType<{className?: string}>;
|
||||
borderColor: string;
|
||||
bgColor: string;
|
||||
iconColor: string;
|
||||
titleColor: string;
|
||||
}
|
||||
> = {
|
||||
info: {
|
||||
icon: Info,
|
||||
borderColor: 'border-blue-200',
|
||||
bgColor: 'bg-blue-50',
|
||||
iconColor: 'text-blue-600',
|
||||
titleColor: 'text-blue-900',
|
||||
},
|
||||
warning: {
|
||||
icon: AlertTriangle,
|
||||
borderColor: 'border-amber-200',
|
||||
bgColor: 'bg-amber-50',
|
||||
iconColor: 'text-amber-600',
|
||||
titleColor: 'text-amber-900',
|
||||
},
|
||||
tip: {
|
||||
icon: Lightbulb,
|
||||
borderColor: 'border-purple-200',
|
||||
bgColor: 'bg-purple-50',
|
||||
iconColor: 'text-purple-600',
|
||||
titleColor: 'text-purple-900',
|
||||
},
|
||||
success: {
|
||||
icon: CheckCircle2,
|
||||
borderColor: 'border-green-200',
|
||||
bgColor: 'bg-green-50',
|
||||
iconColor: 'text-green-600',
|
||||
titleColor: 'text-green-900',
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* InfoBox component for displaying tips, warnings, notes, and other callouts in guides
|
||||
*/
|
||||
export function InfoBox({type = 'info', title, children, className}: InfoBoxProps) {
|
||||
const config = infoBoxConfig[type];
|
||||
const Icon = config.icon;
|
||||
|
||||
const defaultTitles: Record<InfoBoxType, string> = {
|
||||
info: 'Note',
|
||||
warning: 'Warning',
|
||||
tip: 'Tip',
|
||||
success: 'Success',
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`rounded-xl border ${config.borderColor} ${config.bgColor} p-6 my-6 ${className || ''}`}>
|
||||
<div className={'flex gap-4'}>
|
||||
<div className={'shrink-0'}>
|
||||
<Icon className={`h-5 w-5 ${config.iconColor}`} />
|
||||
</div>
|
||||
<div>
|
||||
{(title || defaultTitles[type]) && (
|
||||
<h4 className={`not-prose font-semibold ${config.titleColor}`}>{title || defaultTitles[type]}</h4>
|
||||
)}
|
||||
<div className={'text-sm text-neutral-700 leading-relaxed mt-0 prose prose-sm max-w-none'}>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export {GuideLayout} from './GuideLayout';
|
||||
export {InfoBox} from './InfoBox';
|
||||
@@ -0,0 +1,605 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import {CodeBlock} from '../../components/CodeBlock';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function EmailAPIGuide() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="Email API Guide: Everything You Need to Know with Code Examples"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
Email APIs allow developers to programmatically send, receive, and manage emails from applications. Whether
|
||||
you're sending order confirmations, password resets, or marketing campaigns, email APIs provide a reliable,
|
||||
scalable way to integrate email into your software.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
This guide covers everything you need to know: how email APIs work, implementation examples in multiple
|
||||
languages, best practices, and choosing the right provider.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* What is an Email API */}
|
||||
<section id="what-is-email-api" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What is an Email API?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
An email API is a programmatic interface that lets you send and manage emails via HTTP requests instead of
|
||||
manually configuring SMTP servers. APIs abstract away the complexity of email delivery, providing simple HTTP
|
||||
endpoints to send emails and webhooks to track delivery status.
|
||||
</p>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2 mb-8">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">SMTP (Traditional)</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Direct protocol for sending email</li>
|
||||
<li>• Requires managing connections</li>
|
||||
<li>• Manual error handling</li>
|
||||
<li>• Limited delivery tracking</li>
|
||||
<li>• More complex implementation</li>
|
||||
<li>• Port 25, 587, or 465</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Email API (Modern)</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• HTTP-based RESTful interface</li>
|
||||
<li>• No connection management needed</li>
|
||||
<li>• Structured error responses</li>
|
||||
<li>• Built-in tracking & analytics</li>
|
||||
<li>• Simpler to implement</li>
|
||||
<li>• Standard HTTP/HTTPS</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="tip" title="When to Use Email APIs">
|
||||
<p>
|
||||
Email APIs are ideal for transactional emails (order confirmations, password resets), automated
|
||||
notifications, and programmatic campaigns. If you're building software that sends emails, APIs are almost
|
||||
always the better choice over SMTP.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* How Email APIs Work */}
|
||||
<section id="how-it-works" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How Email APIs Work</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">1. Authentication</h3>
|
||||
<p className="text-neutral-700">
|
||||
You authenticate requests using an API key (usually passed in headers). This identifies your account and
|
||||
authorizes API access.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">2. Make HTTP Request</h3>
|
||||
<p className="text-neutral-700">
|
||||
Send a POST request to the API endpoint with email details (recipient, subject, body, etc.) as JSON.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">3. API Validates & Queues</h3>
|
||||
<p className="text-neutral-700">
|
||||
The API validates your request, queues the email for delivery, and returns a response with the email ID
|
||||
and status.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">4. Email Delivery</h3>
|
||||
<p className="text-neutral-700">
|
||||
The service handles SMTP connections, retry logic, and delivery to the recipient's mail server.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">5. Webhooks & Tracking</h3>
|
||||
<p className="text-neutral-700">
|
||||
You receive webhook notifications for delivery events (delivered, bounced, opened, clicked) and can query
|
||||
the API for email status.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Code Examples */}
|
||||
<section id="examples" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Email API Code Examples</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Here's how to send an email using Plunk's API in various languages:
|
||||
</p>
|
||||
|
||||
<div className="space-y-8">
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">JavaScript / Node.js</h3>
|
||||
<CodeBlock
|
||||
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', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer YOUR_API_KEY'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
to: '[email protected]',
|
||||
subject: 'Welcome to our platform!',
|
||||
body: '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
|
||||
// Optional fields
|
||||
from: '[email protected]',
|
||||
name: 'Your Company',
|
||||
replyTo: '[email protected]'
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
console.log('Email sent!', data.emailId);
|
||||
} else {
|
||||
console.error('Failed to send:', data.error);
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Python</h3>
|
||||
<CodeBlock
|
||||
language="python"
|
||||
title="Python Example"
|
||||
code={`import requests
|
||||
|
||||
response = requests.post(
|
||||
'https://api.useplunk.com/v1/send',
|
||||
headers={
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer YOUR_API_KEY'
|
||||
},
|
||||
json={
|
||||
'to': '[email protected]',
|
||||
'subject': 'Welcome to our platform!',
|
||||
'body': '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
|
||||
'from': '[email protected]',
|
||||
'name': 'Your Company'
|
||||
}
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"Email sent! ID: {data['emailId']}")
|
||||
else:
|
||||
print(f"Error: {response.json()['error']}")`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">PHP</h3>
|
||||
<CodeBlock
|
||||
language="php"
|
||||
title="PHP Example"
|
||||
code={`<?php
|
||||
$ch = curl_init('https://api.useplunk.com/v1/send');
|
||||
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer YOUR_API_KEY'
|
||||
]);
|
||||
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
|
||||
'to' => '[email protected]',
|
||||
'subject' => 'Welcome to our platform!',
|
||||
'body' => '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
|
||||
'from' => '[email protected]',
|
||||
'name' => 'Your Company'
|
||||
]));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if ($httpCode === 200) {
|
||||
echo "Email sent! ID: " . $data['emailId'];
|
||||
} else {
|
||||
echo "Error: " . $data['error'];
|
||||
}
|
||||
?>`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Ruby</h3>
|
||||
<CodeBlock
|
||||
language="ruby"
|
||||
title="Ruby Example"
|
||||
code={`require 'net/http'
|
||||
require 'json'
|
||||
|
||||
uri = URI('https://api.useplunk.com/v1/send')
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
http.use_ssl = true
|
||||
|
||||
request = Net::HTTP::Post.new(uri.path)
|
||||
request['Content-Type'] = 'application/json'
|
||||
request['Authorization'] = 'Bearer YOUR_API_KEY'
|
||||
request.body = {
|
||||
to: '[email protected]',
|
||||
subject: 'Welcome to our platform!',
|
||||
body: '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
|
||||
from: '[email protected]',
|
||||
name: 'Your Company'
|
||||
}.to_json
|
||||
|
||||
response = http.request(request)
|
||||
data = JSON.parse(response.body)
|
||||
|
||||
if response.code.to_i == 200
|
||||
puts "Email sent! ID: #{data['emailId']}"
|
||||
else
|
||||
puts "Error: #{data['error']}"
|
||||
end`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Go</h3>
|
||||
<CodeBlock
|
||||
language="go"
|
||||
title="Go Example"
|
||||
code={`package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type EmailRequest struct {
|
||||
To string \`json:"to"\`
|
||||
Subject string \`json:"subject"\`
|
||||
Body string \`json:"body"\`
|
||||
From string \`json:"from"\`
|
||||
Name string \`json:"name"\`
|
||||
}
|
||||
|
||||
func main() {
|
||||
email := EmailRequest{
|
||||
To: "[email protected]",
|
||||
Subject: "Welcome to our platform!",
|
||||
Body: "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
|
||||
From: "[email protected]",
|
||||
Name: "Your Company",
|
||||
}
|
||||
|
||||
jsonData, _ := json.Marshal(email)
|
||||
|
||||
req, _ := http.NewRequest("POST", "https://api.useplunk.com/v1/send", bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
fmt.Println("Error:", err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
|
||||
if resp.StatusCode == 200 {
|
||||
var result map[string]interface{}
|
||||
json.Unmarshal(body, &result)
|
||||
fmt.Printf("Email sent! ID: %v\\n", result["emailId"])
|
||||
} else {
|
||||
fmt.Println("Error:", string(body))
|
||||
}
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Common Features */}
|
||||
<section id="features" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Common Email API Features</h2>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Sending Features</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Send individual or batch emails</li>
|
||||
<li>• HTML and plain text support</li>
|
||||
<li>• Attachments</li>
|
||||
<li>• CC, BCC recipients</li>
|
||||
<li>• Custom headers</li>
|
||||
<li>• Template rendering</li>
|
||||
<li>• Scheduled sending</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Tracking & Analytics</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Delivery status tracking</li>
|
||||
<li>• Open tracking</li>
|
||||
<li>• Click tracking</li>
|
||||
<li>• Bounce detection</li>
|
||||
<li>• Spam complaint monitoring</li>
|
||||
<li>• Unsubscribe management</li>
|
||||
<li>• Real-time analytics</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Webhooks & Events</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Delivery notifications</li>
|
||||
<li>• Bounce notifications</li>
|
||||
<li>• Spam complaint alerts</li>
|
||||
<li>• Unsubscribe events</li>
|
||||
<li>• Open and click events</li>
|
||||
<li>• Custom event triggers</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Management Features</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Suppression list management</li>
|
||||
<li>• Contact management</li>
|
||||
<li>• Domain verification</li>
|
||||
<li>• Template management</li>
|
||||
<li>• API key management</li>
|
||||
<li>• Rate limiting</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Best Practices */}
|
||||
<section id="best-practices" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Email API Best Practices</h2>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Secure Your API Keys</h3>
|
||||
<p className="text-neutral-700">
|
||||
Store API keys in environment variables, never in code. Use separate keys for development, staging, and
|
||||
production. Rotate keys periodically and immediately if compromised.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Implement Proper Error Handling</h3>
|
||||
<p className="text-neutral-700 mb-3">Handle different HTTP status codes appropriately:</p>
|
||||
<ul className="list-disc list-inside space-y-1 text-sm text-neutral-700">
|
||||
<li>200: Success</li>
|
||||
<li>400-499: Client errors (bad request, validation failed) - don't retry</li>
|
||||
<li>500-599: Server errors - retry with exponential backoff</li>
|
||||
<li>429: Rate limit exceeded - back off and retry later</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Use Webhooks for Delivery Status</h3>
|
||||
<p className="text-neutral-700">
|
||||
Don't poll the API for email status. Set up webhooks to receive real-time delivery notifications
|
||||
(delivered, bounced, opened, clicked). This is more efficient and provides faster updates.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Respect Rate Limits</h3>
|
||||
<p className="text-neutral-700">
|
||||
Implement rate limiting in your code to stay within API limits. Queue emails and send in batches. Use
|
||||
exponential backoff when you receive 429 rate limit errors.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Validate Email Addresses</h3>
|
||||
<p className="text-neutral-700">
|
||||
Validate email format before making API calls. Check for common typos. Consider using email validation
|
||||
APIs to verify deliverability before sending.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
6
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Use Templates</h3>
|
||||
<p className="text-neutral-700">
|
||||
Store email templates in your email service provider rather than hardcoding HTML in your application.
|
||||
This allows non-developers to update email content without code changes.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
7
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Monitor Deliverability Metrics</h3>
|
||||
<p className="text-neutral-700">
|
||||
Track bounce rates, spam complaints, and engagement metrics. Set up alerts for anomalies. Address
|
||||
deliverability issues proactively.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
8
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Test in Sandbox/Development Mode</h3>
|
||||
<p className="text-neutral-700">
|
||||
Use sandbox or test mode during development. Test error scenarios, retry logic, and webhook handling
|
||||
before deploying to production.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
9
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Log API Requests & Responses</h3>
|
||||
<p className="text-neutral-700">
|
||||
Log all API interactions (but redact sensitive data like API keys). This helps debug issues and
|
||||
understand email sending patterns.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
10
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Handle Timeouts</h3>
|
||||
<p className="text-neutral-700">
|
||||
Set appropriate timeouts for API requests (typically 10-30 seconds). Don't block user requests waiting
|
||||
for email API responses—queue emails asynchronously if needed.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Choosing a Provider */}
|
||||
<section id="choosing-provider" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Choosing an Email API Provider</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Consider these factors when selecting an email API provider:
|
||||
</p>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">Deliverability Reputation</h3>
|
||||
<p className="text-neutral-700">
|
||||
Choose providers with strong deliverability rates and sender reputation. Poor deliverability means your
|
||||
emails land in spam, defeating the purpose.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">Feature Set</h3>
|
||||
<p className="text-neutral-700">
|
||||
Ensure the API supports your needs: templates, webhooks, analytics, scheduling, attachments, etc. Some
|
||||
providers specialize in transactional emails, others in marketing.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">Pricing Model</h3>
|
||||
<p className="text-neutral-700">
|
||||
Understand pricing: per-email charges, monthly tiers, overage fees. Calculate costs for your expected
|
||||
volume. Watch for hidden fees and price increases at higher volumes.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">Developer Experience</h3>
|
||||
<p className="text-neutral-700">
|
||||
Good documentation, SDKs in your language, clear error messages, and responsive support make
|
||||
implementation much easier.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">Scalability & Reliability</h3>
|
||||
<p className="text-neutral-700">
|
||||
Can the provider handle your peak volumes? What's their uptime guarantee (SLA)? Do they have redundancy
|
||||
and failover systems?
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">Compliance & Security</h3>
|
||||
<p className="text-neutral-700">
|
||||
Ensure the provider complies with GDPR, CAN-SPAM, and other relevant regulations. Check their security
|
||||
certifications (SOC 2, ISO 27001).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/transactional-vs-marketing-email"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Transactional vs Marketing Email</h3>
|
||||
<p className="text-sm text-neutral-600">Understand email types for APIs.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-deliverability"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Deliverability</h3>
|
||||
<p className="text-sm text-neutral-600">Ensure API-sent emails reach the inbox.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-sender-reputation"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Sender Reputation</h3>
|
||||
<p className="text-sm text-neutral-600">Maintain good sender reputation.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,433 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import {CodeBlock} from '../../components/CodeBlock';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function EmailBounceRate() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="Email Bounce Rate: Hard vs Soft Bounces & How to Reduce Them"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
Email bounce rate measures the percentage of emails that couldn't be delivered to recipients' inboxes. Bounces
|
||||
occur for various reasons—some temporary, others permanent—and high bounce rates seriously damage your sender
|
||||
reputation and deliverability.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
Understanding the types of bounces and how to minimize them is essential for maintaining a healthy email
|
||||
program.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* What is Bounce Rate */}
|
||||
<section id="what-is-bounce-rate" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What is Email Bounce Rate?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Bounce rate is the percentage of sent emails that were rejected by receiving mail servers and couldn't be
|
||||
delivered.
|
||||
</p>
|
||||
|
||||
<div className="rounded-xl border-2 border-neutral-900 bg-neutral-50 p-8 mb-8">
|
||||
<div className="text-center">
|
||||
<div className="text-3xl font-bold text-neutral-900 mb-4">Bounce Rate Formula</div>
|
||||
<CodeBlock
|
||||
language="text"
|
||||
code={`Bounce Rate = (Bounced Emails ÷ Sent Emails) × 100
|
||||
|
||||
Example:
|
||||
- Sent: 10,000 emails
|
||||
- Bounced: 150 emails
|
||||
|
||||
Bounce Rate = (150 ÷ 10,000) × 100 = 1.5%`}
|
||||
showCopy={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-3 mb-8">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<div className="text-3xl font-bold text-green-600 mb-2"><2%</div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Excellent</h3>
|
||||
<p className="text-sm text-neutral-700">Healthy list with good hygiene practices</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<div className="text-3xl font-bold text-amber-600 mb-2">2-5%</div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Concerning</h3>
|
||||
<p className="text-sm text-neutral-700">List quality issues need attention</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<div className="text-3xl font-bold text-red-600 mb-2">>5%</div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Critical</h3>
|
||||
<p className="text-sm text-neutral-700">Serious problems damaging sender reputation</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Types of Bounces */}
|
||||
<section id="types-of-bounces" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Hard Bounces vs Soft Bounces</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Not all bounces are the same. Understanding the difference between hard and soft bounces is crucial for
|
||||
managing your email list.
|
||||
</p>
|
||||
|
||||
<div className="grid gap-8 md:grid-cols-2">
|
||||
<div className="rounded-xl border-2 border-red-200 bg-red-50 p-6">
|
||||
<h3 className="text-2xl font-semibold text-red-900 mb-4">Hard Bounces (Permanent)</h3>
|
||||
<p className="text-neutral-700 mb-4">
|
||||
Hard bounces occur when an email can't be delivered for permanent reasons. These addresses will never
|
||||
receive your emails.
|
||||
</p>
|
||||
<div className="space-y-3 mb-4">
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Common Causes:</h4>
|
||||
<ul className="space-y-1 text-sm text-neutral-700">
|
||||
<li>• Email address doesn't exist</li>
|
||||
<li>• Domain name doesn't exist</li>
|
||||
<li>• Email server has completely blocked delivery</li>
|
||||
<li>• Invalid email address format</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-lg bg-red-100 border border-red-200 p-4">
|
||||
<p className="text-sm font-semibold text-red-900 mb-2">Action Required:</p>
|
||||
<p className="text-sm text-neutral-700">
|
||||
<strong>Remove immediately.</strong> Never send to hard bounce addresses again. Continuing to send to
|
||||
them damages your sender reputation.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-amber-200 bg-amber-50 p-6">
|
||||
<h3 className="text-2xl font-semibold text-amber-900 mb-4">Soft Bounces (Temporary)</h3>
|
||||
<p className="text-neutral-700 mb-4">
|
||||
Soft bounces are temporary delivery failures. The email address is valid, but delivery failed for a
|
||||
temporary reason.
|
||||
</p>
|
||||
<div className="space-y-3 mb-4">
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Common Causes:</h4>
|
||||
<ul className="space-y-1 text-sm text-neutral-700">
|
||||
<li>• Recipient's mailbox is full</li>
|
||||
<li>• Email server is temporarily down or busy</li>
|
||||
<li>• Email message is too large</li>
|
||||
<li>• Recipient's server is experiencing issues</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-lg bg-amber-100 border border-amber-200 p-4">
|
||||
<p className="text-sm font-semibold text-amber-900 mb-2">Action Required:</p>
|
||||
<p className="text-sm text-neutral-700">
|
||||
<strong>Retry automatically.</strong> Most platforms retry for 24-72 hours. After 3-5 consecutive soft
|
||||
bounces, treat as a hard bounce and remove.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="info" title="Bounce vs Block" className="mt-6">
|
||||
<p>
|
||||
A <strong>block</strong> occurs when the receiving server actively rejects your email due to reputation or
|
||||
content issues. Unlike bounces (address problems), blocks indicate deliverability problems that affect all
|
||||
your emails to that domain.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Common Bounce Reasons */}
|
||||
<section id="bounce-reasons" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Common Bounce Reasons & Error Codes</h2>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Error Type</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Reason</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Type</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-neutral-200 bg-white">
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">550</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Mailbox unavailable</td>
|
||||
<td className="px-6 py-4 text-sm text-red-600">Hard</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Remove</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">551</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">User not local/Invalid address</td>
|
||||
<td className="px-6 py-4 text-sm text-red-600">Hard</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Remove</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">552</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Mailbox full</td>
|
||||
<td className="px-6 py-4 text-sm text-amber-600">Soft</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Retry</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">553</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Mailbox name invalid</td>
|
||||
<td className="px-6 py-4 text-sm text-red-600">Hard</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Remove</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">554</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Transaction failed</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-600">Varies</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Investigate</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">421</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Service not available</td>
|
||||
<td className="px-6 py-4 text-sm text-amber-600">Soft</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Retry</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">450</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Mailbox busy</td>
|
||||
<td className="px-6 py-4 text-sm text-amber-600">Soft</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Retry</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* How to Reduce Bounces */}
|
||||
<section id="reduce-bounces" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How to Reduce Email Bounce Rates</h2>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Use Double Opt-In</h3>
|
||||
<p className="text-neutral-700">
|
||||
Require new subscribers to confirm their email address by clicking a verification link. This ensures the
|
||||
address is valid, active, and belongs to the person who submitted it. Double opt-in reduces bounce rates
|
||||
by 50-70%.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Validate Email Addresses</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
Use real-time email validation on signup forms to catch typos and invalid formats. Validate:
|
||||
</p>
|
||||
<ul className="list-disc list-inside space-y-1 text-sm text-neutral-700">
|
||||
<li>Email format (contains @ and valid domain)</li>
|
||||
<li>Domain has valid MX records</li>
|
||||
<li>Catch common typos (gmial.com → gmail.com)</li>
|
||||
<li>Block disposable email addresses (if needed)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Remove Hard Bounces Immediately</h3>
|
||||
<p className="text-neutral-700">
|
||||
Automate removal of hard bounce addresses from your list. Never send to them again. Continued sending to
|
||||
invalid addresses signals poor list hygiene to email providers.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Clean Your List Regularly</h3>
|
||||
<p className="text-neutral-700">
|
||||
Remove or re-engage inactive subscribers every 6-12 months. Email addresses become invalid over time
|
||||
(15- 20% per year). Regular list cleaning prevents bounce accumulation.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Never Buy Email Lists</h3>
|
||||
<p className="text-neutral-700">
|
||||
Purchased lists have 20-40% invalid addresses and zero engagement. They'll destroy your bounce rate and
|
||||
sender reputation. Build your list organically—it's slower but dramatically more effective.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
6
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Monitor Soft Bounces</h3>
|
||||
<p className="text-neutral-700">
|
||||
Track addresses that repeatedly soft bounce. After 3-5 consecutive soft bounces over multiple campaigns,
|
||||
treat them as hard bounces and remove them.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
7
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Optimize Email Size</h3>
|
||||
<p className="text-neutral-700">
|
||||
Keep email size under 100KB to avoid soft bounces from size limits. Compress images, minimize code, and
|
||||
avoid large attachments (link to downloads instead).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
8
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Maintain Consistent Sending</h3>
|
||||
<p className="text-neutral-700">
|
||||
Send regularly to maintain list freshness. Long gaps between sends (3+ months) increase bounce rates as
|
||||
addresses become invalid or subscribers forget about you.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Impact on Deliverability */}
|
||||
<section id="impact" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How Bounce Rate Affects Deliverability</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Bounce rates directly impact your sender reputation and ability to reach the inbox:
|
||||
</p>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-xl border-2 border-red-200 bg-red-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-red-900 mb-3">Damaged Sender Reputation</h3>
|
||||
<p className="text-neutral-700">
|
||||
Email providers track bounce rates. High rates signal poor list quality and careless email practices,
|
||||
damaging your reputation score. This causes more emails—even to valid addresses—to land in spam.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-amber-200 bg-amber-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-amber-900 mb-3">Spam Trap Hits</h3>
|
||||
<p className="text-neutral-700">
|
||||
Invalid addresses can be recycled as spam traps—addresses used to catch senders with poor list hygiene.
|
||||
Sending to spam traps can get you blacklisted, severely impacting deliverability across all recipients.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-blue-200 bg-blue-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-blue-900 mb-3">IP/Domain Blacklisting</h3>
|
||||
<p className="text-neutral-700">
|
||||
Consistently high bounce rates can lead to your sending IP or domain being blacklisted by email providers
|
||||
or third-party blacklist services, making it extremely difficult to deliver emails.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-purple-200 bg-purple-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-purple-900 mb-3">Reduced Engagement</h3>
|
||||
<p className="text-neutral-700">
|
||||
High bounce rates correlate with low engagement. Email providers notice when large portions of your list
|
||||
aren't valid, reducing trust in your remaining emails.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="warning" title="Recovery Takes Time" className="mt-6">
|
||||
<p>
|
||||
Once your sender reputation is damaged by high bounce rates, recovery can take weeks or months of
|
||||
consistently good sending behavior. Prevention is far easier than recovery.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Monitoring Bounces */}
|
||||
<section id="monitoring" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Monitoring & Managing Bounces</h2>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">What to Track</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Overall bounce rate (target: <2%)</li>
|
||||
<li>• Hard bounce rate specifically</li>
|
||||
<li>• Soft bounce rate and retry success</li>
|
||||
<li>• Bounce rate by campaign</li>
|
||||
<li>• Bounce rate trends over time</li>
|
||||
<li>• Specific bounce reasons/error codes</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Automated Actions</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Auto-remove hard bounces immediately</li>
|
||||
<li>• Retry soft bounces 3-5 times over 72 hours</li>
|
||||
<li>• Remove persistent soft bouncers</li>
|
||||
<li>• Alert when bounce rate exceeds threshold</li>
|
||||
<li>• Weekly bounce rate reports</li>
|
||||
<li>• Validate emails at signup</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/email-deliverability"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Deliverability</h3>
|
||||
<p className="text-sm text-neutral-600">Complete guide to reaching the inbox.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-sender-reputation"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Sender Reputation</h3>
|
||||
<p className="text-sm text-neutral-600">Build and maintain sender reputation.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-marketing-best-practices"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Marketing Best Practices</h3>
|
||||
<p className="text-sm text-neutral-600">Complete email marketing guide.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,474 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import {CodeBlock} from '../../components/CodeBlock';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function EmailClickThroughRate() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="Email Click-Through Rate: How to Optimize CTAs & Increase Clicks"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
Email click-through rate (CTR) measures the percentage of recipients who clicked a link in your email. While
|
||||
open rates show subject line effectiveness, CTR reveals how compelling your email content and calls-to-action
|
||||
are.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
High CTR indicates engaged subscribers who find value in your emails and are moving toward conversion. This
|
||||
guide covers everything you need to optimize CTAs and maximize clicks.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* What is CTR */}
|
||||
<section id="what-is-ctr" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What is Email Click-Through Rate?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Click-through rate is the percentage of delivered emails that received at least one click on a link.
|
||||
</p>
|
||||
|
||||
<div className="rounded-xl border-2 border-neutral-900 bg-neutral-50 p-8 mb-8">
|
||||
<div className="text-center mb-6">
|
||||
<div className="text-3xl font-bold text-neutral-900 mb-4">CTR Formula</div>
|
||||
<CodeBlock
|
||||
language="text"
|
||||
code={`CTR = (Unique Clicks ÷ Delivered Emails) × 100
|
||||
|
||||
Example:
|
||||
- Sent: 10,000 emails
|
||||
- Delivered: 9,800 emails
|
||||
- Unique Clicks: 294
|
||||
|
||||
CTR = (294 ÷ 9,800) × 100 = 3.0%`}
|
||||
showCopy={false}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="text-3xl font-bold text-neutral-900 mb-4">CTOR Formula</div>
|
||||
<CodeBlock
|
||||
language="text"
|
||||
code={`CTOR (Click-to-Open Rate) = (Unique Clicks ÷ Unique Opens) × 100
|
||||
|
||||
Example:
|
||||
- Unique Opens: 2,450
|
||||
- Unique Clicks: 294
|
||||
|
||||
CTOR = (294 ÷ 2,450) × 100 = 12.0%`}
|
||||
showCopy={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="info" title="CTR vs CTOR">
|
||||
<p>
|
||||
<strong>CTR</strong> measures overall campaign effectiveness (including deliverability and opens).{' '}
|
||||
<strong>CTOR</strong> isolates content quality by measuring engagement from those who opened. Use both—CTR
|
||||
for overall performance, CTOR for content optimization.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Benchmarks */}
|
||||
<section id="benchmarks" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">CTR Benchmarks by Industry</h2>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 overflow-hidden mb-8">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Industry</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Average CTR</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Good CTR</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Average CTOR</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-neutral-200 bg-white">
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">SaaS / Technology</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">2-3%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">4%+</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">10-15%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">E-commerce / Retail</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">3-5%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">6%+</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">12-18%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">Media / Publishing</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">4-6%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">7%+</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">15-20%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">Financial Services</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">2-4%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">5%+</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">10-14%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">Non-Profit</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">2-4%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">5%+</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">10-16%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">Education</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">3-5%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">6%+</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">12-17%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<InfoBox type="tip" title="Context Matters">
|
||||
<p>
|
||||
CTR varies dramatically by email type: promotional emails (2-3%), newsletters (4-6%), transactional emails
|
||||
(10-15%), and triggered emails (15-30%). Compare similar email types, not all campaigns together.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Factors Affecting CTR */}
|
||||
<section id="factors" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What Affects Click-Through Rates?</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">1. Call-to-Action (CTA) Design</h3>
|
||||
<p className="text-neutral-700">
|
||||
Your CTA's design, placement, and copy directly impact clicks. Clear, prominent, action-oriented CTAs
|
||||
significantly outperform generic "Click here" links.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">2. Email Relevance</h3>
|
||||
<p className="text-neutral-700">
|
||||
Targeted, personalized content generates 2-3x higher CTR than generic blasts. Segmentation and
|
||||
personalization ensure emails match subscriber interests.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">3. Value Proposition</h3>
|
||||
<p className="text-neutral-700">
|
||||
Recipients need a clear reason to click. Compelling value propositions—exclusive content, limited offers,
|
||||
solutions to problems—drive clicks.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">4. Mobile Optimization</h3>
|
||||
<p className="text-neutral-700">
|
||||
60%+ of emails are read on mobile. Unoptimized emails with small links or poorly formatted content see 50%
|
||||
lower CTR on mobile devices.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">5. Content Scannability</h3>
|
||||
<p className="text-neutral-700">
|
||||
Most people skim emails. Clear structure with headers, bullet points, and whitespace helps readers find
|
||||
and click CTAs quickly.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">6. Number of CTAs</h3>
|
||||
<p className="text-neutral-700">
|
||||
More CTAs = divided attention. Emails with one primary CTA convert 371% better than those with multiple
|
||||
competing CTAs.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* How to Improve CTR */}
|
||||
<section id="improve-ctr" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How to Increase Email Click-Through Rates</h2>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Use Clear, Action-Oriented CTA Copy</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
Be specific about what happens when users click. Action verbs + value = higher CTR.
|
||||
</p>
|
||||
<div className="rounded-lg bg-neutral-100 p-4 space-y-2">
|
||||
<div className="flex items-start gap-2">
|
||||
<span className="text-green-600 font-bold">✓</span>
|
||||
<span className="text-sm text-neutral-700">"Download your free guide"</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<span className="text-green-600 font-bold">✓</span>
|
||||
<span className="text-sm text-neutral-700">"Start your 14-day free trial"</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<span className="text-green-600 font-bold">✓</span>
|
||||
<span className="text-sm text-neutral-700">"Get 20% off today only"</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<span className="text-red-600 font-bold">✗</span>
|
||||
<span className="text-sm text-neutral-700">"Click here"</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<span className="text-red-600 font-bold">✗</span>
|
||||
<span className="text-sm text-neutral-700">"Learn more"</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Design Prominent CTA Buttons</h3>
|
||||
<p className="text-neutral-700 mb-3">Button best practices:</p>
|
||||
<ul className="list-disc list-inside space-y-1 text-sm text-neutral-700">
|
||||
<li>Use contrasting colors that stand out from email design</li>
|
||||
<li>Make buttons large enough to tap on mobile (44x44px minimum)</li>
|
||||
<li>Add white space around buttons for visual prominence</li>
|
||||
<li>Use button text, not images (better for accessibility and loading)</li>
|
||||
<li>Repeat primary CTA if email is long (top and bottom)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Create a Single, Clear Focus</h3>
|
||||
<p className="text-neutral-700">
|
||||
Each email should have one primary goal. Multiple CTAs competing for attention reduce overall clicks.
|
||||
Guide readers toward one clear action.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Personalize Content</h3>
|
||||
<p className="text-neutral-700">
|
||||
Go beyond "Hi [Name]". Use behavioral data, purchase history, browsing activity, or preferences to send
|
||||
highly relevant emails. Personalized CTAs see 202% higher CTR.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Optimize for Mobile</h3>
|
||||
<p className="text-neutral-700 mb-3">Mobile optimization is critical:</p>
|
||||
<ul className="list-disc list-inside space-y-1 text-sm text-neutral-700">
|
||||
<li>Responsive design that adapts to screen size</li>
|
||||
<li>Large, tappable buttons (not small text links)</li>
|
||||
<li>Single-column layout for easy scrolling</li>
|
||||
<li>Concise copy (mobile users scan quickly)</li>
|
||||
<li>Place CTAs above the fold when possible</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
6
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Use Urgency and Scarcity (Authentically)</h3>
|
||||
<p className="text-neutral-700">
|
||||
Genuine limited-time offers or limited quantity create urgency that drives clicks. Be authentic—false
|
||||
urgency damages trust. "Sale ends tonight" or "Only 5 spots remaining" work when true.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
7
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Segment Your Audience</h3>
|
||||
<p className="text-neutral-700">
|
||||
Send targeted emails to specific groups based on behavior, interests, or demographics. Segmented
|
||||
campaigns see 3x higher CTR than non-segmented blasts.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
8
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Include Preview/Teaser Content</h3>
|
||||
<p className="text-neutral-700">
|
||||
Show just enough value to create curiosity. Product images, stat highlights, or content snippets
|
||||
encourage clicks to see more. "Read the full article" works better than just a headline.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
9
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">A/B Test CTAs</h3>
|
||||
<p className="text-neutral-700 mb-3">Test systematically:</p>
|
||||
<ul className="list-disc list-inside space-y-1 text-sm text-neutral-700">
|
||||
<li>Button copy ("Get started" vs "Start free trial")</li>
|
||||
<li>Button color (brand color vs high-contrast color)</li>
|
||||
<li>Button placement (top, middle, bottom)</li>
|
||||
<li>Number of CTAs (one vs multiple)</li>
|
||||
<li>Button size and shape</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
10
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Improve Email-Landing Page Match</h3>
|
||||
<p className="text-neutral-700">
|
||||
Ensure landing pages match email promises. Mismatched expectations cause immediate bounces. Email says
|
||||
"20% off"? Landing page should show 20% off, not a generic homepage.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Placement */}
|
||||
<section id="cta-placement" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">CTA Placement Best Practices</h2>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Short Emails (<200 words)</h3>
|
||||
<p className="text-sm text-neutral-700 mb-3">One CTA in the middle or at the end.</p>
|
||||
<div className="rounded-lg bg-neutral-50 p-3 text-xs text-neutral-600">Intro → Value prop → CTA</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Medium Emails (200-500 words)</h3>
|
||||
<p className="text-sm text-neutral-700 mb-3">CTAs at the beginning and end.</p>
|
||||
<div className="rounded-lg bg-neutral-50 p-3 text-xs text-neutral-600">
|
||||
Intro + CTA → Content → Final CTA
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Long Emails (>500 words)</h3>
|
||||
<p className="text-sm text-neutral-700 mb-3">Multiple CTAs throughout.</p>
|
||||
<div className="rounded-lg bg-neutral-50 p-3 text-xs text-neutral-600">
|
||||
CTA → Content → CTA → More content → Final CTA
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="tip" title="Above the Fold" className="mt-6">
|
||||
<p>
|
||||
Place at least one CTA above the fold (visible without scrolling) on mobile. Many readers won't scroll, so
|
||||
give them an early opportunity to click.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Common Mistakes */}
|
||||
<section id="common-mistakes" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Common CTR Mistakes to Avoid</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ Too Many CTAs</h3>
|
||||
<p className="text-neutral-700">
|
||||
Multiple competing CTAs confuse readers and reduce overall clicks. Focus on one primary action per email.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ Vague CTA Copy</h3>
|
||||
<p className="text-neutral-700">
|
||||
"Click here" and "Learn more" don't communicate value. Be specific: "Download free guide" or "Start 14-day
|
||||
trial" tell readers exactly what they'll get.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ Image-Only CTAs</h3>
|
||||
<p className="text-neutral-700">
|
||||
Many email clients block images by default. If your CTA is an image, users won't see it. Use HTML buttons
|
||||
with text.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ Small, Hard-to-Tap Links</h3>
|
||||
<p className="text-neutral-700">
|
||||
Tiny text links are difficult to tap on mobile. Use large buttons (minimum 44x44px) for easy tapping.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ No Clear Value Proposition</h3>
|
||||
<p className="text-neutral-700">
|
||||
Readers won't click if they don't know why they should. Clearly communicate the benefit of clicking before
|
||||
asking them to act.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/email-open-rate"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Open Rates</h3>
|
||||
<p className="text-sm text-neutral-600">Improve opens to get more clicks.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-marketing-best-practices"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Marketing Best Practices</h3>
|
||||
<p className="text-sm text-neutral-600">Complete email marketing guide.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-deliverability"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Deliverability</h3>
|
||||
<p className="text-sm text-neutral-600">Reach the inbox for better engagement.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function EmailDeliverability() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="Email Deliverability Guide: Reach the Inbox Every Time"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
Email deliverability is the measure of how successfully your emails reach recipients' inboxes rather than spam
|
||||
folders or being blocked entirely. Even perfectly crafted emails are worthless if they never reach your
|
||||
audience.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
This comprehensive guide covers everything you need to know about email deliverability—from technical
|
||||
authentication to content best practices—so you can maximize inbox placement rates.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* What is Email Deliverability */}
|
||||
<section id="what-is-deliverability" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What is Email Deliverability?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Email deliverability refers to your ability to deliver emails to subscribers' inboxes. It's measured as a
|
||||
percentage of sent emails that successfully reach the inbox.
|
||||
</p>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-3 mb-8">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<div className="text-3xl font-bold text-green-600 mb-2">95%+</div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Excellent</h3>
|
||||
<p className="text-sm text-neutral-700">
|
||||
Strong sender reputation, proper authentication, engaged audience
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<div className="text-3xl font-bold text-amber-600 mb-2">85-94%</div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Good</h3>
|
||||
<p className="text-sm text-neutral-700">Room for improvement in authentication or engagement</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<div className="text-3xl font-bold text-red-600 mb-2"><85%</div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Poor</h3>
|
||||
<p className="text-sm text-neutral-700">Serious issues requiring immediate attention</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="info" title="Deliverability vs Delivery Rate">
|
||||
<p>
|
||||
<strong>Delivery rate</strong> measures emails that weren't bounced (reached the server).{' '}
|
||||
<strong>Deliverability</strong> measures emails that reached the inbox specifically, not spam. You want both
|
||||
to be high.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Key Factors */}
|
||||
<section id="key-factors" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Key Factors Affecting Deliverability</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Email deliverability depends on multiple interconnected factors:
|
||||
</p>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">1. Sender Reputation</h3>
|
||||
<p className="text-neutral-700">
|
||||
Email providers track your sending behavior over time. High engagement rates, low spam complaints, and few
|
||||
bounces build a positive reputation. Poor practices damage it.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">2. Email Authentication</h3>
|
||||
<p className="text-neutral-700">
|
||||
SPF, DKIM, and DMARC authenticate your emails and prove they're legitimate. Without proper authentication,
|
||||
emails are more likely to be flagged as spam.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">3. Email Content</h3>
|
||||
<p className="text-neutral-700">
|
||||
Spam filters analyze your subject lines, body content, links, and images. Spammy language, excessive
|
||||
links, or misleading content trigger filters.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">4. List Quality & Engagement</h3>
|
||||
<p className="text-neutral-700">
|
||||
Sending to engaged subscribers who want your emails is crucial. High open rates and clicks signal quality.
|
||||
Low engagement or spam complaints hurt deliverability.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">5. Technical Infrastructure</h3>
|
||||
<p className="text-neutral-700">
|
||||
Your sending IP address, domain reputation, and email infrastructure affect how providers perceive your
|
||||
emails. Dedicated IPs and proper warm-up are important at scale.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Best Practices */}
|
||||
<section id="best-practices" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Email Deliverability Best Practices</h2>
|
||||
|
||||
<div className="space-y-8">
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Authentication & Technical Setup</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Configure SPF, DKIM, and DMARC</h4>
|
||||
<p className="text-neutral-700">
|
||||
Implement all three authentication protocols. This proves your emails are legitimate and protects
|
||||
your domain from spoofing.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Use a Dedicated Sending Domain</h4>
|
||||
<p className="text-neutral-700">
|
||||
Send marketing emails from a subdomain (e.g., mail.yourdomain.com) to protect your main domain's
|
||||
reputation if issues arise.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Warm Up New IPs and Domains</h4>
|
||||
<p className="text-neutral-700">
|
||||
If using a new IP or domain, gradually increase sending volume over 2-4 weeks. Sudden high volume
|
||||
from new sources looks suspicious.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">List Management</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Use Double Opt-In</h4>
|
||||
<p className="text-neutral-700">
|
||||
Require subscribers to confirm their email address. This ensures list quality and prevents spam trap
|
||||
addresses from being added.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Clean Your List Regularly</h4>
|
||||
<p className="text-neutral-700">
|
||||
Remove hard bounces immediately and consider removing subscribers who haven't engaged in 6-12
|
||||
months. Inactive subscribers hurt your reputation.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
6
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Make Unsubscribing Easy</h4>
|
||||
<p className="text-neutral-700">
|
||||
Include a clear unsubscribe link in every email. Making it hard to unsubscribe leads to spam
|
||||
complaints, which are much worse for deliverability.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Content Best Practices</h3>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
7
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Avoid Spam Trigger Words</h4>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
Words like "FREE", "ACT NOW", "LIMITED TIME", excessive exclamation marks, and all caps trigger spam
|
||||
filters. Write naturally and professionally.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
8
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Balance Text and Images</h4>
|
||||
<p className="text-neutral-700">
|
||||
Don't send image-only emails. Maintain a healthy text-to-image ratio (at least 60% text). Include
|
||||
alt text for images.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
9
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Use Relevant Subject Lines</h4>
|
||||
<p className="text-neutral-700">
|
||||
Subject lines should accurately reflect email content. Misleading subjects increase spam complaints
|
||||
and damage trust.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Common Issues */}
|
||||
<section id="common-issues" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Common Deliverability Issues & Solutions</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-xl border-2 border-red-200 bg-red-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-red-900 mb-3">Problem: Emails Going to Spam</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Causes:</strong> Poor sender reputation, missing authentication, spammy content, low engagement
|
||||
</p>
|
||||
<p className="text-neutral-700">
|
||||
<strong>Solutions:</strong> Verify SPF/DKIM/DMARC setup, improve email content, segment your list to send
|
||||
to engaged subscribers, warm up sending reputation
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-amber-200 bg-amber-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-amber-900 mb-3">Problem: High Bounce Rate</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Causes:</strong> Invalid email addresses, purchased lists, poor list hygiene
|
||||
</p>
|
||||
<p className="text-neutral-700">
|
||||
<strong>Solutions:</strong> Use double opt-in, validate email addresses, remove hard bounces immediately,
|
||||
regularly clean your list
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-blue-200 bg-blue-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-blue-900 mb-3">Problem: Low Engagement Rates</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Causes:</strong> Irrelevant content, wrong send frequency, stale email list
|
||||
</p>
|
||||
<p className="text-neutral-700">
|
||||
<strong>Solutions:</strong> Segment your audience, personalize content, test send times, re-engagement
|
||||
campaigns for inactive subscribers
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-purple-200 bg-purple-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-purple-900 mb-3">Problem: Blacklisted IP or Domain</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Causes:</strong> Spam complaints, sending to spam traps, compromised account
|
||||
</p>
|
||||
<p className="text-neutral-700">
|
||||
<strong>Solutions:</strong> Check blacklists (MXToolbox, Spamhaus), request delisting, fix underlying
|
||||
issues, consider a new sending domain if severely damaged
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 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>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Delivery Rate</h3>
|
||||
<p className="text-neutral-700">
|
||||
Percentage of emails that didn't bounce. Target: 98%+. Track hard vs soft bounces separately.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Inbox Placement Rate</h3>
|
||||
<p className="text-neutral-700">
|
||||
Percentage of delivered emails that reached the inbox (not spam). Target: 95%+. Use seed list testing.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Spam Complaint Rate</h3>
|
||||
<p className="text-neutral-700">
|
||||
Percentage of recipients who mark as spam. Target: <0.1%. Even 0.3% is concerning.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Engagement Metrics</h3>
|
||||
<p className="text-neutral-700">
|
||||
Open rates, click rates, and unsubscribe rates. Sustained low engagement signals poor deliverability.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="tip" title="Use DMARC Reports">
|
||||
<p>
|
||||
DMARC aggregate reports show authentication success rates and potential spoofing attempts. Review these
|
||||
weekly to catch deliverability issues early.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/what-is-dkim"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">What is DKIM?</h3>
|
||||
<p className="text-sm text-neutral-600">Learn about DKIM email authentication.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/what-is-spf"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">What is SPF?</h3>
|
||||
<p className="text-sm text-neutral-600">Understand SPF records and sender authorization.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-sender-reputation"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Sender Reputation</h3>
|
||||
<p className="text-sm text-neutral-600">Build and maintain sender reputation.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,549 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function EmailMarketingBestPractices() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="Email Marketing Best Practices: The Complete Guide"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
Email marketing remains one of the most effective digital marketing channels, delivering an average ROI of
|
||||
$36-42 for every $1 spent. But success requires following best practices that have evolved with technology,
|
||||
regulations, and user expectations.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
This comprehensive guide covers everything you need to know: from building your list to crafting compelling
|
||||
content, optimizing deliverability, and staying compliant with regulations.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* List Building */}
|
||||
<section id="list-building" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Building Your Email List</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
A high-quality email list is the foundation of successful email marketing. Focus on engaged subscribers who
|
||||
genuinely want to hear from you.
|
||||
</p>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-xl border-2 border-green-200 bg-green-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-green-900 mb-3">✓ Best Practices</h3>
|
||||
<ul className="space-y-3 text-neutral-700">
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="text-green-600 font-bold mt-1">•</span>
|
||||
<span>
|
||||
<strong>Use double opt-in:</strong> Require subscribers to confirm their email address. This ensures
|
||||
list quality and reduces spam complaints.
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="text-green-600 font-bold mt-1">•</span>
|
||||
<span>
|
||||
<strong>Offer clear value:</strong> Explain what subscribers will receive and how often. "Get weekly
|
||||
tips on [topic]" is better than "Subscribe to our newsletter."
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="text-green-600 font-bold mt-1">•</span>
|
||||
<span>
|
||||
<strong>Use multiple touchpoints:</strong> Add signup forms on your website, blog, checkout page,
|
||||
social media, and in-person events.
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="text-green-600 font-bold mt-1">•</span>
|
||||
<span>
|
||||
<strong>Provide incentives:</strong> Lead magnets like ebooks, discounts, templates, or exclusive
|
||||
content encourage signups.
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="text-green-600 font-bold mt-1">•</span>
|
||||
<span>
|
||||
<strong>Make forms easy:</strong> Keep signup forms simple—ask only for essential information (usually
|
||||
just email, sometimes name).
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-red-200 bg-red-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-red-900 mb-3">✗ Avoid These Mistakes</h3>
|
||||
<ul className="space-y-3 text-neutral-700">
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="text-red-600 font-bold mt-1">•</span>
|
||||
<span>
|
||||
<strong>Never buy email lists:</strong> Purchased lists lead to spam complaints, poor engagement, and
|
||||
damaged reputation.
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="text-red-600 font-bold mt-1">•</span>
|
||||
<span>
|
||||
<strong>Don't use pre-checked boxes:</strong> Subscribers must actively opt-in. Pre-checked boxes
|
||||
violate GDPR and reduce engagement.
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<span className="text-red-600 font-bold mt-1">•</span>
|
||||
<span>
|
||||
<strong>Avoid hidden signup terms:</strong> Be transparent about email frequency and content type.
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Content Best Practices */}
|
||||
<section id="content" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Email Content Best Practices</h2>
|
||||
|
||||
<div className="space-y-6 mb-8">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">1. Craft Compelling Subject Lines</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
Your subject line determines whether emails get opened. Keep them under 50 characters, create curiosity,
|
||||
and be specific about value.
|
||||
</p>
|
||||
<div className="rounded-lg bg-neutral-50 p-4">
|
||||
<p className="text-sm font-semibold text-neutral-900 mb-2">Examples:</p>
|
||||
<ul className="space-y-1 text-sm text-neutral-700">
|
||||
<li>✓ "5 proven strategies to reduce churn by 30%"</li>
|
||||
<li>✓ "Your personalized year-end report is ready"</li>
|
||||
<li>✓ "Last chance: Sale ends tonight at midnight"</li>
|
||||
<li>✗ "Newsletter #47"</li>
|
||||
<li>✗ "Check this out!!!"</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">2. Personalize Beyond First Names</h3>
|
||||
<p className="text-neutral-700">
|
||||
Use behavioral data, purchase history, browsing activity, or preferences. Personalized emails deliver 6x
|
||||
higher transaction rates than generic blasts.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">3. Focus on One Primary Goal</h3>
|
||||
<p className="text-neutral-700">
|
||||
Each email should have one clear call-to-action (CTA). Multiple CTAs confuse readers and reduce conversion
|
||||
rates. Guide recipients toward a single action.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">4. Write Scannable Content</h3>
|
||||
<p className="text-neutral-700 mb-3">Most people skim emails. Structure content for easy scanning:</p>
|
||||
<ul className="list-disc list-inside space-y-1 text-neutral-700">
|
||||
<li>Use short paragraphs (2-3 sentences max)</li>
|
||||
<li>Include bullet points and numbered lists</li>
|
||||
<li>Add descriptive subheadings</li>
|
||||
<li>Use white space generously</li>
|
||||
<li>Highlight key points with bold text</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">5. Create Compelling CTAs</h3>
|
||||
<p className="text-neutral-700 mb-3">Effective CTAs are:</p>
|
||||
<ul className="list-disc list-inside space-y-1 text-neutral-700">
|
||||
<li>
|
||||
<strong>Action-oriented:</strong> "Download the guide" not "Click here"
|
||||
</li>
|
||||
<li>
|
||||
<strong>Specific:</strong> "Start your 14-day free trial" not "Get started"
|
||||
</li>
|
||||
<li>
|
||||
<strong>Visually prominent:</strong> Button format with contrasting colors
|
||||
</li>
|
||||
<li>
|
||||
<strong>Urgent when appropriate:</strong> "Claim your discount today"
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">6. Provide Real Value</h3>
|
||||
<p className="text-neutral-700">
|
||||
Every email should benefit the reader. Share insights, solve problems, offer exclusive content, or provide
|
||||
entertainment. Don't just promote—educate and engage.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Design Best Practices */}
|
||||
<section id="design" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Email Design Best Practices</h2>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Mobile-First Design</h3>
|
||||
<p className="text-neutral-700">
|
||||
60%+ of emails are opened on mobile. Use responsive templates, large tap targets (44x44px minimum), and
|
||||
test on multiple devices and email clients.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Optimize Images</h3>
|
||||
<p className="text-neutral-700">
|
||||
Compress images for fast loading, use alt text (many clients block images), and maintain 60/40
|
||||
text-to-image ratio. Never send image-only emails.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Brand Consistency</h3>
|
||||
<p className="text-neutral-700">
|
||||
Use your brand colors, fonts, logo, and voice consistently. Recipients should instantly recognize your
|
||||
emails. Create a template system for efficiency.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Accessible Design</h3>
|
||||
<p className="text-neutral-700">
|
||||
Use sufficient color contrast (4.5:1 minimum), readable font sizes (14px+ for body text), descriptive
|
||||
link text, and semantic HTML for screen readers.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Test Across Email Clients</h3>
|
||||
<p className="text-neutral-700">
|
||||
Email rendering varies dramatically across Gmail, Outlook, Apple Mail, etc. Test your designs across
|
||||
major clients before sending to your full list.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Timing & Frequency */}
|
||||
<section id="timing" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Timing & Frequency Best Practices</h2>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2 mb-8">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Best Send Times (General)</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>
|
||||
<strong>B2B:</strong> Tuesday-Thursday, 10am-11am or 2pm-3pm
|
||||
</li>
|
||||
<li>
|
||||
<strong>B2C:</strong> Varies widely—test evenings and weekends
|
||||
</li>
|
||||
<li>
|
||||
<strong>Avoid:</strong> Monday mornings (inbox overload) and Friday afternoons
|
||||
</li>
|
||||
</ul>
|
||||
<InfoBox type="info" title="Test Your Audience" className="mt-4">
|
||||
<p className="text-sm">
|
||||
These are starting points. Your specific audience may behave differently. A/B test send times and let
|
||||
data guide your strategy.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Email Frequency Guidelines</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>
|
||||
<strong>Weekly:</strong> Most common for newsletters and content
|
||||
</li>
|
||||
<li>
|
||||
<strong>2-3x/week:</strong> Works for engaged audiences with fresh content
|
||||
</li>
|
||||
<li>
|
||||
<strong>Daily:</strong> Only for news, deals, or highly engaged communities
|
||||
</li>
|
||||
<li>
|
||||
<strong>Monthly:</strong> Risk of being forgotten; better for curated content
|
||||
</li>
|
||||
</ul>
|
||||
<InfoBox type="warning" title="Monitor Unsubscribes">
|
||||
<p className="text-sm">
|
||||
If unsubscribe rates spike when you increase frequency, you're sending too often. Find the balance.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Segmentation */}
|
||||
<section id="segmentation" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Segmentation & Personalization</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Segmented campaigns generate 30% more opens and 50% more clicks than non-segmented campaigns. Send targeted
|
||||
messages to specific groups rather than blasting your entire list.
|
||||
</p>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Common Segmentation Criteria</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>
|
||||
• <strong>Demographics:</strong> Age, location, job title, company size
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Behavior:</strong> Purchase history, browsing activity, email engagement
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Lifecycle stage:</strong> New subscriber, active customer, churned user
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Engagement level:</strong> Highly engaged vs inactive subscribers
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Preferences:</strong> Product interests, content topics, email frequency
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Purchase recency:</strong> Recent buyers, lapsed customers
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Segment-Specific Campaigns</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Welcome series for new subscribers</li>
|
||||
<li>• Re-engagement campaigns for inactive users</li>
|
||||
<li>• Win-back campaigns for churned customers</li>
|
||||
<li>• Product recommendations based on past purchases</li>
|
||||
<li>• Location-specific offers and events</li>
|
||||
<li>• VIP campaigns for high-value customers</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Testing & Optimization */}
|
||||
<section id="testing" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Testing & Optimization</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Continuous testing is essential for improving email performance. Never assume—test and let data guide
|
||||
decisions.
|
||||
</p>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">What to A/B Test</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>
|
||||
• <strong>Subject lines:</strong> Length, personalization, questions vs statements, emojis
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Send times:</strong> Day of week, time of day, time zones
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Content:</strong> Long vs short, text vs image-heavy, tone and style
|
||||
</li>
|
||||
<li>
|
||||
• <strong>CTAs:</strong> Button text, color, placement, number of CTAs
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Sender name:</strong> Company name vs person's name
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Personalization:</strong> Generic vs personalized content
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">A/B Testing Best Practices</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>• Test one variable at a time for clear results</li>
|
||||
<li>• Use statistically significant sample sizes (minimum 1,000+ per variant)</li>
|
||||
<li>• Run tests long enough to account for timing variations</li>
|
||||
<li>• Test with random splits, not cherry-picked segments</li>
|
||||
<li>• Implement winners, then test the next variable</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Compliance */}
|
||||
<section id="compliance" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Legal Compliance</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Email marketing is heavily regulated. Non-compliance can result in massive fines and damage to your
|
||||
reputation.
|
||||
</p>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="rounded-xl border-2 border-blue-200 bg-blue-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-blue-900 mb-3">CAN-SPAM (US)</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>• Don't use misleading subject lines or headers</li>
|
||||
<li>• Include your physical mailing address</li>
|
||||
<li>• Provide a clear, easy unsubscribe mechanism</li>
|
||||
<li>• Honor unsubscribe requests within 10 business days</li>
|
||||
<li>• Identify the email as an advertisement (if applicable)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-purple-200 bg-purple-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-purple-900 mb-3">GDPR (EU)</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>• Obtain explicit consent before sending marketing emails</li>
|
||||
<li>• Provide clear information about data usage</li>
|
||||
<li>• Allow subscribers to access, modify, or delete their data</li>
|
||||
<li>• Keep records of consent</li>
|
||||
<li>• Implement appropriate data security measures</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="warning" title="When in Doubt, Get Consent" className="mt-6">
|
||||
<p>
|
||||
Laws vary by jurisdiction. The safest approach is always to get explicit, documented consent before adding
|
||||
anyone to your email list. Make unsubscribing easy and honor requests immediately.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Metrics to Track */}
|
||||
<section id="metrics" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Key Metrics to Track</h2>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Engagement Metrics</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>
|
||||
• <strong>Open rate:</strong> Industry average: 15-25%
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Click-through rate (CTR):</strong> Industry average: 2-5%
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Click-to-open rate (CTOR):</strong> Clicks ÷ opens
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Conversion rate:</strong> Goal completions ÷ delivered
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Health Metrics</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>
|
||||
• <strong>Bounce rate:</strong> Target: <2%
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Unsubscribe rate:</strong> Target: <0.5%
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Spam complaint rate:</strong> Target: <0.1%
|
||||
</li>
|
||||
<li>
|
||||
• <strong>List growth rate:</strong> New subscribers vs unsubscribes
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Business Metrics</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>
|
||||
• <strong>ROI:</strong> Revenue generated ÷ cost
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Revenue per email:</strong> Total revenue ÷ emails sent
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Customer lifetime value (CLV):</strong> Long-term value
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Cost per acquisition (CPA):</strong> Acquisition cost
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Deliverability Metrics</h3>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>
|
||||
• <strong>Delivery rate:</strong> Target: 98%+
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Inbox placement rate:</strong> Target: 95%+
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Sender reputation score:</strong> Monitor regularly
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Authentication status:</strong> SPF, DKIM, DMARC passing
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/email-deliverability"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Deliverability</h3>
|
||||
<p className="text-sm text-neutral-600">Ensure your emails reach the inbox.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-open-rate"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Open Rates</h3>
|
||||
<p className="text-sm text-neutral-600">Improve your open rates with proven tactics.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-click-through-rate"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Click-Through Rate</h3>
|
||||
<p className="text-sm text-neutral-600">Optimize CTAs for more clicks.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,394 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import {CodeBlock} from '../../components/CodeBlock';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function EmailOpenRate() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="Email Open Rate: Benchmarks, Strategies & Best Practices"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
Email open rate measures the percentage of recipients who open your email. It's one of the most important
|
||||
email marketing metrics, indicating how well your subject lines, sender name, and send timing resonate with
|
||||
your audience.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
While recent privacy changes have affected open rate accuracy, it remains a valuable metric for understanding
|
||||
email performance and audience engagement.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* What is Open Rate */}
|
||||
<section id="what-is-open-rate" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What is Email Open Rate?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Open rate is calculated by dividing the number of unique opens by the number of delivered emails (sent emails
|
||||
minus bounces).
|
||||
</p>
|
||||
|
||||
<div className="rounded-xl border-2 border-neutral-900 bg-neutral-50 p-8 mb-8">
|
||||
<div className="text-center">
|
||||
<div className="text-3xl font-bold text-neutral-900 mb-4">Open Rate Formula</div>
|
||||
<CodeBlock
|
||||
language="text"
|
||||
code={`Open Rate = (Unique Opens ÷ Emails Delivered) × 100
|
||||
|
||||
Example:
|
||||
- Sent: 1,000 emails
|
||||
- Bounced: 50 emails
|
||||
- Delivered: 950 emails
|
||||
- Unique Opens: 285
|
||||
|
||||
Open Rate = (285 ÷ 950) × 100 = 30%`}
|
||||
showCopy={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="info" title="Unique vs Total Opens">
|
||||
<p>
|
||||
<strong>Unique opens</strong> count each recipient only once, even if they open multiple times.{' '}
|
||||
<strong>Total opens</strong> count every open. Always use unique opens for open rate calculations to avoid
|
||||
inflated metrics.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Benchmarks */}
|
||||
<section id="benchmarks" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Email Open Rate Benchmarks by Industry</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Open rates vary significantly by industry, audience, and email type:
|
||||
</p>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 overflow-hidden mb-8">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Industry</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Average Open Rate</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Good Open Rate</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-neutral-200 bg-white">
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">SaaS / Technology</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">20-25%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">30%+</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">E-commerce / Retail</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">15-20%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">25%+</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">Financial Services</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">18-23%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">28%+</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">Healthcare</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">20-25%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">30%+</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">Education</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">22-28%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">33%+</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">Media / Publishing</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">18-23%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">28%+</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm text-neutral-900">Non-Profit</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">24-30%</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">35%+</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<InfoBox type="warning" title="Post-Apple MPP Benchmarks">
|
||||
<p>
|
||||
Since Apple Mail Privacy Protection launched in 2021, industry-wide open rates have increased by 5-15
|
||||
percentage points. Compare against your own historical data rather than relying solely on industry
|
||||
benchmarks.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Factors Affecting */}
|
||||
<section id="factors" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What Affects Email Open Rates?</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">1. Subject Line</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
Your subject line is the #1 factor. It must be compelling, relevant, and create curiosity without being
|
||||
clickbait. Personalization and specificity improve opens.
|
||||
</p>
|
||||
<div className="rounded-lg bg-neutral-50 p-4 space-y-2">
|
||||
<div className="flex items-start gap-2">
|
||||
<span className="text-green-600 font-bold">✓</span>
|
||||
<span className="text-sm text-neutral-700">
|
||||
"John, your invoice is ready" (personal, specific, clear)
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<span className="text-green-600 font-bold">✓</span>
|
||||
<span className="text-sm text-neutral-700">
|
||||
"3 proven ways to increase conversion rates" (specific value)
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<span className="text-red-600 font-bold">✗</span>
|
||||
<span className="text-sm text-neutral-700">"You won't believe this!" (clickbait, vague)</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-2">
|
||||
<span className="text-red-600 font-bold">✗</span>
|
||||
<span className="text-sm text-neutral-700">"Newsletter #47" (generic, uninteresting)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">2. Sender Name</h3>
|
||||
<p className="text-neutral-700">
|
||||
Recipients decide whether to open based on who it's from. Use a recognizable name—either your brand or a
|
||||
person from your company. "Company Name" or "John from Company" work better than "noreply@company.com".
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">3. Send Time & Day</h3>
|
||||
<p className="text-neutral-700">
|
||||
Timing impacts visibility. B2B emails typically perform best Tuesday-Thursday, 10am-2pm. B2C varies more
|
||||
by audience—test evenings and weekends. Avoid Monday mornings and Friday afternoons.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">4. List Quality & Segmentation</h3>
|
||||
<p className="text-neutral-700">
|
||||
Engaged subscribers open more. Segmenting by behavior, interests, or demographics ensures relevance.
|
||||
Inactive subscribers drag down open rates—consider re-engagement or removal.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">5. Deliverability & Sender Reputation</h3>
|
||||
<p className="text-neutral-700">
|
||||
If emails land in spam, they won't be opened. Maintain good sender reputation through proper
|
||||
authentication (SPF, DKIM, DMARC), low spam complaints, and high engagement.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">6. Email Frequency</h3>
|
||||
<p className="text-neutral-700">
|
||||
Too frequent leads to fatigue and unsubscribes. Too infrequent and subscribers forget you. Find the sweet
|
||||
spot for your audience—typically 1-4 emails per week for marketing.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">7. Mobile Optimization</h3>
|
||||
<p className="text-neutral-700">
|
||||
60%+ of emails are opened on mobile. Use short subject lines (40-50 characters), clear preview text, and
|
||||
mobile-responsive design to improve mobile open rates.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* How to Improve */}
|
||||
<section id="improve-open-rates" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How to Improve Email Open Rates</h2>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Write Compelling Subject Lines</h3>
|
||||
<p className="text-neutral-700">
|
||||
Test different approaches: questions, personalization, numbers, urgency (without being spammy). Keep
|
||||
them under 50 characters. A/B test to find what resonates with your audience.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Personalize Beyond First Names</h3>
|
||||
<p className="text-neutral-700">
|
||||
Use behavioral data, past purchases, browsing history, or location. "Products you recently viewed" or
|
||||
"Based on your interest in [topic]" outperform generic blasts.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Segment Your Audience</h3>
|
||||
<p className="text-neutral-700">
|
||||
Send targeted emails to specific groups based on engagement level, purchase history, demographics, or
|
||||
interests. Segmented campaigns see 14-100% higher open rates than non-segmented.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Optimize Preview Text</h3>
|
||||
<p className="text-neutral-700">
|
||||
Preview text appears next to the subject line. Use it to complement your subject, add context, or create
|
||||
additional curiosity. Don't let it default to "View this email in your browser".
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Clean Your Email List Regularly</h3>
|
||||
<p className="text-neutral-700">
|
||||
Remove subscribers who haven't engaged in 6-12 months. While this reduces list size, it dramatically
|
||||
improves open rates and sender reputation. Quality over quantity.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
6
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Test Send Times</h3>
|
||||
<p className="text-neutral-700">
|
||||
Run A/B tests sending the same email at different times. Track when your specific audience is most
|
||||
responsive. Send time optimization can improve opens by 20-50%.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
7
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Re-engage Inactive Subscribers</h3>
|
||||
<p className="text-neutral-700">
|
||||
Before removing inactive users, send a re-engagement campaign: "We miss you" or "Still interested?"
|
||||
emails with special offers. Remove those who still don't engage.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
8
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Use a Recognizable Sender Name</h3>
|
||||
<p className="text-neutral-700">
|
||||
Build consistency with your sender name. People are more likely to open emails from names they
|
||||
recognize. Avoid changing it frequently.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Apple MPP Impact */}
|
||||
<section id="apple-mpp" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Apple Mail Privacy Protection Impact</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Since iOS 15, Apple Mail Privacy Protection pre-loads email images and tracking pixels, making open tracking
|
||||
less reliable for Apple Mail users.
|
||||
</p>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="rounded-xl border-2 border-amber-200 bg-amber-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-amber-900 mb-3">What Changed</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>• Apple Mail pre-loads all images automatically</li>
|
||||
<li>• Opens are registered even if user never sees email</li>
|
||||
<li>• 30-50% of email lists use Apple Mail</li>
|
||||
<li>• Open rates appear 5-15% higher than reality</li>
|
||||
<li>• Open-based automation is less accurate</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-blue-200 bg-blue-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-blue-900 mb-3">How to Adapt</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>• Focus on click rates as primary engagement metric</li>
|
||||
<li>• Track conversions and replies, not just opens</li>
|
||||
<li>• Use multi-touch attribution</li>
|
||||
<li>• Compare your own historical data, not industry averages</li>
|
||||
<li>• Segment by email client to understand true engagement</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="tip" title="Beyond Open Rates">
|
||||
<p>
|
||||
With less reliable open tracking, prioritize metrics like click-through rate, conversion rate, reply rate,
|
||||
and revenue per email. These better indicate true engagement and ROI.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/email-click-through-rate"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Click-Through Rate</h3>
|
||||
<p className="text-sm text-neutral-600">Optimize CTAs and improve email clicks.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-deliverability"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Deliverability</h3>
|
||||
<p className="text-sm text-neutral-600">Reach the inbox to maximize opens.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-marketing-best-practices"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Marketing Best Practices</h3>
|
||||
<p className="text-sm text-neutral-600">Complete email marketing strategy guide.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,580 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import {CodeBlock} from '../../components/CodeBlock';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function EmailSenderReputation() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="Email Sender Reputation: Build & Maintain Trust for Better Deliverability"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
Email sender reputation is your sending domain and IP address's trustworthiness score in the eyes of email
|
||||
providers. It's the single most important factor determining whether your emails reach the inbox or spam
|
||||
folder.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
Think of it like a credit score for email: good reputation = inbox placement, bad reputation = spam folder or
|
||||
blocked delivery. This guide explains how reputation works and how to build and maintain it.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* What is Sender Reputation */}
|
||||
<section id="what-is-reputation" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What is Email Sender Reputation?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Sender reputation is a score (typically 0-100) that email providers (Gmail, Outlook, Yahoo) assign to your
|
||||
sending domain and IP address. It's calculated based on your sending history, engagement rates, spam
|
||||
complaints, authentication, and list quality.
|
||||
</p>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-3 mb-8">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<div className="text-3xl font-bold text-green-600 mb-2">80-100</div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Excellent</h3>
|
||||
<p className="text-sm text-neutral-700">
|
||||
Strong inbox placement, trusted sender, high engagement, proper authentication
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<div className="text-3xl font-bold text-amber-600 mb-2">50-79</div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Moderate</h3>
|
||||
<p className="text-sm text-neutral-700">Some emails may reach spam, mixed signals, needs improvement</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<div className="text-3xl font-bold text-red-600 mb-2"><50</div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Poor</h3>
|
||||
<p className="text-sm text-neutral-700">Most emails go to spam or blocked, serious deliverability issues</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="info" title="Domain vs IP Reputation">
|
||||
<p>
|
||||
Email providers track reputation for both your <strong>sending domain</strong> (yourdomain.com) and{' '}
|
||||
<strong>IP address</strong>. Both matter. Domain reputation is more permanent, while IP reputation can be
|
||||
changed by switching IPs (though you have to rebuild it).
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Factors Affecting Reputation */}
|
||||
<section id="factors" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What Affects Sender Reputation?</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">1. Spam Complaint Rate</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Impact: Critical.</strong> When recipients mark your emails as spam, it severely damages
|
||||
reputation. Target: <0.1% (1 complaint per 1,000 emails). Even 0.3% is concerning.
|
||||
</p>
|
||||
<p className="text-sm text-neutral-600">
|
||||
Prevention: Only send to opted-in subscribers, provide value, make unsubscribing easy.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">2. Engagement Metrics</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Impact: Very High.</strong> Email providers track opens, clicks, replies, forwards, and deletes.
|
||||
High engagement signals that recipients want your emails. Low engagement suggests spam.
|
||||
</p>
|
||||
<p className="text-sm text-neutral-600">
|
||||
Boost engagement: Send relevant, valuable content to interested subscribers.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">3. Bounce Rate</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Impact: High.</strong> High bounce rates (especially hard bounces) indicate poor list hygiene,
|
||||
purchased lists, or spam traps. Target: <2% overall bounce rate.
|
||||
</p>
|
||||
<p className="text-sm text-neutral-600">
|
||||
Prevent bounces: Use double opt-in, validate emails, remove hard bounces immediately.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">4. Email Authentication</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Impact: High.</strong> Proper SPF, DKIM, and DMARC authentication proves your emails are
|
||||
legitimate. Missing authentication raises red flags.
|
||||
</p>
|
||||
<p className="text-sm text-neutral-600">
|
||||
Required: Implement all three authentication protocols (SPF, DKIM, DMARC).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">5. Spam Trap Hits</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Impact: Critical.</strong> Spam traps are email addresses used to catch senders with poor
|
||||
practices. Hitting spam traps can get you blacklisted instantly.
|
||||
</p>
|
||||
<p className="text-sm text-neutral-600">
|
||||
Avoid: Never buy lists, use double opt-in, clean old addresses regularly.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">6. Sending Volume & Consistency</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Impact: Moderate.</strong> Sudden spikes in volume look suspicious. Inconsistent sending (long
|
||||
gaps, then huge blasts) damages reputation.
|
||||
</p>
|
||||
<p className="text-sm text-neutral-600">
|
||||
Best practice: Send consistently and gradually increase volume over time (warm-up).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">7. Content Quality</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Impact: Moderate.</strong> Spammy content (excessive links, misleading subject lines, all caps)
|
||||
triggers filters and reduces engagement.
|
||||
</p>
|
||||
<p className="text-sm text-neutral-600">
|
||||
Write naturally: Professional, valuable content that matches subject line promises.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">8. Blacklist Status</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Impact: Critical.</strong> Being listed on major blacklists (Spamhaus, Barracuda, SURBL) can block
|
||||
delivery to entire domains.
|
||||
</p>
|
||||
<p className="text-sm text-neutral-600">
|
||||
Monitor: Regularly check blacklist status and request delisting if listed.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">9. Sending History</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
<strong>Impact: Cumulative.</strong> Reputation is built over time. New domains/IPs have no history (zero
|
||||
reputation) and need to be warmed up gradually.
|
||||
</p>
|
||||
<p className="text-sm text-neutral-600">
|
||||
For new senders: Start with small volumes and gradually increase over 4-8 weeks.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Building Reputation */}
|
||||
<section id="building" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How to Build Sender Reputation</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Building reputation from scratch (new domain or IP) requires patience and best practices:
|
||||
</p>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Warm Up New IPs and Domains</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
Gradually increase sending volume over 4-8 weeks. Start with your most engaged subscribers.
|
||||
</p>
|
||||
<CodeBlock
|
||||
language="text"
|
||||
title="Example Warm-Up Schedule"
|
||||
code={`Week 1: 200-500 emails/day
|
||||
Week 2: 500-1,000 emails/day
|
||||
Week 3: 1,000-5,000 emails/day
|
||||
Week 4: 5,000-10,000 emails/day
|
||||
Week 5: 10,000-20,000 emails/day
|
||||
Week 6: 20,000-50,000 emails/day
|
||||
Week 7: 50,000-100,000 emails/day
|
||||
Week 8+: Full volume
|
||||
|
||||
Adjust based on engagement and bounce rates.`}
|
||||
showCopy={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Start with Highly Engaged Subscribers</h3>
|
||||
<p className="text-neutral-700">
|
||||
During warm-up, send only to subscribers who recently opened or clicked. High engagement in early sends
|
||||
establishes positive reputation quickly.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Implement Full Authentication</h3>
|
||||
<p className="text-neutral-700">
|
||||
Set up SPF, DKIM, and DMARC before sending. Proper authentication is table stakes for building
|
||||
reputation.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Maintain Consistent Sending</h3>
|
||||
<p className="text-neutral-700">
|
||||
Send regularly (daily or weekly) rather than sporadic blasts. Consistency builds trust with email
|
||||
providers.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Use Double Opt-In</h3>
|
||||
<p className="text-neutral-700">
|
||||
Require email confirmation before adding subscribers. This ensures list quality and prevents spam trap
|
||||
addresses from the start.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
6
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Monitor Metrics Closely</h3>
|
||||
<p className="text-neutral-700">
|
||||
Track bounce rate, spam complaints, and engagement during warm-up. If metrics degrade, slow down volume
|
||||
increases and improve list quality.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
7
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Provide Immediate Value</h3>
|
||||
<p className="text-neutral-700">
|
||||
Your first emails set the tone. Deliver on promises made during signup. High engagement on early emails
|
||||
accelerates reputation building.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Maintaining Reputation */}
|
||||
<section id="maintaining" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Maintaining Good Sender Reputation</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Once built, reputation requires ongoing attention:
|
||||
</p>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Clean Your List Regularly</h3>
|
||||
<p className="text-neutral-700 mb-3">Remove or re-engage inactive subscribers every 6-12 months:</p>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Send re-engagement campaigns to inactive subscribers</li>
|
||||
<li>• Remove those who don't re-engage</li>
|
||||
<li>• Immediately remove hard bounces</li>
|
||||
<li>• Remove persistent soft bouncers (3-5 bounces)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Make Unsubscribing Easy</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
Paradoxically, easy unsubscribes protect reputation. Frustrated users who can't unsubscribe mark as spam
|
||||
instead, which is far worse.
|
||||
</p>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Include clear, one-click unsubscribe in every email</li>
|
||||
<li>• Process unsubscribes immediately (don't require confirmation)</li>
|
||||
<li>• Honor unsubscribes permanently</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Monitor Reputation Metrics</h3>
|
||||
<p className="text-neutral-700 mb-3">Track these indicators weekly:</p>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Delivery rate (target: 98%+)</li>
|
||||
<li>• Spam complaint rate (target: <0.1%)</li>
|
||||
<li>• Bounce rate (target: <2%)</li>
|
||||
<li>• Engagement rates (opens, clicks)</li>
|
||||
<li>• Blacklist status (monthly checks)</li>
|
||||
<li>• Sender Score (check quarterly)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Segment and Personalize</h3>
|
||||
<p className="text-neutral-700">
|
||||
Send targeted, relevant emails to specific subscriber groups. Segmentation dramatically improves
|
||||
engagement, which protects reputation.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">
|
||||
Use Separate Domains for Different Email Types
|
||||
</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
Protect critical transactional email reputation by separating from marketing:
|
||||
</p>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Transactional: transact.yourdomain.com</li>
|
||||
<li>• Marketing: news.yourdomain.com or marketing.yourdomain.com</li>
|
||||
<li>• Benefits: Marketing issues won't affect mission-critical transactional emails</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Recovering Damaged Reputation */}
|
||||
<section id="recovery" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Recovering from Damaged Reputation</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
If your reputation suffers, recovery is possible but takes time and discipline:
|
||||
</p>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-amber-50 border border-amber-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-amber-600 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-amber-900 mb-2">Identify the Root Cause</h3>
|
||||
<p className="text-neutral-700">
|
||||
Review recent campaigns for spam complaints, high bounces, poor engagement. Check if you're blacklisted.
|
||||
Find and fix the underlying issue.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-amber-50 border border-amber-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-amber-600 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-amber-900 mb-2">Clean Your List Aggressively</h3>
|
||||
<p className="text-neutral-700">
|
||||
Remove all unengaged subscribers, bounced addresses, and anyone who hasn't opened in 6+ months. Yes,
|
||||
your list shrinks, but quality beats quantity for reputation recovery.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-amber-50 border border-amber-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-amber-600 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-amber-900 mb-2">Reduce Volume Temporarily</h3>
|
||||
<p className="text-neutral-700">
|
||||
Cut sending volume by 50-70% while you fix issues. Send only to highly engaged subscribers. Rebuild
|
||||
trust before scaling back up.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-amber-50 border border-amber-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-amber-600 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-amber-900 mb-2">Request Blacklist Removal</h3>
|
||||
<p className="text-neutral-700">
|
||||
If blacklisted, identify which lists, fix the underlying issues, then request delisting. Most blacklists
|
||||
have removal request processes. Be honest about what you fixed.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-amber-50 border border-amber-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-amber-600 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-amber-900 mb-2">Send Valuable, Engaging Content</h3>
|
||||
<p className="text-neutral-700">
|
||||
Recovery requires proving you send emails people want. Focus on value, not promotions. High engagement
|
||||
signals to providers that you've reformed.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-amber-50 border border-amber-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-amber-600 text-white text-sm font-bold">
|
||||
6
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-amber-900 mb-2">Be Patient</h3>
|
||||
<p className="text-neutral-700">
|
||||
Reputation recovery typically takes 4-12 weeks of consistently good behavior. Monitor metrics closely
|
||||
and don't rush back to high volumes before reputation improves.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="warning" title="Severe Damage May Require Starting Fresh" className="mt-6">
|
||||
<p>
|
||||
If reputation is severely damaged (sender score <30, multiple blacklistings, blocked by major providers),
|
||||
recovery may be impractical. Consider migrating to a new subdomain or IP and starting reputation from
|
||||
scratch. This is a last resort.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Monitoring Tools */}
|
||||
<section id="monitoring" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Reputation Monitoring Tools</h2>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Google Postmaster Tools</h3>
|
||||
<p className="text-sm text-neutral-700 mb-3">
|
||||
Free tool showing domain reputation, spam rate, authentication, and encryption for Gmail delivery.
|
||||
</p>
|
||||
<a
|
||||
href="https://postmaster.google.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-blue-600 hover:underline"
|
||||
>
|
||||
postmaster.google.com →
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Microsoft SNDS</h3>
|
||||
<p className="text-sm text-neutral-700 mb-3">
|
||||
Smart Network Data Services provides data on how Microsoft views your IPs, including spam complaints.
|
||||
</p>
|
||||
<a
|
||||
href="https://sendersupport.olc.protection.outlook.com/snds/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-blue-600 hover:underline"
|
||||
>
|
||||
Microsoft SNDS →
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Sender Score (Validity)</h3>
|
||||
<p className="text-sm text-neutral-700 mb-3">
|
||||
Free sender reputation score (0-100) based on industry data. Widely used benchmark for IP reputation.
|
||||
</p>
|
||||
<a
|
||||
href="https://www.validity.com/everest/senderscore/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-blue-600 hover:underline"
|
||||
>
|
||||
Check Sender Score →
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">MXToolbox Blacklist Check</h3>
|
||||
<p className="text-sm text-neutral-700 mb-3">
|
||||
Check if your domain or IP is on major blacklists. Monitor regularly to catch listings early.
|
||||
</p>
|
||||
<a
|
||||
href="https://mxtoolbox.com/blacklists.aspx"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-blue-600 hover:underline"
|
||||
>
|
||||
MXToolbox →
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Talos Intelligence</h3>
|
||||
<p className="text-sm text-neutral-700 mb-3">
|
||||
Cisco Talos provides sender reputation data. Check your IP's reputation and request delisting if needed.
|
||||
</p>
|
||||
<a
|
||||
href="https://talosintelligence.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-blue-600 hover:underline"
|
||||
>
|
||||
Talos Intelligence →
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">BarracudaCentral</h3>
|
||||
<p className="text-sm text-neutral-700 mb-3">
|
||||
Check reputation and blacklist status on Barracuda's network. Important for enterprise email delivery.
|
||||
</p>
|
||||
<a
|
||||
href="https://www.barracudacentral.org/lookups"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-blue-600 hover:underline"
|
||||
>
|
||||
BarracudaCentral →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/email-deliverability"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Deliverability</h3>
|
||||
<p className="text-sm text-neutral-600">Complete deliverability guide.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-bounce-rate"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Bounce Rate</h3>
|
||||
<p className="text-sm text-neutral-600">Reduce bounces to protect reputation.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/what-is-dkim"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">What is DKIM?</h3>
|
||||
<p className="text-sm text-neutral-600">Email authentication for better reputation.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
import {Footer, Navbar} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Book, Code, Mail, Shield, TrendingUp, Users} from 'lucide-react';
|
||||
|
||||
interface Guide {
|
||||
title: string;
|
||||
description: string;
|
||||
href: string;
|
||||
icon: React.ComponentType<{className?: string}>;
|
||||
badge?: string;
|
||||
}
|
||||
|
||||
const guides: Guide[] = [
|
||||
{
|
||||
title: 'What is DKIM?',
|
||||
description: 'Learn how DKIM email authentication works and why it matters for deliverability.',
|
||||
href: '/guides/what-is-dkim',
|
||||
icon: Shield,
|
||||
badge: 'Authentication',
|
||||
},
|
||||
{
|
||||
title: 'What is SPF?',
|
||||
description: 'Understand SPF records and how they protect your emails from spoofing.',
|
||||
href: '/guides/what-is-spf',
|
||||
icon: Shield,
|
||||
badge: 'Authentication',
|
||||
},
|
||||
{
|
||||
title: 'What is DMARC?',
|
||||
description: 'Complete guide to DMARC policies and email security best practices.',
|
||||
href: '/guides/what-is-dmarc',
|
||||
icon: Shield,
|
||||
badge: 'Authentication',
|
||||
},
|
||||
{
|
||||
title: 'Email Deliverability Guide',
|
||||
description: 'Improve your email deliverability with best practices and proven strategies.',
|
||||
href: '/guides/email-deliverability',
|
||||
icon: TrendingUp,
|
||||
badge: 'Deliverability',
|
||||
},
|
||||
{
|
||||
title: 'Email Open Rates',
|
||||
description: 'Industry benchmarks and strategies to improve your email open rates.',
|
||||
href: '/guides/email-open-rate',
|
||||
icon: Mail,
|
||||
badge: 'Analytics',
|
||||
},
|
||||
{
|
||||
title: 'Email Marketing Best Practices',
|
||||
description: 'Comprehensive guide to email marketing: timing, content, design, and more.',
|
||||
href: '/guides/email-marketing-best-practices',
|
||||
icon: Book,
|
||||
badge: 'Best Practices',
|
||||
},
|
||||
{
|
||||
title: 'Email Bounce Rate',
|
||||
description: 'Understand hard vs soft bounces and how to reduce your bounce rate.',
|
||||
href: '/guides/email-bounce-rate',
|
||||
icon: TrendingUp,
|
||||
badge: 'Deliverability',
|
||||
},
|
||||
{
|
||||
title: 'Email Click-Through Rate',
|
||||
description: 'Optimize your CTAs and improve email click-through rates.',
|
||||
href: '/guides/email-click-through-rate',
|
||||
icon: Mail,
|
||||
badge: 'Analytics',
|
||||
},
|
||||
{
|
||||
title: 'Transactional vs Marketing Email',
|
||||
description: 'Understand the legal and technical differences between email types.',
|
||||
href: '/guides/transactional-vs-marketing-email',
|
||||
icon: Book,
|
||||
badge: 'Fundamentals',
|
||||
},
|
||||
{
|
||||
title: 'Email API Guide',
|
||||
description: 'Everything you need to know about email APIs with code examples.',
|
||||
href: '/guides/email-api-guide',
|
||||
icon: Code,
|
||||
badge: 'Technical',
|
||||
},
|
||||
{
|
||||
title: 'Email Sender Reputation',
|
||||
description: 'Build and maintain a positive sender reputation for better deliverability.',
|
||||
href: '/guides/email-sender-reputation',
|
||||
icon: Users,
|
||||
badge: 'Deliverability',
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Email Guides hub page
|
||||
*/
|
||||
export default function GuidesIndex() {
|
||||
return (
|
||||
<>
|
||||
<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"
|
||||
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'}],
|
||||
}}
|
||||
/>
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<Book className="h-4 w-4 text-neutral-600" />
|
||||
<span className={'text-sm text-neutral-600'}>Free Email Guides</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl'}>
|
||||
Master email
|
||||
<br />
|
||||
marketing & deliverability
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Free guides on email authentication, deliverability, best practices, and technical implementation. Learn
|
||||
from the experts.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Try Plunk free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Guides Grid */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Browse all guides</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Everything you need to master email</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-6 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
{guides.map((guide, index) => {
|
||||
const Icon = guide.icon;
|
||||
return (
|
||||
<motion.div
|
||||
key={guide.href}
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: index * 0.05, ease: [0.22, 1, 0.36, 1]}}
|
||||
>
|
||||
<Link
|
||||
href={guide.href}
|
||||
className={
|
||||
'group block h-full rounded-2xl border border-neutral-200 bg-white p-8 transition hover:border-neutral-300 hover:shadow-lg'
|
||||
}
|
||||
>
|
||||
<div className={'flex items-start justify-between mb-4'}>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Icon className="h-5 w-5" />
|
||||
</div>
|
||||
{guide.badge && (
|
||||
<span className={'rounded-full bg-neutral-100 px-3 py-1 text-xs font-medium text-neutral-700'}>
|
||||
{guide.badge}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<h3 className={'text-xl font-semibold text-neutral-900 mb-2 group-hover:text-neutral-700'}>
|
||||
{guide.title}
|
||||
</h3>
|
||||
<p className={'text-sm text-neutral-600 leading-relaxed'}>{guide.description}</p>
|
||||
</Link>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className={'border-t border-neutral-200 py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Ready to get started?</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Put these guides into practice with Plunk's modern email platform. Start free, no credit card required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
Start free trial
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function TransactionalVsMarketingEmail() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="Transactional vs Marketing Email: Legal & Technical Differences"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
Not all emails are created equal. Transactional and marketing emails serve different purposes, follow
|
||||
different legal rules, and require different strategies. Understanding these differences is essential for
|
||||
compliance, deliverability, and effective email communication.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
This guide explains the key distinctions, legal requirements, and best practices for each email type.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Quick Comparison */}
|
||||
<section id="comparison" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Quick Comparison</h2>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Aspect</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Transactional Email</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold">Marketing Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-neutral-200 bg-white">
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm font-semibold text-neutral-900">Purpose</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Facilitate transaction or provide service info</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Promote products, services, or content</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm font-semibold text-neutral-900">Trigger</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">User action or system event</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Scheduled or campaign-based</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm font-semibold text-neutral-900">Consent Required</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">No (expected as part of service)</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Yes (explicit opt-in required)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm font-semibold text-neutral-900">Unsubscribe Link</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Not required</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Required by law</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm font-semibold text-neutral-900">Open Rate</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">60-80% (very high)</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">15-25% (average)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 text-sm font-semibold text-neutral-900">Volume</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Lower, event-based</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Higher, scheduled campaigns</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Transactional Email */}
|
||||
<section id="transactional" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What is Transactional Email?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Transactional emails are automated messages sent in response to a user's action or system event. They contain
|
||||
information the user needs or expects to facilitate a transaction or use a service.
|
||||
</p>
|
||||
|
||||
<div className="mb-8">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Common Types of Transactional Emails</h3>
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h4 className="font-semibold text-neutral-900 mb-3">Account & Authentication</h4>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Welcome emails after signup</li>
|
||||
<li>• Email verification/confirmation</li>
|
||||
<li>• Password reset requests</li>
|
||||
<li>• Login notifications</li>
|
||||
<li>• Two-factor authentication codes</li>
|
||||
<li>• Account deletion confirmations</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h4 className="font-semibold text-neutral-900 mb-3">Commerce & Transactions</h4>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Order confirmations</li>
|
||||
<li>• Shipping notifications</li>
|
||||
<li>• Delivery updates</li>
|
||||
<li>• Payment receipts</li>
|
||||
<li>• Refund confirmations</li>
|
||||
<li>• Invoice emails</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h4 className="font-semibold text-neutral-900 mb-3">Notifications & Alerts</h4>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Activity notifications</li>
|
||||
<li>• Comment or mention alerts</li>
|
||||
<li>• Security alerts</li>
|
||||
<li>• System status updates</li>
|
||||
<li>• Subscription renewals</li>
|
||||
<li>• Trial expiration notices</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h4 className="font-semibold text-neutral-900 mb-3">Account Management</h4>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Billing statements</li>
|
||||
<li>• Usage reports</li>
|
||||
<li>• Account updates</li>
|
||||
<li>• Plan changes</li>
|
||||
<li>• Subscription confirmations</li>
|
||||
<li>• Account deactivation notices</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Transactional Email Best Practices</h3>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Send Immediately</h4>
|
||||
<p className="text-neutral-700">
|
||||
Transactional emails should be sent within seconds or minutes of the triggering action. Users expect
|
||||
instant confirmation—delays cause anxiety and support tickets.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Prioritize Clarity & Accuracy</h4>
|
||||
<p className="text-neutral-700">
|
||||
Include all critical information: order numbers, amounts, dates, tracking links. Be precise—errors in
|
||||
transactional emails damage trust significantly.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Use Descriptive Subject Lines</h4>
|
||||
<p className="text-neutral-700">
|
||||
Make subject lines scannable and specific: "Your order #12345 has shipped" not "Update from
|
||||
YourCompany". Users should know what the email contains at a glance.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Minimize Promotional Content</h4>
|
||||
<p className="text-neutral-700">
|
||||
The primary content must be transactional. Small promotional sections (cross-sells, upsells) are
|
||||
acceptable at the bottom, but don't turn order confirmations into marketing emails.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Ensure High Deliverability</h4>
|
||||
<p className="text-neutral-700">
|
||||
Use a dedicated sending infrastructure for transactional emails. They're mission-critical—users depend
|
||||
on them. Don't let marketing email issues affect transactional deliverability.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Marketing Email */}
|
||||
<section id="marketing" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What is Marketing Email?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Marketing emails are promotional messages sent to build relationships, drive engagement, and encourage
|
||||
conversions. Recipients must explicitly opt-in to receive them.
|
||||
</p>
|
||||
|
||||
<div className="mb-8">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Common Types of Marketing Emails</h3>
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h4 className="font-semibold text-neutral-900 mb-3">Promotional Campaigns</h4>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Product announcements</li>
|
||||
<li>• Sale and discount promotions</li>
|
||||
<li>• New feature launches</li>
|
||||
<li>• Seasonal campaigns</li>
|
||||
<li>• Limited-time offers</li>
|
||||
<li>• Flash sales</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h4 className="font-semibold text-neutral-900 mb-3">Content Marketing</h4>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Newsletters</li>
|
||||
<li>• Blog post roundups</li>
|
||||
<li>• Educational content</li>
|
||||
<li>• Industry news and trends</li>
|
||||
<li>• Case studies</li>
|
||||
<li>• Webinar invitations</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h4 className="font-semibold text-neutral-900 mb-3">Nurture & Engagement</h4>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Welcome series (beyond initial welcome)</li>
|
||||
<li>• Onboarding sequences</li>
|
||||
<li>• Re-engagement campaigns</li>
|
||||
<li>• Win-back emails</li>
|
||||
<li>• Customer surveys</li>
|
||||
<li>• Loyalty program updates</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h4 className="font-semibold text-neutral-900 mb-3">Lifecycle Marketing</h4>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Abandoned cart reminders</li>
|
||||
<li>• Product recommendations</li>
|
||||
<li>• Upsell/cross-sell campaigns</li>
|
||||
<li>• Birthday or anniversary emails</li>
|
||||
<li>• Renewal reminders (if promotional)</li>
|
||||
<li>• Review requests</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-4">Marketing Email Best Practices</h3>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Always Get Explicit Consent</h4>
|
||||
<p className="text-neutral-700">
|
||||
Use clear opt-in forms (preferably double opt-in). Never add people without permission or use purchased
|
||||
lists. GDPR and CAN-SPAM require explicit consent for marketing emails.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Provide Value, Not Just Promotions</h4>
|
||||
<p className="text-neutral-700">
|
||||
Balance promotional content with educational value, entertainment, or useful information. Subscribers
|
||||
who only receive sales pitches will unsubscribe.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Segment Your Audience</h4>
|
||||
<p className="text-neutral-700">
|
||||
Send targeted emails based on behavior, preferences, demographics, or engagement. Segmented campaigns
|
||||
see 3x higher engagement than mass blasts.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Make Unsubscribing Easy</h4>
|
||||
<p className="text-neutral-700">
|
||||
Include a clear, one-click unsubscribe link in every email (required by law). Making it hard to
|
||||
unsubscribe leads to spam complaints, which are much worse for deliverability.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-2">Test and Optimize</h4>
|
||||
<p className="text-neutral-700">
|
||||
A/B test subject lines, send times, content, and CTAs. Marketing emails benefit from continuous
|
||||
optimization based on performance data.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Legal Requirements */}
|
||||
<section id="legal" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Legal Requirements</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
The legal distinction between transactional and marketing emails is critical. Violating these rules can result
|
||||
in significant fines and damage to your reputation.
|
||||
</p>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="rounded-xl border-2 border-blue-200 bg-blue-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-blue-900 mb-4">Transactional Email Laws</h3>
|
||||
<div className="space-y-3 text-neutral-700">
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-1">CAN-SPAM (US)</h4>
|
||||
<p className="text-sm">Exempt from most requirements but must not include false/misleading headers</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-1">GDPR (EU)</h4>
|
||||
<p className="text-sm">
|
||||
Allowed as "legitimate interest" for service provision. Must still protect user data and allow opt-out
|
||||
of optional transactional emails
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-1">Key Point</h4>
|
||||
<p className="text-sm">
|
||||
Transactional emails don't require explicit consent or unsubscribe links, but abuse this category (by
|
||||
making promotional emails appear transactional) violates laws
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-purple-200 bg-purple-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-purple-900 mb-4">Marketing Email Laws</h3>
|
||||
<div className="space-y-3 text-neutral-700">
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-1">CAN-SPAM (US)</h4>
|
||||
<ul className="text-sm space-y-1">
|
||||
<li>• Clear opt-out mechanism (unsubscribe link)</li>
|
||||
<li>• Honor opt-outs within 10 business days</li>
|
||||
<li>• Include physical mailing address</li>
|
||||
<li>• Identify message as advertisement</li>
|
||||
<li>• No false/misleading subject lines or headers</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-900 mb-1">GDPR (EU)</h4>
|
||||
<ul className="text-sm space-y-1">
|
||||
<li>• Explicit opt-in consent required</li>
|
||||
<li>• Clear information about data usage</li>
|
||||
<li>• Easy opt-out anytime</li>
|
||||
<li>• Right to data access/deletion</li>
|
||||
<li>• Records of consent</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="warning" title="Don't Abuse the Transactional Category" className="mt-6">
|
||||
<p>
|
||||
It's illegal and unethical to disguise marketing emails as transactional to avoid consent requirements.
|
||||
Regulators and ISPs actively monitor for this abuse. Keep transactional emails purely functional.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Infrastructure Considerations */}
|
||||
<section id="infrastructure" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Infrastructure & Sending Practices</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Separate Sending Domains</h3>
|
||||
<p className="text-neutral-700 mb-3">Use different subdomains for transactional and marketing emails:</p>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>
|
||||
• <strong>Transactional:</strong> transact.yourdomain.com or mail.yourdomain.com
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Marketing:</strong> marketing.yourdomain.com or news.yourdomain.com
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Benefit:</strong> Protects critical transactional email reputation from marketing
|
||||
deliverability issues
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Dedicated IP Addresses (High Volume)</h3>
|
||||
<p className="text-neutral-700 mb-3">For organizations sending 100,000+ emails/month:</p>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>• Use separate dedicated IPs for transactional and marketing</li>
|
||||
<li>• Properly warm up new IPs to build sender reputation</li>
|
||||
<li>• Monitor reputation for each IP independently</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Monitoring & Analytics</h3>
|
||||
<p className="text-neutral-700 mb-3">Track metrics separately for each type:</p>
|
||||
<ul className="space-y-2 text-sm text-neutral-700">
|
||||
<li>
|
||||
• <strong>Transactional:</strong> Delivery rate (target: 99%+), delivery speed, bounce rate
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Marketing:</strong> Open rate, CTR, conversions, engagement, unsubscribe rate
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* The Gray Area */}
|
||||
<section id="gray-area" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">The Gray Area: What's What?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Some emails can be tricky to categorize. Here's guidance:
|
||||
</p>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="rounded-xl border-2 border-green-200 bg-green-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-green-900 mb-3">Clearly Transactional</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>✓ Order confirmations and shipping updates</li>
|
||||
<li>✓ Password resets and account verification</li>
|
||||
<li>✓ Billing receipts and invoices</li>
|
||||
<li>✓ System alerts and security notifications</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-amber-200 bg-amber-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-amber-900 mb-3">Gray Area (Be Careful)</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>
|
||||
• <strong>Cart abandonment:</strong> If purely reminder = transactional. If includes promotions =
|
||||
marketing
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Review requests:</strong> If tied to recent purchase = transactional. If general request =
|
||||
marketing
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Welcome emails:</strong> Initial verification = transactional. Follow-up series = marketing
|
||||
</li>
|
||||
<li>
|
||||
• <strong>Renewal reminders:</strong> If informational only = transactional. If promotional = marketing
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-red-200 bg-red-50 p-6">
|
||||
<h3 className="text-xl font-semibold text-red-900 mb-3">Clearly Marketing</h3>
|
||||
<ul className="space-y-2 text-neutral-700">
|
||||
<li>✗ Newsletters and content roundups</li>
|
||||
<li>✗ Product announcements and promotions</li>
|
||||
<li>✗ Sales and discount offers</li>
|
||||
<li>✗ Educational content and webinars</li>
|
||||
<li>✗ Re-engagement campaigns</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="tip" title="When in Doubt" className="mt-6">
|
||||
<p>
|
||||
If you're unsure whether an email is transactional or marketing, err on the side of treating it as
|
||||
marketing. Include an unsubscribe link, get proper consent, and follow all marketing email regulations.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/email-api-guide"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email API Guide</h3>
|
||||
<p className="text-sm text-neutral-600">Implement transactional emails with APIs.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-marketing-best-practices"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Marketing Best Practices</h3>
|
||||
<p className="text-sm text-neutral-600">Complete marketing email guide.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-deliverability"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Deliverability</h3>
|
||||
<p className="text-sm text-neutral-600">Ensure both email types reach the inbox.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import {CodeBlock} from '../../components/CodeBlock';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function WhatIsDKIM() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="What is DKIM? Email Authentication Explained"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
DKIM (DomainKeys Identified Mail) is an email authentication method that allows receiving mail servers to
|
||||
verify that an email was actually sent by the domain it claims to be from and that the message wasn't altered
|
||||
in transit.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
Think of DKIM as a digital signature for your emails—like a wax seal on a letter that proves it's authentic
|
||||
and hasn't been tampered with.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* How DKIM Works */}
|
||||
<section id="how-dkim-works" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How DKIM Works</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
DKIM uses cryptographic authentication to validate emails. Here's the process:
|
||||
</p>
|
||||
|
||||
<div className="space-y-6 mb-8">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">1. The Sending Server Signs the Email</h3>
|
||||
<p className="text-neutral-700">
|
||||
When you send an email, your email server adds a DKIM signature to the email header. This signature is
|
||||
created using a private key that only your server knows.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">2. The Signature is Added to Headers</h3>
|
||||
<p className="text-neutral-700">
|
||||
The DKIM signature includes a hash of specific email components (like the subject, body, and sender) and
|
||||
is added to the email headers as a "DKIM-Signature" field.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">3. The Receiving Server Verifies</h3>
|
||||
<p className="text-neutral-700">
|
||||
When the email arrives, the receiving server looks up your domain's public DKIM key in DNS, then uses it
|
||||
to verify the signature. If everything matches, the email passes DKIM authentication.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">4. Delivery Decision</h3>
|
||||
<p className="text-neutral-700">
|
||||
Passing DKIM verification improves your sender reputation and deliverability. Failing or missing DKIM may
|
||||
result in emails being flagged as suspicious or sent to spam.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="tip" title="Technical Detail">
|
||||
<p>
|
||||
DKIM uses asymmetric cryptography (public/private key pairs). The private key stays secure on your mail
|
||||
server, while the public key is published in your DNS records for anyone to verify.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* DKIM Record Example */}
|
||||
<section id="dkim-record-example" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What Does a DKIM Record Look Like?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
A DKIM record is a TXT record in your DNS that contains your public key. Here's an example:
|
||||
</p>
|
||||
|
||||
<CodeBlock
|
||||
language="dns"
|
||||
title="Example DKIM DNS Record"
|
||||
code={`default._domainkey.yourdomain.com IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3QEKyU1fSma0axspqYK5iAj+54lsAg4qRRCnpKK68hawSJfliq9vKD6czJ..."
|
||||
|
||||
# Breaking down the components:
|
||||
# v=DKIM1 -> DKIM version
|
||||
# k=rsa -> Key type (RSA encryption)
|
||||
# p=MIGfMA0... -> Public key (base64 encoded)`}
|
||||
/>
|
||||
|
||||
<InfoBox type="info" title="Selector Names">
|
||||
<p>
|
||||
The "default" in <code>default._domainkey</code> is called a selector. You can use different selectors to
|
||||
rotate keys or separate different email streams (e.g., marketing, transactional).
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Why DKIM Matters */}
|
||||
<section id="why-dkim-matters" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Why DKIM Matters for Email Deliverability</h2>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2 mb-8">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Prevents Email Spoofing</h3>
|
||||
<p className="text-neutral-700">
|
||||
DKIM makes it nearly impossible for spammers to forge emails from your domain. The cryptographic signature
|
||||
can't be replicated without your private key.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Improves Deliverability</h3>
|
||||
<p className="text-neutral-700">
|
||||
Major email providers (Gmail, Outlook, Yahoo) use DKIM as a trust signal. Emails with valid DKIM
|
||||
signatures are more likely to reach the inbox.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Protects Brand Reputation</h3>
|
||||
<p className="text-neutral-700">
|
||||
By preventing domain spoofing, DKIM protects your brand from being used in phishing attacks that could
|
||||
damage your reputation.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Enables DMARC</h3>
|
||||
<p className="text-neutral-700">
|
||||
DKIM is a prerequisite for implementing DMARC, which provides even stronger email authentication and
|
||||
reporting capabilities.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="warning" title="Gmail & Yahoo Requirements">
|
||||
<p>
|
||||
As of February 2024, Gmail and Yahoo require DKIM authentication for bulk senders (5,000+ emails/day). Even
|
||||
if you send less, implementing DKIM is considered a best practice.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* DKIM Signature Example */}
|
||||
<section id="dkim-signature-example" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">What Does a DKIM Signature Look Like?</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
When you send an email, the DKIM signature is added to the email headers. Here's what it looks like:
|
||||
</p>
|
||||
|
||||
<CodeBlock
|
||||
language="text"
|
||||
title="DKIM-Signature Header Example"
|
||||
code={`DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
|
||||
d=yourdomain.com; s=default;
|
||||
h=from:subject:date:message-id:to;
|
||||
bh=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN/XKdLCPjaYaY=;
|
||||
b=GJwP3Qr8KqKKKNT5HL8j3fjXvLEm9KmZs6YdO2KqEqr...
|
||||
|
||||
# Key components:
|
||||
# v=1 -> DKIM version
|
||||
# d=yourdomain.com -> Signing domain
|
||||
# s=default -> Selector (matches DNS record)
|
||||
# h=from:subject... -> Headers included in signature
|
||||
# bh=frcCV1... -> Hash of email body
|
||||
# b=GJwP3Q... -> The actual signature`}
|
||||
/>
|
||||
</section>
|
||||
|
||||
{/* How Plunk Handles DKIM */}
|
||||
<section id="plunk-dkim" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How Plunk Simplifies DKIM</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
Setting up DKIM manually can be complex, but Plunk makes it automatic:
|
||||
</p>
|
||||
|
||||
<div className="space-y-4 mb-8">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Automatic Key Generation</h3>
|
||||
<p className="text-neutral-700">
|
||||
Plunk automatically generates secure DKIM key pairs for your domain when you add it to your account.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Simple DNS Setup</h3>
|
||||
<p className="text-neutral-700">
|
||||
We provide the exact DNS records you need to add—just copy and paste into your DNS provider.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Automatic Signing</h3>
|
||||
<p className="text-neutral-700">
|
||||
Every email you send through Plunk is automatically signed with DKIM. No configuration needed.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Verification & Monitoring</h3>
|
||||
<p className="text-neutral-700">
|
||||
Plunk verifies your DKIM setup and monitors authentication status for all your emails.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="success" title="Ready in Minutes">
|
||||
<p>
|
||||
Most Plunk users have DKIM fully configured and working within 5-10 minutes. Our dashboard guides you
|
||||
through every step.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* DKIM Best Practices */}
|
||||
<section id="dkim-best-practices" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">DKIM Best Practices</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-l-4 border-green-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✓ Use 2048-bit Keys</h3>
|
||||
<p className="text-neutral-700">
|
||||
While 1024-bit keys still work, 2048-bit keys provide better security and are recommended by Gmail and
|
||||
other providers.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-green-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✓ Implement SPF and DMARC Too</h3>
|
||||
<p className="text-neutral-700">
|
||||
DKIM works best when combined with SPF and DMARC for comprehensive email authentication. Use all three for
|
||||
maximum protection.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-green-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✓ Monitor DKIM Status</h3>
|
||||
<p className="text-neutral-700">
|
||||
Regularly check that your DKIM signatures are passing. Most email platforms provide authentication
|
||||
reports.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-green-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✓ Rotate Keys Periodically</h3>
|
||||
<p className="text-neutral-700">
|
||||
For enhanced security, rotate your DKIM keys every 6-12 months. Plan key rotation carefully to avoid
|
||||
delivery disruptions.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ Don't Share Private Keys</h3>
|
||||
<p className="text-neutral-700">
|
||||
Your DKIM private key should never be shared or stored insecurely. Treat it like a password.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ Don't Use the Same Key Across Domains</h3>
|
||||
<p className="text-neutral-700">
|
||||
Each domain should have its own unique DKIM key pair for security and proper authentication.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Authentication Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/what-is-spf"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">What is SPF?</h3>
|
||||
<p className="text-sm text-neutral-600">Learn about SPF records and how they complement DKIM.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/what-is-dmarc"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">What is DMARC?</h3>
|
||||
<p className="text-sm text-neutral-600">Complete guide to DMARC policies and email security.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-deliverability"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Deliverability Guide</h3>
|
||||
<p className="text-sm text-neutral-600">Improve your email deliverability with best practices.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,351 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import {CodeBlock} from '../../components/CodeBlock';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function WhatIsDMARC() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="What is DMARC? Email Policy & Reporting Explained"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
DMARC (Domain-based Message Authentication, Reporting, and Conformance) is an email authentication protocol
|
||||
that builds on SPF and DKIM to protect your domain from email spoofing and phishing.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
While SPF and DKIM authenticate emails, DMARC tells receiving servers what to do when authentication fails and
|
||||
provides reports about your email authentication status.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* How DMARC Works */}
|
||||
<section id="how-dmarc-works" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How DMARC Works</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
DMARC adds a policy layer on top of SPF and DKIM. Here's how it works:
|
||||
</p>
|
||||
|
||||
<div className="space-y-6 mb-8">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">1. Email Authentication</h3>
|
||||
<p className="text-neutral-700">
|
||||
When an email is received, the server first checks SPF and DKIM authentication. At least one of these must
|
||||
pass for DMARC to pass.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">2. Alignment Check</h3>
|
||||
<p className="text-neutral-700">
|
||||
DMARC checks if the domain in the "From" header aligns with the domain that passed SPF or DKIM. This is
|
||||
called "identifier alignment."
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">3. Policy Application</h3>
|
||||
<p className="text-neutral-700">
|
||||
If authentication and alignment pass, the email is delivered. If they fail, the receiving server follows
|
||||
your DMARC policy: none (monitor only), quarantine (send to spam), or reject (block completely).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">4. Reporting</h3>
|
||||
<p className="text-neutral-700">
|
||||
Receiving servers send daily reports to your specified email address, showing authentication results for
|
||||
all emails claiming to be from your domain.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="info" title="DMARC Requires SPF or DKIM">
|
||||
<p>
|
||||
DMARC doesn't work alone—you must have SPF and/or DKIM configured first. DMARC builds on these protocols to
|
||||
provide policy enforcement and reporting.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* DMARC Record Syntax */}
|
||||
<section id="dmarc-record-syntax" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">DMARC Record Syntax</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
A DMARC record is a TXT record published at <code>_dmarc.yourdomain.com</code>. Here's an example:
|
||||
</p>
|
||||
|
||||
<CodeBlock
|
||||
language="dns"
|
||||
title="Example DMARC Record"
|
||||
code={`_dmarc.yourdomain.com IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]; ruf=mailto:[email protected]; pct=100; adkim=r; aspf=r"
|
||||
|
||||
# Breaking down the components:
|
||||
# v=DMARC1 -> DMARC version
|
||||
# p=quarantine -> Policy (none, quarantine, or reject)
|
||||
# rua=mailto:[email protected] -> Aggregate report email
|
||||
# ruf=mailto:[email protected] -> Forensic report email
|
||||
# pct=100 -> Percentage of mail to apply policy (100%)
|
||||
# adkim=r -> DKIM alignment mode (r=relaxed, s=strict)
|
||||
# aspf=r -> SPF alignment mode (r=relaxed, s=strict)`}
|
||||
/>
|
||||
|
||||
<div className="mt-8 space-y-6">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">DMARC Policy Tags</h3>
|
||||
<div className="rounded-xl border border-neutral-200 overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead className="bg-neutral-50">
|
||||
<tr>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-neutral-900">Tag</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-neutral-900">Description</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-neutral-900">Required</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-neutral-200">
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">v</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">DMARC version (always DMARC1)</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Yes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">p</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Policy: none, quarantine, or reject</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Yes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">rua</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Aggregate report email address</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Recommended</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">ruf</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Forensic report email address</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Optional</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">pct</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Percentage of mail to filter (0-100)</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Optional</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">sp</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Policy for subdomains</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Optional</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">adkim</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">DKIM alignment: r (relaxed) or s (strict)</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Optional</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">aspf</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">SPF alignment: r (relaxed) or s (strict)</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Optional</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* DMARC Policies */}
|
||||
<section id="dmarc-policies" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Understanding DMARC Policies</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
DMARC offers three policy levels. You should implement them progressively:
|
||||
</p>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="rounded-xl border-2 border-blue-200 bg-blue-50 p-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-blue-600 text-white font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-blue-900 mb-2">p=none (Monitor Mode)</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
No action is taken on failed emails—they're still delivered. Use this initially to monitor your email
|
||||
authentication without affecting delivery.
|
||||
</p>
|
||||
<CodeBlock language="dns" code={`v=DMARC1; p=none; rua=mailto:[email protected]`} showCopy={false} />
|
||||
<p className="text-sm text-neutral-600 mt-3">
|
||||
<strong>Best for:</strong> Initial setup, gathering data, testing configuration
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-amber-200 bg-amber-50 p-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-amber-600 text-white font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-amber-900 mb-2">p=quarantine (Quarantine Failed Mail)</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
Emails that fail authentication are sent to spam/junk folders. This is a good middle ground that
|
||||
protects your domain while minimizing delivery issues.
|
||||
</p>
|
||||
<CodeBlock
|
||||
language="dns"
|
||||
code={`v=DMARC1; p=quarantine; rua=mailto:[email protected]; pct=100`}
|
||||
showCopy={false}
|
||||
/>
|
||||
<p className="text-sm text-neutral-600 mt-3">
|
||||
<strong>Best for:</strong> After monitoring, when you're confident in your setup
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border-2 border-red-200 bg-red-50 p-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-red-600 text-white font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-red-900 mb-2">p=reject (Block Failed Mail)</h3>
|
||||
<p className="text-neutral-700 mb-3">
|
||||
Emails that fail authentication are completely rejected and not delivered. This provides maximum
|
||||
protection but requires perfect configuration.
|
||||
</p>
|
||||
<CodeBlock
|
||||
language="dns"
|
||||
code={`v=DMARC1; p=reject; rua=mailto:[email protected]; pct=100`}
|
||||
showCopy={false}
|
||||
/>
|
||||
<p className="text-sm text-neutral-600 mt-3">
|
||||
<strong>Best for:</strong> Mature implementations with complete authentication coverage
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="warning" title="Progressive Implementation">
|
||||
<p>
|
||||
Always start with <code>p=none</code> and monitor for at least 2-4 weeks. Review DMARC reports, fix any
|
||||
authentication issues, then gradually move to <code>p=quarantine</code> and finally <code>p=reject</code>.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Setting Up DMARC */}
|
||||
<section id="setting-up-dmarc" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How to Set Up DMARC</h2>
|
||||
|
||||
<div className="space-y-4 mb-8">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Ensure SPF and DKIM are Working</h3>
|
||||
<p className="text-neutral-700">
|
||||
DMARC requires either SPF or DKIM (or both) to be configured. Verify these are working before
|
||||
implementing DMARC.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Create a Mailbox for Reports</h3>
|
||||
<p className="text-neutral-700">
|
||||
Set up an email address to receive DMARC reports (e.g., [email protected]). These reports can be
|
||||
large and frequent, so use a dedicated mailbox.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Create Your DMARC Record</h3>
|
||||
<p className="text-neutral-700 mb-3">Start with a monitoring-only policy:</p>
|
||||
<CodeBlock language="dns" code={`v=DMARC1; p=none; rua=mailto:[email protected]; pct=100`} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Add to DNS</h3>
|
||||
<p className="text-neutral-700">
|
||||
Add the DMARC record as a TXT record at <code>_dmarc.yourdomain.com</code>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Monitor Reports</h3>
|
||||
<p className="text-neutral-700">
|
||||
Review DMARC reports for 2-4 weeks. Look for failed authentications and identify any legitimate sources
|
||||
that need SPF/DKIM configuration.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
6
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Gradually Increase Policy</h3>
|
||||
<p className="text-neutral-700">
|
||||
Once confident, update to <code>p=quarantine</code>, monitor again, then move to <code>p=reject</code>{' '}
|
||||
if desired.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Authentication Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/what-is-dkim"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">What is DKIM?</h3>
|
||||
<p className="text-sm text-neutral-600">Learn how DKIM authenticates email content.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/what-is-spf"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">What is SPF?</h3>
|
||||
<p className="text-sm text-neutral-600">Understand SPF records and server authorization.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-deliverability"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Deliverability Guide</h3>
|
||||
<p className="text-sm text-neutral-600">Complete guide to improving email deliverability.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
import React from 'react';
|
||||
import {GuideLayout, InfoBox} from '../../components/guides';
|
||||
import {CodeBlock} from '../../components/CodeBlock';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function WhatIsSPF() {
|
||||
return (
|
||||
<GuideLayout
|
||||
title="What is SPF? Email Sender Policy Framework Explained"
|
||||
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"
|
||||
>
|
||||
{/* Introduction */}
|
||||
<section id="introduction" className="mb-12">
|
||||
<p className="text-neutral-700 leading-relaxed">
|
||||
SPF (Sender Policy Framework) is an email authentication protocol that allows domain owners to specify which
|
||||
mail servers are authorized to send emails on behalf of their domain.
|
||||
</p>
|
||||
<p className="mt-4 text-neutral-700 leading-relaxed">
|
||||
Think of SPF as a guest list for your domain—it tells receiving servers, "These are the only servers allowed
|
||||
to send email using my domain name."
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* How SPF Works */}
|
||||
<section id="how-spf-works" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How SPF Works</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
SPF works by publishing a list of authorized sending servers in your DNS records. Here's the process:
|
||||
</p>
|
||||
|
||||
<div className="space-y-6 mb-8">
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">1. You Publish an SPF Record</h3>
|
||||
<p className="text-neutral-700">
|
||||
You add a TXT record to your domain's DNS that lists all IP addresses and services authorized to send
|
||||
email from your domain.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">2. An Email is Sent</h3>
|
||||
<p className="text-neutral-700">
|
||||
When someone sends an email claiming to be from your domain, the receiving server notes the IP address of
|
||||
the sending server.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">3. The Receiving Server Checks SPF</h3>
|
||||
<p className="text-neutral-700">
|
||||
The receiving server looks up your domain's SPF record in DNS and checks if the sending server's IP
|
||||
address is listed as authorized.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-neutral-900 pl-6">
|
||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">4. Pass or Fail</h3>
|
||||
<p className="text-neutral-700">
|
||||
If the IP matches, SPF passes. If not, SPF fails and the email may be flagged as spam or rejected,
|
||||
depending on your policy.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="info" title="SPF Validates the Server, Not the Content">
|
||||
<p>
|
||||
Unlike DKIM which validates email content, SPF only checks if the sending server is authorized. This is why
|
||||
using both SPF and DKIM together provides stronger authentication.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* SPF Record Syntax */}
|
||||
<section id="spf-record-syntax" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">SPF Record Syntax</h2>
|
||||
<p className="text-neutral-700 leading-relaxed mb-6">
|
||||
An SPF record is a TXT record with a specific format. Here's a typical example:
|
||||
</p>
|
||||
|
||||
<CodeBlock
|
||||
language="dns"
|
||||
title="Example SPF Record"
|
||||
code={`v=spf1 include:_spf.google.com include:sendgrid.net ip4:192.0.2.1 ~all
|
||||
|
||||
# Breaking down the components:
|
||||
# v=spf1 -> SPF version (always v=spf1)
|
||||
# include:_spf.google.com -> Include Google's SPF record
|
||||
# include:sendgrid.net -> Include SendGrid's SPF record
|
||||
# ip4:192.0.2.1 -> Authorize specific IPv4 address
|
||||
# ~all -> Soft fail for all others`}
|
||||
/>
|
||||
|
||||
<div className="mt-8 space-y-6">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Common SPF Mechanisms</h3>
|
||||
<div className="rounded-xl border border-neutral-200 overflow-hidden">
|
||||
<table className="w-full">
|
||||
<thead className="bg-neutral-50">
|
||||
<tr>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-neutral-900">Mechanism</th>
|
||||
<th className="px-6 py-3 text-left text-sm font-semibold text-neutral-900">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-neutral-200">
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">ip4:192.0.2.1</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Authorize specific IPv4 address</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">ip6:2001:db8::1</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Authorize specific IPv6 address</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">include:domain.com</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Include another domain's SPF record</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">a</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Authorize domain's A record IP</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">mx</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Authorize domain's MX record IPs</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">~all</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Soft fail (treat others as suspicious)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-6 py-4 font-mono text-sm text-neutral-900">-all</td>
|
||||
<td className="px-6 py-4 text-sm text-neutral-700">Hard fail (reject all others)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="warning" title="10 DNS Lookup Limit">
|
||||
<p>
|
||||
SPF has a hard limit of 10 DNS lookups. Each <code>include:</code> mechanism counts as one lookup. Exceeding
|
||||
this limit causes SPF validation to fail. Keep your SPF record concise and avoid excessive includes.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Why SPF Matters */}
|
||||
<section id="why-spf-matters" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Why SPF Matters</h2>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2 mb-8">
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Prevents Email Spoofing</h3>
|
||||
<p className="text-neutral-700">
|
||||
SPF makes it much harder for spammers to send emails that appear to come from your domain. Only authorized
|
||||
servers can send on your behalf.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Improves Deliverability</h3>
|
||||
<p className="text-neutral-700">
|
||||
Emails from domains with proper SPF records are more trusted by receiving servers, leading to better inbox
|
||||
placement rates.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Protects Your Domain</h3>
|
||||
<p className="text-neutral-700">
|
||||
By specifying authorized senders, you protect your domain from being used in phishing and spam campaigns.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-6">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-3">Required for DMARC</h3>
|
||||
<p className="text-neutral-700">
|
||||
SPF (along with DKIM) is necessary for implementing DMARC, which provides comprehensive email
|
||||
authentication and reporting.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Setting Up SPF */}
|
||||
<section id="setting-up-spf" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How to Set Up SPF</h2>
|
||||
|
||||
<div className="space-y-4 mb-8">
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
1
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Identify All Email Senders</h3>
|
||||
<p className="text-neutral-700">
|
||||
List all services and servers that send email from your domain: your email service provider, marketing
|
||||
tools, support systems, etc.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Gather SPF Include Values</h3>
|
||||
<p className="text-neutral-700 mb-3">Each email service provides SPF values to include. For example:</p>
|
||||
<CodeBlock
|
||||
language="text"
|
||||
code={`Google Workspace: include:_spf.google.com
|
||||
Microsoft 365: include:spf.protection.outlook.com
|
||||
Plunk: include:spf.useplunk.com
|
||||
SendGrid: include:sendgrid.net`}
|
||||
showCopy={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Create Your SPF Record</h3>
|
||||
<p className="text-neutral-700 mb-3">Combine all authorized senders into one SPF record:</p>
|
||||
<CodeBlock language="dns" code={`v=spf1 include:_spf.google.com include:spf.useplunk.com ~all`} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
4
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Add to DNS</h3>
|
||||
<p className="text-neutral-700">
|
||||
Add the SPF record as a TXT record in your DNS settings. The record name should be your root domain
|
||||
(e.g., "@" or "yourdomain.com").
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4 p-6 rounded-xl bg-neutral-50 border border-neutral-200">
|
||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-900 text-white text-sm font-bold">
|
||||
5
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-neutral-900 mb-2">Verify SPF</h3>
|
||||
<p className="text-neutral-700">
|
||||
Use SPF validation tools to confirm your record is correct and doesn't exceed the 10 DNS lookup limit.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InfoBox type="success" title="Plunk Handles This Automatically">
|
||||
<p>
|
||||
When you set up a domain in Plunk, we provide the exact SPF record you need. Just copy and paste it into
|
||||
your DNS, and we'll verify it's working correctly.
|
||||
</p>
|
||||
</InfoBox>
|
||||
</section>
|
||||
|
||||
{/* Common SPF Mistakes */}
|
||||
<section id="common-mistakes" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Common SPF Mistakes to Avoid</h2>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ Multiple SPF Records</h3>
|
||||
<p className="text-neutral-700">
|
||||
Never create multiple SPF TXT records. You can only have ONE SPF record per domain. Combine all authorized
|
||||
senders into a single record.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ Exceeding 10 DNS Lookups</h3>
|
||||
<p className="text-neutral-700">
|
||||
Each <code>include:</code> mechanism counts toward the 10 lookup limit. Too many includes will cause SPF
|
||||
to fail. Consolidate where possible.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ Forgetting to Update SPF</h3>
|
||||
<p className="text-neutral-700">
|
||||
When you add new email services, remember to update your SPF record. Outdated SPF records cause legitimate
|
||||
emails to fail authentication.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-l-4 border-red-500 pl-6 py-2">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">✗ Using +all</h3>
|
||||
<p className="text-neutral-700">
|
||||
Never use <code>+all</code> (pass all). This completely defeats the purpose of SPF by allowing anyone to
|
||||
send from your domain. Always use <code>~all</code> or <code>-all</code>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Related Guides */}
|
||||
<section id="related-guides" className="mb-12">
|
||||
<h2 className="text-3xl font-bold text-neutral-900 mb-6">Related Email Authentication Guides</h2>
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Link
|
||||
href="/guides/what-is-dkim"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">What is DKIM?</h3>
|
||||
<p className="text-sm text-neutral-600">Learn how DKIM complements SPF for email authentication.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/what-is-dmarc"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">What is DMARC?</h3>
|
||||
<p className="text-sm text-neutral-600">Implement DMARC using SPF and DKIM together.</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/guides/email-deliverability"
|
||||
className="block rounded-xl border border-neutral-200 bg-white p-6 transition hover:border-neutral-300 hover:shadow-lg"
|
||||
>
|
||||
<h3 className="text-lg font-semibold text-neutral-900 mb-2">Email Deliverability Guide</h3>
|
||||
<p className="text-sm text-neutral-600">Complete guide to improving email deliverability.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</GuideLayout>
|
||||
);
|
||||
}
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
TrendingUp,
|
||||
User,
|
||||
Users,
|
||||
Workflow
|
||||
Workflow,
|
||||
} from 'lucide-react';
|
||||
|
||||
const testimonials = [
|
||||
@@ -197,15 +197,16 @@ export default function Index() {
|
||||
'@type': 'UnitPriceSpecification',
|
||||
'price': '0.001',
|
||||
'priceCurrency': 'USD',
|
||||
'unitText': 'email'
|
||||
}
|
||||
'unitText': 'email',
|
||||
},
|
||||
},
|
||||
'aggregateRating': {
|
||||
'@type': 'AggregateRating',
|
||||
'ratingValue': '4.8',
|
||||
'reviewCount': '50'
|
||||
'reviewCount': '50',
|
||||
},
|
||||
'featureList': 'Workflow Automation, Dynamic Segmentation, Campaign Management, Analytics, Developer API, Custom Domains, Self-Hosting, Open Source'
|
||||
'featureList':
|
||||
'Workflow Automation, Dynamic Segmentation, Campaign Management, Analytics, Developer API, Custom Domains, Self-Hosting, Open Source',
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
@@ -281,10 +282,7 @@ export default function Index() {
|
||||
</p>
|
||||
|
||||
<div className={'mt-16 grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-5'}>
|
||||
<Link
|
||||
href={'/vs/resend'}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<Link href={'/vs/resend'} className={'group bg-white p-10 transition hover:bg-neutral-50'}>
|
||||
<div className={'flex flex-col items-center gap-4'}>
|
||||
<div className={'text-2xl font-bold text-neutral-400 transition group-hover:text-neutral-900'}>
|
||||
Resend
|
||||
@@ -293,10 +291,7 @@ export default function Index() {
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href={'/vs/sendgrid'}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<Link href={'/vs/sendgrid'} className={'group bg-white p-10 transition hover:bg-neutral-50'}>
|
||||
<div className={'flex flex-col items-center gap-4'}>
|
||||
<div className={'text-2xl font-bold text-neutral-400 transition group-hover:text-neutral-900'}>
|
||||
SendGrid
|
||||
@@ -305,10 +300,7 @@ export default function Index() {
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href={'/vs/mailchimp'}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<Link href={'/vs/mailchimp'} className={'group bg-white p-10 transition hover:bg-neutral-50'}>
|
||||
<div className={'flex flex-col items-center gap-4'}>
|
||||
<div className={'text-2xl font-bold text-neutral-400 transition group-hover:text-neutral-900'}>
|
||||
Mailchimp
|
||||
@@ -317,10 +309,7 @@ export default function Index() {
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href={'/vs/customerio'}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<Link href={'/vs/customerio'} className={'group bg-white p-10 transition hover:bg-neutral-50'}>
|
||||
<div className={'flex flex-col items-center gap-4'}>
|
||||
<div className={'text-2xl font-bold text-neutral-400 transition group-hover:text-neutral-900'}>
|
||||
Customer.io
|
||||
@@ -329,10 +318,7 @@ export default function Index() {
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
href={'/vs/mailgun'}
|
||||
className={'group bg-white p-10 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<Link href={'/vs/mailgun'} className={'group bg-white p-10 transition hover:bg-neutral-50'}>
|
||||
<div className={'flex flex-col items-center gap-4'}>
|
||||
<div className={'text-2xl font-bold text-neutral-400 transition group-hover:text-neutral-900'}>
|
||||
Mailgun
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -114,8 +114,7 @@ export default function Index() {
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<span>Click & open tracking
|
||||
</span>
|
||||
<span>Click & open tracking</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-3 text-white/80">
|
||||
<svg className="mt-0.5 h-5 w-5 flex-shrink-0 text-white" fill="currentColor" viewBox="0 0 20 20">
|
||||
|
||||
@@ -12,7 +12,9 @@ export default function Index() {
|
||||
<>
|
||||
<NextSeo
|
||||
title={'Plunk Terms of Service | The Open-Source Email Platform'}
|
||||
description={'Terms of Service for Plunk, the open-source email automation platform. Read our user agreement and service terms.'}
|
||||
description={
|
||||
'Terms of Service for Plunk, the open-source email automation platform. Read our user agreement and service terms.'
|
||||
}
|
||||
openGraph={{
|
||||
title: 'Plunk Terms of Service | The Open-Source Email Platform',
|
||||
description:
|
||||
|
||||
@@ -0,0 +1,425 @@
|
||||
import {ComparisonTable, FAQSection, Footer, Navbar} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
const comparisonData: ComparisonRow[] = [
|
||||
{feature: 'Pricing Model', plunk: 'Pay-as-you-go per email', competitor: 'Monthly tiers by contacts'},
|
||||
{feature: 'Contact Limits', plunk: 'Unlimited', competitor: 'Tier-based limits'},
|
||||
{feature: 'Open Source', plunk: true, competitor: false},
|
||||
{feature: 'Self-Hostable', plunk: true, competitor: false},
|
||||
{feature: 'Target Audience', plunk: 'Developers & SaaS', competitor: 'All-in-one marketing suite'},
|
||||
{feature: 'Setup Time', plunk: '5 minutes', competitor: '30+ minutes'},
|
||||
{feature: 'Transactional Emails', plunk: true, competitor: true},
|
||||
{feature: 'Marketing Campaigns', plunk: true, competitor: true},
|
||||
{feature: 'Workflow Automation', plunk: 'Included', competitor: 'Higher tiers only'},
|
||||
];
|
||||
|
||||
const faqs: FAQ[] = [
|
||||
{
|
||||
question: 'What is the difference between Plunk and Brevo (Sendinblue)?',
|
||||
answer:
|
||||
'Plunk is built for developers with a simple API and pay-as-you-go pricing, while Brevo is an all-in-one marketing suite with more features but higher complexity. Plunk is open-source and self-hostable, while Brevo is proprietary. Plunk charges per email sent with unlimited contacts, while Brevo uses tiered pricing based on contact count.',
|
||||
},
|
||||
{
|
||||
question: 'Is Plunk cheaper than Brevo?',
|
||||
answer:
|
||||
"It depends on your usage pattern. Plunk's pay-as-you-go model ($0.001 per email) with unlimited contacts is often more cost-effective for businesses with large contact lists but moderate email volume. Brevo charges based on contact count, which can become expensive as your audience grows.",
|
||||
},
|
||||
{
|
||||
question: 'Can I self-host Plunk unlike Brevo?',
|
||||
answer:
|
||||
'Yes. Plunk is open-source (AGPL-3.0) and can be self-hosted using Docker, giving you full control over your data and infrastructure. Brevo is a proprietary cloud-only service with no self-hosting option.',
|
||||
},
|
||||
{
|
||||
question: 'Is Plunk easier to use than Brevo?',
|
||||
answer:
|
||||
'For developers, yes. Plunk focuses on email essentials with a clean API and minimal setup. Brevo offers more features (SMS, chat, CRM) which adds complexity. If you just need email automation, Plunk is simpler. If you need an all-in-one marketing platform, Brevo might be better.',
|
||||
},
|
||||
{
|
||||
question: 'How easy is it to migrate from Brevo to Plunk?',
|
||||
answer:
|
||||
"Migration is straightforward. Export your contacts from Brevo, import them to Plunk via CSV, and update your application to use Plunk's API. Most migrations take less than a day. Plunk's API is well-documented and easy to integrate.",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Plunk vs Brevo (Sendinblue) comparison page
|
||||
*/
|
||||
export default function BrevoComparison() {
|
||||
return (
|
||||
<>
|
||||
<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"
|
||||
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'}],
|
||||
}}
|
||||
/>
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Brevo</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl'}>
|
||||
Developer-first alternative
|
||||
<br />
|
||||
for Brevo
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Simpler pricing, cleaner API, open-source code. All the email power, none of the bloat. Built for
|
||||
developers, not marketing teams.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Pricing That Scales With You</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay for emails sent, not contacts stored</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Simple pay-as-you-go pricing. Unlimited contacts, pay only for emails sent.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>$0.001/email</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Unlimited contacts included</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>All features on all plans</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>No monthly minimums</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Brevo</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Tiered by contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Monthly subscription tiers based on contact count with feature restrictions on lower plans.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Contact-based</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Pricing increases with contacts</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Features gated by tier</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Monthly subscription required</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Why Choose Plunk Over Brevo</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Focus on email, not feature overload</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Simpler Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay $0.001 per email with unlimited contacts. No contact-based tiers, no surprise charges as you grow.
|
||||
Predictable costs.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Developer-First</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Clean API, clear documentation, 5-minute setup. Built for developers who want to ship fast, not navigate
|
||||
complex marketing suites.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</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. Inspect the code, contribute features, fork if needed. Full transparency, no vendor
|
||||
lock-in. Brevo is proprietary.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized. Brevo is
|
||||
cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</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 at no extra cost. Brevo charges more as your contact list grows. With Plunk,
|
||||
you only pay for emails sent.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Email-Focused</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Plunk does email and does it well. No SMS, chat, CRM bloat. If you need just email automation, Plunk is
|
||||
simpler and more focused.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Feature-by-Feature Comparison</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="Brevo" rows={comparisonData} />
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-brevo" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'border-t border-neutral-200 py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Make the switch to simplicity</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join developers choosing focused tools over bloated marketing suites. Start free, no credit card required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
Start free trial
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing details
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import {Footer, Navbar, ComparisonTable, FAQSection} from '../../components';
|
||||
import {ComparisonTable, FAQSection, Footer, Navbar} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Code2, DollarSign, PackageOpen, Zap, Globe, BarChart3} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, Code2, DollarSign, Globe, PackageOpen, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -25,17 +25,17 @@ const faqs: FAQ[] = [
|
||||
{
|
||||
question: 'When should I choose Customer.io over Plunk?',
|
||||
answer:
|
||||
'Choose Customer.io if you need advanced behavioral segmentation, visual journey builders, and have a dedicated marketing operations team. Customer.io excels at complex, enterprise-level marketing automation with sophisticated visual tools. Choose Plunk if you want developer-friendly APIs, simpler workflows, and don\'t need the overhead of an enterprise marketing platform.',
|
||||
"Choose Customer.io if you need advanced behavioral segmentation, visual journey builders, and have a dedicated marketing operations team. Customer.io excels at complex, enterprise-level marketing automation with sophisticated visual tools. Choose Plunk if you want developer-friendly APIs, simpler workflows, and don't need the overhead of an enterprise marketing platform.",
|
||||
},
|
||||
{
|
||||
question: 'What is the pricing difference between Plunk and Customer.io?',
|
||||
answer:
|
||||
'Plunk uses a simple pay-as-you-go pricing model where you only pay for emails sent. Customer.io has complex usage-based tiers that combine messages sent, active profiles, and feature access. For small to medium teams, Plunk is typically more cost-effective. Customer.io\'s pricing scales with contact count and feature usage, which can become expensive as you grow.',
|
||||
"Plunk uses a simple pay-as-you-go pricing model where you only pay for emails sent. Customer.io has complex usage-based tiers that combine messages sent, active profiles, and feature access. For small to medium teams, Plunk is typically more cost-effective. Customer.io's pricing scales with contact count and feature usage, which can become expensive as you grow.",
|
||||
},
|
||||
{
|
||||
question: 'Is migration from Customer.io to Plunk complex?',
|
||||
answer:
|
||||
'Migration complexity depends on your current setup. If you use basic transactional emails and simple workflows, migration is straightforward - update your API integration and recreate your workflows. If you rely heavily on Customer.io\'s visual journey builder and advanced behavioral segmentation, you\'ll need to simplify some workflows. Most teams can migrate in a few days of development work.',
|
||||
"Migration complexity depends on your current setup. If you use basic transactional emails and simple workflows, migration is straightforward - update your API integration and recreate your workflows. If you rely heavily on Customer.io's visual journey builder and advanced behavioral segmentation, you'll need to simplify some workflows. Most teams can migrate in a few days of development work.",
|
||||
},
|
||||
{
|
||||
question: 'What does Plunk simplify compared to Customer.io?',
|
||||
@@ -80,7 +80,11 @@ export default function CustomerioComparison() {
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'}>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Customer.io</span>
|
||||
</div>
|
||||
@@ -258,8 +262,8 @@ export default function CustomerioComparison() {
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Developer-First Experience</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Clean, simple APIs designed for developers. No complex visual builders or marketing jargon. Integrate
|
||||
in minutes, not weeks.
|
||||
Clean, simple APIs designed for developers. No complex visual builders or marketing jargon. Integrate in
|
||||
minutes, not weeks.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
@@ -279,8 +283,8 @@ export default function CustomerioComparison() {
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Transparent Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing with no hidden costs or complex tiers. No need to pay for contact lists or
|
||||
profile counts - just emails sent.
|
||||
Pay-as-you-go pricing with no hidden costs or complex tiers. No need to pay for contact lists or profile
|
||||
counts - just emails sent.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
|
||||
@@ -0,0 +1,428 @@
|
||||
import {ComparisonTable, FAQSection, Footer, Navbar} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
const comparisonData: ComparisonRow[] = [
|
||||
{feature: 'Pricing Model', plunk: 'Pay-as-you-go', competitor: 'Monthly subscription tiers'},
|
||||
{feature: 'Open Source', plunk: true, competitor: false},
|
||||
{feature: 'Self-Hostable', plunk: true, competitor: false},
|
||||
{feature: 'Contact Limits', plunk: 'Unlimited', competitor: 'Tier-based limits'},
|
||||
{feature: 'Transactional Emails', plunk: true, competitor: true},
|
||||
{feature: 'Marketing Campaigns', plunk: true, competitor: true},
|
||||
{feature: 'Workflow Automation', plunk: true, competitor: true},
|
||||
{feature: 'Dynamic Segmentation', plunk: true, competitor: true},
|
||||
{feature: 'API Access', plunk: true, competitor: true},
|
||||
];
|
||||
|
||||
const faqs: FAQ[] = [
|
||||
{
|
||||
question: 'What is the main difference between Plunk and Loops?',
|
||||
answer:
|
||||
'Plunk is open-source (AGPL-3.0) and self-hostable, while Loops is a proprietary SaaS platform. Plunk uses pay-as-you-go pricing with no contact limits, whereas Loops uses subscription tiers with contact-based limits. Both offer similar features, but Plunk gives you full transparency and control.',
|
||||
},
|
||||
{
|
||||
question: 'Is Plunk cheaper than Loops?',
|
||||
answer:
|
||||
"It depends on your usage. Plunk's pay-as-you-go model ($0.001 per email) means you only pay for what you send. Loops charges monthly subscriptions based on contact count. For businesses with variable email volume or growing contact lists, Plunk is often more cost-effective.",
|
||||
},
|
||||
{
|
||||
question: 'Can I self-host Plunk unlike Loops?',
|
||||
answer:
|
||||
'Yes. Plunk is open-source and can be self-hosted using Docker. This gives you full control over your data, infrastructure, and costs. Loops is cloud-only with no self-hosting option.',
|
||||
},
|
||||
{
|
||||
question: 'Does Plunk have the same modern features as Loops?',
|
||||
answer:
|
||||
'Yes. Plunk offers transactional emails, marketing campaigns, workflow automation, dynamic segmentation, and a modern API—just like Loops. The key difference is Plunk is open-source, self-hostable, and has no contact limits.',
|
||||
},
|
||||
{
|
||||
question: 'How easy is it to migrate from Loops to Plunk?',
|
||||
answer:
|
||||
"Migration is straightforward. Export your contacts from Loops, import them to Plunk via CSV, and update your application to use Plunk's API. Most migrations can be completed in a few hours.",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Plunk vs Loops comparison page
|
||||
*/
|
||||
export default function LoopsComparison() {
|
||||
return (
|
||||
<>
|
||||
<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"
|
||||
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'}],
|
||||
}}
|
||||
/>
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Loops</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl'}>
|
||||
Open-source alternative
|
||||
<br />
|
||||
for Loops
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Same modern features, but open-source and self-hostable. No contact limits, no proprietary lock-in, no
|
||||
hidden costs. Built for transparency.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>
|
||||
Transparent Pricing vs Vendor Lock-In
|
||||
</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Pay per email, not per contact</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Pay per email sent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go pricing with unlimited contacts. No monthly commitments or contact-based limits.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>$0.001/email</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Unlimited contacts at no extra cost</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>All features included on all plans</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Open-source and self-hostable</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Loops</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Subscription tiers by contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Monthly subscription based on contact count with tier-based limits and feature restrictions.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Tiered pricing</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Contact-based pricing limits</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Feature limits on lower tiers</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Proprietary, cloud-only platform</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Why Choose Plunk Over Loops</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Open-source transparency meets modern SaaS features</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source & Transparent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, understand exactly how your emails are sent.
|
||||
No black boxes.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized for scale.
|
||||
Loops is cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Unlimited Contacts</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
No contact-based limits. Grow your audience without worrying about tier upgrades or surprise charges.
|
||||
Pay for emails, not contacts.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Predictable Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go per email. No surprise costs as you grow. No forced tier upgrades. No sales calls. Just
|
||||
simple, transparent pricing.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Full API Access</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Complete API access on all plans. No feature restrictions, no "contact sales" for API access. Everything
|
||||
documented and ready to use.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>All Features Included</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Transactional emails, campaigns, workflows, segmentation—all included. No artificial feature gating
|
||||
based on your plan.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Feature-by-Feature Comparison</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="Loops" rows={comparisonData} />
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-loops" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'border-t border-neutral-200 py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Switch to open source</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join developers choosing transparency and control over proprietary platforms. Start free, no credit card
|
||||
required.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
Start free trial
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing details
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import {Footer, Navbar, ComparisonTable, FAQSection, CodeBlock} from '../../components';
|
||||
import {ComparisonTable, FAQSection, Footer, Navbar} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, Code2, DollarSign, Zap, PackageOpen, Mail, Send} from 'lucide-react';
|
||||
import {ArrowRight, Code2, DollarSign, Mail, PackageOpen, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -25,20 +25,20 @@ const faqs: FAQ[] = [
|
||||
{
|
||||
question: 'When should I choose Mailchimp over Plunk?',
|
||||
answer:
|
||||
'Choose Mailchimp if you\'re a marketer who needs a drag-and-drop email builder and prefers a marketing-first interface. Mailchimp excels at visual design and non-technical users. Choose Plunk if you\'re a developer who values API-first design, wants transactional + marketing in one platform, and prefers code over drag-and-drop.',
|
||||
"Choose Mailchimp if you're a marketer who needs a drag-and-drop email builder and prefers a marketing-first interface. Mailchimp excels at visual design and non-technical users. Choose Plunk if you're a developer who values API-first design, wants transactional + marketing in one platform, and prefers code over drag-and-drop.",
|
||||
},
|
||||
{
|
||||
question: 'What is the difference between Plunk and Mailchimp pricing?',
|
||||
answer:
|
||||
"Mailchimp charges per contact stored, regardless of how many emails you send. Plunk uses a pay-as-you-go model where you only pay for emails sent. This means with Mailchimp, your cost increases as your contact list grows, while with Plunk, you only pay when you actually send emails.",
|
||||
'Mailchimp charges per contact stored, regardless of how many emails you send. Plunk uses a pay-as-you-go model where you only pay for emails sent. This means with Mailchimp, your cost increases as your contact list grows, while with Plunk, you only pay when you actually send emails.',
|
||||
},
|
||||
{
|
||||
question: 'Can Plunk handle both transactional and marketing emails?',
|
||||
answer:
|
||||
'Yes, that\'s one of Plunk\'s key advantages. Transactional emails (receipts, password resets) and marketing emails (newsletters, campaigns) are built into one platform. With Mailchimp, you need their separate Mandrill service for transactional emails, which adds complexity.',
|
||||
"Yes, that's one of Plunk's key advantages. Transactional emails (receipts, password resets) and marketing emails (newsletters, campaigns) are built into one platform. With Mailchimp, you need their separate Mandrill service for transactional emails, which adds complexity.",
|
||||
},
|
||||
{
|
||||
question: 'Is Plunk\'s API easier to use than Mailchimp\'s?',
|
||||
question: "Is Plunk's API easier to use than Mailchimp's?",
|
||||
answer:
|
||||
'Yes, significantly. Plunk has a modern RESTful API designed for developers. Mailchimp\'s API is complex and marketing-focused, requiring you to understand concepts like "audiences," "campaigns," and "merge fields." Most developers find Plunk\'s API 10x easier to integrate.',
|
||||
},
|
||||
@@ -85,7 +85,11 @@ export default function MailchimpComparison() {
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'}>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Mailchimp</span>
|
||||
</div>
|
||||
@@ -247,7 +251,8 @@ export default function MailchimpComparison() {
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Pay-as-you-go Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Only pay for emails you send, not for contacts you store. No monthly minimums or fixed subscription costs.
|
||||
Only pay for emails you send, not for contacts you store. No monthly minimums or fixed subscription
|
||||
costs.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
@@ -380,9 +385,12 @@ export default function MailchimpComparison() {
|
||||
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'}>Ready for a better developer experience?</h2>
|
||||
<h2 className={'text-5xl font-bold tracking-tight text-neutral-900'}>
|
||||
Ready for a better developer experience?
|
||||
</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Join developers who've switched from Mailchimp to Plunk for better DX and transparent pay-as-you-go pricing.
|
||||
Join developers who've switched from Mailchimp to Plunk for better DX and transparent pay-as-you-go
|
||||
pricing.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {Footer, Navbar, ComparisonTable, FAQSection} from '../../components';
|
||||
import {ComparisonTable, FAQSection, Footer, Navbar} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, Workflow, Users, PackageOpen, Globe, Layers} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, Globe, Layers, PackageOpen, Users, Workflow} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -30,12 +30,12 @@ const faqs: FAQ[] = [
|
||||
{
|
||||
question: 'What is the pricing difference between Plunk and Mailgun?',
|
||||
answer:
|
||||
'Plunk uses a simple pay-as-you-go pricing model where you pay only for emails sent. Mailgun uses tiered monthly plans based on email volume, which can be cost-effective at very high volumes but less flexible for variable sending patterns. With Plunk, you get marketing campaigns and workflow automation included at no additional cost - with Mailgun, you\'d need separate tools for marketing.',
|
||||
"Plunk uses a simple pay-as-you-go pricing model where you pay only for emails sent. Mailgun uses tiered monthly plans based on email volume, which can be cost-effective at very high volumes but less flexible for variable sending patterns. With Plunk, you get marketing campaigns and workflow automation included at no additional cost - with Mailgun, you'd need separate tools for marketing.",
|
||||
},
|
||||
{
|
||||
question: 'Is migration from Mailgun to Plunk complex?',
|
||||
answer:
|
||||
'Migration requires updating your API integration since Plunk and Mailgun use different API structures. You\'ll need to update your code to use Plunk\'s endpoints and parameter format. Both platforms support similar core features (templates, webhooks, custom domains), so the concepts translate directly. Plan for a few hours of development work to migrate your integration. Your email templates can be adapted with minimal changes.',
|
||||
"Migration requires updating your API integration since Plunk and Mailgun use different API structures. You'll need to update your code to use Plunk's endpoints and parameter format. Both platforms support similar core features (templates, webhooks, custom domains), so the concepts translate directly. Plan for a few hours of development work to migrate your integration. Your email templates can be adapted with minimal changes.",
|
||||
},
|
||||
{
|
||||
question: 'What does Plunk add beyond transactional emails?',
|
||||
@@ -80,7 +80,11 @@ export default function MailgunComparison() {
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'}>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Mailgun</span>
|
||||
</div>
|
||||
@@ -92,8 +96,8 @@ export default function MailgunComparison() {
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Mailgun is excellent for transactional emails. Plunk adds marketing campaigns, workflow automation, and
|
||||
is open-source.
|
||||
Mailgun is excellent for transactional emails. Plunk adds marketing campaigns, workflow automation, and is
|
||||
open-source.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
import {ComparisonTable, FAQSection, Footer, Navbar} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, BarChart3, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
const comparisonData: ComparisonRow[] = [
|
||||
{feature: 'Transactional Emails', plunk: true, competitor: true},
|
||||
{feature: 'Marketing Campaigns', plunk: true, competitor: false},
|
||||
{feature: 'Workflow Automation', plunk: true, competitor: false},
|
||||
{feature: 'Dynamic Segmentation', plunk: true, competitor: false},
|
||||
{feature: 'Open Source', plunk: true, competitor: false},
|
||||
{feature: 'Self-Hostable', plunk: true, competitor: false},
|
||||
];
|
||||
|
||||
const faqs: FAQ[] = [
|
||||
{
|
||||
question: 'What is the main difference between Plunk and Postmark?',
|
||||
answer:
|
||||
'Postmark focuses exclusively on transactional emails, while Plunk offers transactional emails plus marketing campaigns, workflow automation, and dynamic segmentation. Plunk is also open-source and self-hostable, giving you more flexibility and control.',
|
||||
},
|
||||
{
|
||||
question: 'Is Plunk as reliable as Postmark for transactional emails?',
|
||||
answer:
|
||||
'Yes. Plunk is built on AWS SES, which has excellent deliverability and reliability comparable to Postmark. Both support custom domains, DKIM authentication, and provide detailed delivery analytics. The key difference is Plunk adds marketing and automation features on top.',
|
||||
},
|
||||
{
|
||||
question: 'Can I use Plunk for just transactional emails like Postmark?',
|
||||
answer:
|
||||
'Absolutely. You can use Plunk purely for transactional emails just like Postmark. The marketing campaigns and workflows are optional features that are available when you need them, at no extra cost.',
|
||||
},
|
||||
{
|
||||
question: 'Why should I choose Plunk over Postmark?',
|
||||
answer:
|
||||
'Choose Plunk if you want transactional emails plus marketing capabilities in one platform. You get campaigns, automation, and segmentation without paying for a second service. Plunk is also open-source, so you can self-host or inspect the code.',
|
||||
},
|
||||
{
|
||||
question: 'How easy is it to migrate from Postmark to Plunk?',
|
||||
answer:
|
||||
"Migration is straightforward. Plunk's API is simple and well-documented. Update your application to use Plunk's API endpoints, configure your custom domain, and you're ready to go. Most migrations take a few hours.",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Plunk vs Postmark comparison page
|
||||
*/
|
||||
export default function PostmarkComparison() {
|
||||
return (
|
||||
<>
|
||||
<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"
|
||||
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'}],
|
||||
}}
|
||||
/>
|
||||
|
||||
<Navbar />
|
||||
|
||||
<main className={'mx-auto max-w-7xl px-8 sm:px-0'}>
|
||||
{/* Hero Section */}
|
||||
<section className={'relative py-32 sm:py-48'}>
|
||||
<div
|
||||
className={
|
||||
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_110%)]'
|
||||
}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
animate={{opacity: 1, y: 0}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Postmark</span>
|
||||
</div>
|
||||
|
||||
<h1 className={'text-6xl font-bold tracking-tight text-neutral-900 sm:text-7xl lg:text-8xl'}>
|
||||
Postmark alternative
|
||||
<br />
|
||||
with marketing built-in
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Everything Postmark offers for transactional emails, plus marketing campaigns, workflow automation, and
|
||||
segmentation. One platform, no extra cost.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'group rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white shadow-lg shadow-neutral-900/10 transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
<span className={'flex items-center gap-2'}>
|
||||
Get started free
|
||||
<ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
|
||||
</span>
|
||||
</motion.a>
|
||||
<Link
|
||||
href={WIKI_URI}
|
||||
target={'_blank'}
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 bg-white px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View documentation
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* Pricing Model Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>One Platform for All Your Emails</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Transactional reliability meets marketing power</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-8 lg:grid-cols-2'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: -20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border-2 border-neutral-900 bg-white p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-white'}>Plunk</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Transactional + Marketing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Reliable transactional emails plus marketing campaigns, workflows, and segmentation in one platform.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>All-in-one</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Transactional emails included</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Marketing campaigns included</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-900 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-white'} />
|
||||
</div>
|
||||
<span>Workflow automation included</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, x: 20}}
|
||||
whileInView={{opacity: 1, x: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'rounded-2xl border border-neutral-200 bg-neutral-50 p-10'}
|
||||
>
|
||||
<div className={'mb-4 inline-flex items-center gap-2 rounded-full bg-neutral-200 px-4 py-1.5'}>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Postmark</span>
|
||||
</div>
|
||||
<h3 className={'mt-6 text-2xl font-bold text-neutral-900'}>Transactional only</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Excellent for transactional emails, but no marketing features. Need a second service for campaigns.
|
||||
</p>
|
||||
<div className={'mt-6 text-4xl font-bold text-neutral-900'}>Limited scope</div>
|
||||
<div className={'mt-8 space-y-3'}>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>Transactional emails only</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>No marketing campaigns</span>
|
||||
</div>
|
||||
<div className={'flex items-center gap-3 text-sm text-neutral-600'}>
|
||||
<div className={'h-5 w-5 rounded-full bg-neutral-300 flex items-center justify-center'}>
|
||||
<div className={'h-1.5 w-1.5 rounded-full bg-neutral-600'} />
|
||||
</div>
|
||||
<span>No workflow automation</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Key Advantages */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Why Choose Plunk Over Postmark</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>Do more with one platform instead of two</p>
|
||||
</motion.div>
|
||||
|
||||
<div className={'grid gap-px bg-neutral-200 sm:grid-cols-2 lg:grid-cols-3'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.1, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Marketing Campaigns Included</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Send newsletters, announcements, and promotional emails without needing a separate marketing platform.
|
||||
One platform, one bill.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.2, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Zap className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Workflow Automation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Build automated email sequences with triggers, delays, and conditions. Onboard users, nurture leads,
|
||||
re-engage customers—all automated.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.3, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Users className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Dynamic Segmentation</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Segment your audience based on behavior, properties, and engagement. Send targeted emails to the right
|
||||
people at the right time.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.4, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<PackageOpen className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Open Source & Transparent</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
AGPL-3.0 licensed. Inspect the code, contribute features, understand exactly how it works. No
|
||||
proprietary black boxes.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.5, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<Globe className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Self-Hostable</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Run on your infrastructure with Docker. Full data control, compliance-ready, cost-optimized. Postmark is
|
||||
cloud-only.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
transition={{duration: 0.5, delay: 0.6, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'group bg-white p-12 transition hover:bg-neutral-50'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'flex h-12 w-12 items-center justify-center rounded-xl bg-neutral-900 text-white transition group-hover:scale-110'
|
||||
}
|
||||
>
|
||||
<DollarSign className="h-5 w-5" />
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Pay-As-You-Go Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Simple per-email pricing with all features included. No separate charges for transactional vs marketing
|
||||
emails. No tiers, no commitments.
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature Comparison */}
|
||||
<section className={'py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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'}>Feature-by-Feature Comparison</h2>
|
||||
<p className={'mt-4 text-lg text-neutral-600'}>See exactly what you get with each platform</p>
|
||||
</motion.div>
|
||||
|
||||
<ComparisonTable competitorName="Postmark" rows={comparisonData} />
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<FAQSection faqs={faqs} schemaId="faq-schema-postmark" />
|
||||
|
||||
{/* CTA */}
|
||||
<section className={'border-t border-neutral-200 py-32'}>
|
||||
<motion.div
|
||||
initial={{opacity: 0, y: 20}}
|
||||
whileInView={{opacity: 1, y: 0}}
|
||||
viewport={{once: true}}
|
||||
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 more from your email platform</h2>
|
||||
<p className={'mt-6 text-lg text-neutral-600'}>
|
||||
Stop juggling multiple tools. Get transactional reliability plus marketing power in one platform. Start
|
||||
free.
|
||||
</p>
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
<motion.a
|
||||
whileHover={{scale: 1.02}}
|
||||
whileTap={{scale: 0.98}}
|
||||
href={`${DASHBOARD_URI}/auth/signup`}
|
||||
className={
|
||||
'rounded-lg bg-neutral-900 px-8 py-4 text-base font-semibold text-white transition hover:bg-neutral-800'
|
||||
}
|
||||
>
|
||||
Start free trial
|
||||
</motion.a>
|
||||
<Link
|
||||
href="/pricing"
|
||||
className={
|
||||
'rounded-lg border border-neutral-300 px-8 py-4 text-base font-semibold text-neutral-900 transition hover:border-neutral-400'
|
||||
}
|
||||
>
|
||||
View pricing details
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import {Footer, Navbar, ComparisonTable, FAQSection} from '../../components';
|
||||
import {ComparisonTable, FAQSection, Footer, Navbar} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, PackageOpen, Workflow, Users, BarChart3, Globe, Layers} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, Globe, Layers, PackageOpen, Users, Workflow} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -28,17 +28,17 @@ const faqs: FAQ[] = [
|
||||
'Choose Resend if you only need transactional emails and prefer a service focused exclusively on that use case. Resend has a larger free tier and excellent developer experience for transactional emails. Choose Plunk if you need marketing campaigns, automation workflows, or want the flexibility to self-host (though Plunk also offers fully-managed hosting).',
|
||||
},
|
||||
{
|
||||
question: "What is the pricing difference between Plunk and Resend?",
|
||||
question: 'What is the pricing difference between Plunk and Resend?',
|
||||
answer:
|
||||
"Plunk uses a pay-as-you-go pricing model, while Resend uses a fixed subscription model. Both optimize for different use cases - Resend focuses exclusively on transactional emails. Plunk includes marketing campaigns and workflow automation at no additional cost. If you need both transactional and marketing emails, Plunk may be more cost-effective overall since you won't need a separate marketing platform.",
|
||||
},
|
||||
{
|
||||
question: 'Is migration from Resend to Plunk complex?',
|
||||
answer:
|
||||
'Migration requires updating your API integration since Plunk and Resend use different API structures. You\'ll need to update your code to use Plunk\'s endpoints and parameter format. However, both platforms support similar features (templates, webhooks, custom domains), so the concepts translate directly. Plan for a few hours of development work to migrate your integration.',
|
||||
"Migration requires updating your API integration since Plunk and Resend use different API structures. You'll need to update your code to use Plunk's endpoints and parameter format. However, both platforms support similar features (templates, webhooks, custom domains), so the concepts translate directly. Plan for a few hours of development work to migrate your integration.",
|
||||
},
|
||||
{
|
||||
question: 'What does Plunk offer that Resend doesn\'t?',
|
||||
question: "What does Plunk offer that Resend doesn't?",
|
||||
answer:
|
||||
'Plunk adds marketing campaigns (one-time broadcasts to segments), workflow automation (multi-step email sequences with triggers and conditions), and dynamic audience segmentation. These features mean you can handle both transactional and marketing emails in one platform. Plunk is also open-source (AGPL-3.0) and self-hostable, giving you full control over your email infrastructure.',
|
||||
},
|
||||
@@ -80,7 +80,11 @@ export default function ResendComparison() {
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'}>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs Resend</span>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {Footer, Navbar, ComparisonTable, FAQSection} from '../../components';
|
||||
import {ComparisonTable, FAQSection, Footer, Navbar} from '../../components';
|
||||
import {motion} from 'framer-motion';
|
||||
import {DASHBOARD_URI, WIKI_URI} from '../../lib/constants';
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import {ArrowRight, PackageOpen, DollarSign, Zap, Globe, Users, BarChart3} from 'lucide-react';
|
||||
import {ArrowRight, BarChart3, DollarSign, Globe, PackageOpen, Users, Zap} from 'lucide-react';
|
||||
import type {ComparisonRow} from '../../components/ComparisonTable';
|
||||
import type {FAQ} from '../../components/FAQSection';
|
||||
|
||||
@@ -39,7 +39,7 @@ const faqs: FAQ[] = [
|
||||
{
|
||||
question: 'Can I migrate from SendGrid to Plunk?',
|
||||
answer:
|
||||
'Yes, migration is straightforward. Export your contacts from SendGrid, import them to Plunk via CSV, and update your application to use Plunk\'s easy API. Most migrations take less than a day.',
|
||||
"Yes, migration is straightforward. Export your contacts from SendGrid, import them to Plunk via CSV, and update your application to use Plunk's easy API. Most migrations take less than a day.",
|
||||
},
|
||||
{
|
||||
question: 'What SendGrid features does Plunk not have?',
|
||||
@@ -61,7 +61,7 @@ export default function SendGridComparison() {
|
||||
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.",
|
||||
'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'}],
|
||||
}}
|
||||
@@ -84,7 +84,11 @@ export default function SendGridComparison() {
|
||||
transition={{duration: 0.7, ease: [0.22, 1, 0.36, 1]}}
|
||||
className={'mx-auto max-w-4xl text-center'}
|
||||
>
|
||||
<div className={'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'}>
|
||||
<div
|
||||
className={
|
||||
'mb-6 inline-flex items-center gap-2 rounded-full border border-neutral-200 bg-white px-4 py-2'
|
||||
}
|
||||
>
|
||||
<span className={'text-sm text-neutral-600'}>Comparing</span>
|
||||
<span className={'text-sm font-semibold text-neutral-900'}>Plunk vs SendGrid</span>
|
||||
</div>
|
||||
@@ -96,8 +100,8 @@ export default function SendGridComparison() {
|
||||
</h1>
|
||||
|
||||
<p className={'mx-auto mt-8 max-w-2xl text-xl text-neutral-600'}>
|
||||
Pay-as-you-go instead of fixed subscriptions. No complex setup, no feature gating, no enterprise sales pitches.
|
||||
Built for developers, not procurement teams.
|
||||
Pay-as-you-go instead of fixed subscriptions. No complex setup, no feature gating, no enterprise sales
|
||||
pitches. Built for developers, not procurement teams.
|
||||
</p>
|
||||
|
||||
<div className={'mt-12 flex flex-wrap justify-center gap-4'}>
|
||||
@@ -247,8 +251,8 @@ export default function SendGridComparison() {
|
||||
</div>
|
||||
<h3 className={'mt-6 text-xl font-semibold text-neutral-900'}>Simple, Transparent Pricing</h3>
|
||||
<p className={'mt-3 leading-relaxed text-neutral-600'}>
|
||||
Pay-as-you-go per email. No hidden fees, no complex tiers, no enterprise sales calls. Start free, scale as
|
||||
you grow.
|
||||
Pay-as-you-go per email. No hidden fees, no complex tiers, no enterprise sales calls. Start free, scale
|
||||
as you grow.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/** @type {import('next-sitemap').IConfig} */
|
||||
module.exports = {
|
||||
siteUrl: process.env.NEXT_PUBLIC_LANDING_URI || 'https://www.swyp.be',
|
||||
siteUrl: process.env.NEXT_PUBLIC_DASHBOARD_URI || 'https://app.useplunk.com',
|
||||
generateRobotsTxt: true,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** @type {import('next-sitemap').IConfig} */
|
||||
|
||||
module.exports = {
|
||||
siteUrl: process.env.NEXT_PUBLIC_WIKI || 'https://wiki.swyp.be',
|
||||
siteUrl: process.env.NEXT_PUBLIC_WIKI_URI || 'https://docs.useplunk.com',
|
||||
generateRobotsTxt: true,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user