seo: add spam checker tool with analysis for email content and subject lines

This commit is contained in:
Dries Augustyns
2026-05-02 14:03:58 +02:00
parent 26ec5864ae
commit a729789922
9 changed files with 922 additions and 18 deletions
@@ -1,4 +1,5 @@
import {Footer, Navbar} from '../';
import {FAQSection, Footer, Navbar} from '../';
import type {FAQ} from '../FAQSection';
import {motion} from 'framer-motion';
import React, {ReactNode, useLayoutEffect, useState} from 'react';
import Link from 'next/link';
@@ -13,6 +14,7 @@ interface GuideLayoutProps {
children: ReactNode;
canonical?: string;
ogImage?: string;
faqs?: FAQ[];
}
/**
@@ -26,6 +28,7 @@ export function GuideLayout({
children,
canonical,
ogImage = 'https://www.useplunk.com/assets/card.png',
faqs,
}: GuideLayoutProps) {
const [headings, setHeadings] = useState<{id: string; text: string; level: number}[]>([]);
const [activeId, setActiveId] = useState<string>('');
@@ -241,6 +244,13 @@ export function GuideLayout({
</div>
</main>
{faqs && faqs.length > 0 && (
<FAQSection
faqs={faqs}
schemaId={`faq-${canonical ? canonical.split('/').pop() : 'guide'}`}
/>
)}
<Footer />
</>
);
@@ -2,6 +2,35 @@ import React from 'react';
import {GuideLayout, InfoBox} from '../../components/guides';
import {CodeBlock} from '../../components/CodeBlock';
import Link from 'next/link';
import type {FAQ} from '../../components/FAQSection';
const faqs: FAQ[] = [
{
question: 'What is a good email bounce rate?',
answer:
'A bounce rate below 2% is considered excellent. Between 25% is concerning and needs attention. Above 5% is critical and will seriously damage your sender reputation and deliverability. For hard bounces specifically, keep this below 0.5% per campaign. Most reputable email platforms will suspend accounts or pause sending if hard bounce rates exceed 510%.',
},
{
question: 'What is the difference between a hard bounce and a soft bounce?',
answer:
'A hard bounce is a permanent delivery failure—the email address does not exist, the domain is invalid, or the receiving server has permanently blocked delivery. Remove hard bounce addresses immediately and never send to them again. A soft bounce is a temporary failure—the mailbox is full, the server is temporarily down, or the email is too large. Email platforms typically retry soft bounces automatically for 2472 hours.',
},
{
question: 'How do I reduce email bounce rates?',
answer:
'Key strategies to reduce bounces: (1) Use double opt-in to confirm email addresses at signup, (2) Validate email addresses in real-time on forms to catch typos and invalid formats, (3) Remove hard bounces immediately and automatically, (4) Clean your list every 612 months to remove stale addresses (1520% of email addresses go invalid per year), (5) Never purchase email lists—they have 2040% invalid addresses, and (6) Maintain consistent sending to prevent addresses going stale.',
},
{
question: 'Do bounces affect my email deliverability?',
answer:
'Yes, high bounce rates directly damage your sender reputation. Email providers like Gmail and Outlook track bounce rates as a signal of list quality and sending practices. High bounce rates cause more of your emails—even to valid addresses—to land in spam. Persistent high bounce rates can lead to your sending IP being blacklisted, making it extremely difficult to deliver any emails.',
},
{
question: 'Why are my emails bouncing suddenly?',
answer:
'Sudden increases in bounce rates can be caused by: sending to an old list that has gone stale (addresses expire over time), sending to a purchased list, a domain or server configuration change, your sending IP or domain being blacklisted, or reaching inbox provider sending limits. Identify the pattern—are bounces happening on specific domains or across all recipients?—then investigate the root cause.',
},
];
export default function EmailBounceRate() {
return (
@@ -11,6 +40,7 @@ export default function EmailBounceRate() {
lastUpdated="2025-12-20"
readTime="9 min"
canonical="https://www.useplunk.com/guides/email-bounce-rate"
faqs={faqs}
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -2,15 +2,45 @@ import React from 'react';
import {GuideLayout, InfoBox} from '../../components/guides';
import {CodeBlock} from '../../components/CodeBlock';
import Link from 'next/link';
import type {FAQ} from '../../components/FAQSection';
const faqs: FAQ[] = [
{
question: 'What is a good email open rate?',
answer:
'A good email open rate depends on your industry and email type. For B2B emails, 25-35% is considered excellent. For B2C marketing emails, 20-30% is strong. Overall industry averages range from 20-30%, though Apple Mail Privacy Protection has inflated reported rates by 5-15 percentage points since 2021. Compare against your own historical data rather than industry averages alone.',
},
{
question: 'What are average B2B email open rates?',
answer:
'Average B2B email open rates typically range from 20-30%, with top-performing campaigns achieving 35-45%. B2B emails tend to outperform B2C because recipients opted in for professional reasons and have higher intent. Industry-specific rates vary: SaaS averages 22-28%, financial services 20-25%, and professional services 25-30%. Transactional B2B emails like invoices and notifications often exceed 50%.',
},
{
question: 'How do I improve my email open rate?',
answer:
'The most impactful ways to improve email open rates are: (1) Write compelling, specific subject lines under 50 characters, (2) Personalize beyond first names—use behavioral data and purchase history, (3) Send at optimal times (TuesdayThursday, 10am2pm for B2B), (4) Segment your list to send relevant content to specific groups, (5) Keep your list clean by removing inactive subscribers, (6) Use a recognizable sender name, and (7) Optimize preview text to complement the subject line.',
},
{
question: 'Why are my email open rates low?',
answer:
'Low email open rates typically result from: weak subject lines that fail to create curiosity or urgency, poor list hygiene with too many inactive subscribers dragging down averages, emails landing in spam due to deliverability or authentication issues, bad send timing, email fatigue from sending too frequently, or poor segmentation sending irrelevant content. Review each factor systematically and A/B test changes one at a time.',
},
{
question: 'Does Apple Mail Privacy Protection affect open rates?',
answer:
'Yes. Apple Mail Privacy Protection (MPP), launched in iOS 15 in 2021, pre-loads email images and tracking pixels, registering "opens" even if the user never actually read the email. This inflates open rates by 5-15 percentage points across the industry. To adapt, focus on click-through rates and conversions as more reliable engagement metrics, and segment by email client to understand true engagement patterns.',
},
];
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."
title="Email Open Rates: Industry Benchmarks & How to Improve Yours"
description="Learn what affects email open rates, industry benchmarks by sector, B2B vs B2C averages, and proven tactics to improve your open rates. Complete guide with actionable tips."
lastUpdated="2025-12-20"
readTime="10 min"
readTime="12 min"
canonical="https://www.useplunk.com/guides/email-open-rate"
faqs={faqs}
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -126,6 +156,86 @@ Open Rate = (285 ÷ 950) × 100 = 30%`}
</InfoBox>
</section>
{/* B2B Email Open Rates */}
<section id="b2b-email-open-rates" className="mb-12">
<h2 className="text-3xl font-bold text-neutral-900 mb-6">B2B Email Open Rates</h2>
<p className="text-neutral-700 leading-relaxed mb-6">
B2B (business-to-business) emails consistently outperform B2C benchmarks. Recipients opted in because of
genuine professional need, making them more engaged audiences.
</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">B2B 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">Top Performers</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">2228%</td>
<td className="px-6 py-4 text-sm text-neutral-700">35%+</td>
</tr>
<tr>
<td className="px-6 py-4 text-sm text-neutral-900">Professional Services</td>
<td className="px-6 py-4 text-sm text-neutral-700">2532%</td>
<td className="px-6 py-4 text-sm text-neutral-700">40%+</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">2026%</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">Agency / Marketing</td>
<td className="px-6 py-4 text-sm text-neutral-700">1824%</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">Transactional / Receipts</td>
<td className="px-6 py-4 text-sm text-neutral-700">4565%</td>
<td className="px-6 py-4 text-sm text-neutral-700">70%+</td>
</tr>
</tbody>
</table>
</div>
<div className="grid gap-6 md:grid-cols-2 mb-6">
<div className="rounded-xl border border-neutral-200 bg-white p-6">
<h3 className="text-lg font-semibold text-neutral-900 mb-3">B2B-Specific Tactics</h3>
<ul className="space-y-2 text-sm text-neutral-700">
<li>• Send TuesdayThursday, 10am2pm in recipient's timezone</li>
<li> Use company/product name in subject line for recognition</li>
<li> Personalize with job title, industry, or company size</li>
<li> Reference specific pain points relevant to their role</li>
<li> Keep frequency lower12 times per month for cold lists</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">B2B vs B2C Differences</h3>
<ul className="space-y-2 text-sm text-neutral-700">
<li> B2B decisions are more consideredlonger subject lines acceptable</li>
<li> B2B audiences check email less frequently on weekends</li>
<li> B2B recipients share inboxes with colleagues, affecting metrics</li>
<li> B2B unsubscribe rates are typically lower (0.10.3% vs 0.30.5%)</li>
<li> B2B transactional emails (invoices, updates) have much higher opens</li>
</ul>
</div>
</div>
<InfoBox type="tip" title="Segment Transactional vs Marketing">
<p>
Keep transactional emails (invoices, notifications, password resets) in separate campaigns from marketing
emails. Transactional emails typically achieve 4060% open rates, which will skew your marketing
benchmarks if mixed together.
</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>
+145 -2
View File
@@ -2,15 +2,45 @@ import React from 'react';
import {GuideLayout, InfoBox} from '../../components/guides';
import {CodeBlock} from '../../components/CodeBlock';
import Link from 'next/link';
import type {FAQ} from '../../components/FAQSection';
const faqs: FAQ[] = [
{
question: 'What is DKIM?',
answer:
'DKIM (DomainKeys Identified Mail) is an email authentication method that adds a cryptographic digital signature to your outgoing emails. It allows receiving mail servers to verify that an email was genuinely sent from your domain and that its content was not altered in transit, improving deliverability and protecting against email spoofing.',
},
{
question: 'What is a DKIM key?',
answer:
'A DKIM key is a cryptographic key pair used to sign and verify emails. The private key is stored securely on your mail server and used to sign outgoing emails. The public key is published as a TXT record in your domain\'s DNS under selector._domainkey.yourdomain.com and is used by receiving servers to verify the signature. You should never share or expose your DKIM private key.',
},
{
question: 'How do I set up DKIM?',
answer:
'Setting up DKIM involves three steps: (1) Generate a DKIM key pair for your domain—most email providers do this automatically, (2) Publish the public key as a TXT record in your DNS at selector._domainkey.yourdomain.com, and (3) Configure your mail server or email service provider to sign outgoing emails with the private key. Platforms like Plunk handle all of this automatically when you add your domain.',
},
{
question: 'What is the difference between DKIM and SPF?',
answer:
'SPF (Sender Policy Framework) verifies that the sending mail server is authorized to send email for your domain by checking its IP address against your DNS record. DKIM adds a cryptographic signature to the email that verifies the content has not been altered in transit. They are complementary: SPF validates the server identity, DKIM validates the message integrity. Using both together—along with DMARC—provides the strongest email authentication.',
},
{
question: 'What happens if DKIM fails?',
answer:
'If DKIM verification fails, the receiving mail server may treat the email as suspicious. Depending on your DMARC policy, failed DKIM emails might be delivered normally (p=none), sent to spam (p=quarantine), or completely rejected (p=reject). Persistent DKIM failures damage your sender reputation and reduce email deliverability. Common causes include misconfigured DNS records, expired keys, or email modification during forwarding.',
},
];
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."
description="Learn how DKIM (DomainKeys Identified Mail) works, what a DKIM key is, and how to set it up to protect your emails from spoofing and improve deliverability."
lastUpdated="2025-12-20"
readTime="8 min"
readTime="10 min"
canonical="https://www.useplunk.com/guides/what-is-dkim"
faqs={faqs}
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -300,6 +330,119 @@ export default function WhatIsDKIM() {
</div>
</section>
{/* DKIM vs SPF */}
<section id="dkim-vs-spf" className="mb-12">
<h2 className="text-3xl font-bold text-neutral-900 mb-6">DKIM vs SPF: What's the Difference?</h2>
<p className="text-neutral-700 leading-relaxed mb-6">
DKIM and SPF are both email authentication protocols, but they work differently and check different things:
</p>
<div className="rounded-xl border border-neutral-200 overflow-hidden mb-8">
<table className="w-full">
<thead className="bg-neutral-50">
<tr>
<th className="px-6 py-4 text-left text-sm font-semibold text-neutral-900">Feature</th>
<th className="px-6 py-4 text-left text-sm font-semibold text-neutral-900">DKIM</th>
<th className="px-6 py-4 text-left text-sm font-semibold text-neutral-900">SPF</th>
</tr>
</thead>
<tbody className="divide-y divide-neutral-200 bg-white">
<tr>
<td className="px-6 py-4 text-sm font-medium text-neutral-900">What it validates</td>
<td className="px-6 py-4 text-sm text-neutral-700">Email content integrity</td>
<td className="px-6 py-4 text-sm text-neutral-700">Sending server authorization</td>
</tr>
<tr>
<td className="px-6 py-4 text-sm font-medium text-neutral-900">How it works</td>
<td className="px-6 py-4 text-sm text-neutral-700">Cryptographic signature in headers</td>
<td className="px-6 py-4 text-sm text-neutral-700">IP address check against DNS list</td>
</tr>
<tr>
<td className="px-6 py-4 text-sm font-medium text-neutral-900">Survives forwarding</td>
<td className="px-6 py-4 text-sm text-neutral-700">Yes (if content unchanged)</td>
<td className="px-6 py-4 text-sm text-neutral-700">No (forwarded IP changes)</td>
</tr>
<tr>
<td className="px-6 py-4 text-sm font-medium text-neutral-900">DNS record type</td>
<td className="px-6 py-4 text-sm text-neutral-700">TXT at selector._domainkey.*</td>
<td className="px-6 py-4 text-sm text-neutral-700">TXT at root domain</td>
</tr>
<tr>
<td className="px-6 py-4 text-sm font-medium text-neutral-900">Required for DMARC</td>
<td className="px-6 py-4 text-sm text-neutral-700">Yes (one of SPF/DKIM required)</td>
<td className="px-6 py-4 text-sm text-neutral-700">Yes (one of SPF/DKIM required)</td>
</tr>
</tbody>
</table>
</div>
<InfoBox type="tip" title="Use Both for Maximum Protection">
<p>
DKIM and SPF complement each other. SPF covers scenarios where DKIM can't (like forged server IPs), and DKIM
covers forwarding scenarios where SPF breaks. Implementing bothplus DMARCgives you complete email
authentication coverage.
</p>
</InfoBox>
</section>
{/* How to Test DKIM */}
<section id="test-dkim" className="mb-12">
<h2 className="text-3xl font-bold text-neutral-900 mb-6">How to Test Your DKIM Setup</h2>
<p className="text-neutral-700 leading-relaxed mb-6">
After setting up DKIM, verify it's working correctly using these methods:
</p>
<div className="space-y-6">
<div className="">
<h3 className="text-xl font-semibold text-neutral-900 mb-3">1. Check the Email Headers</h3>
<p className="text-neutral-700 mb-4">
Send a test email and view the raw message headers. Look for the <code>DKIM-Signature</code> header and the{' '}
<code>Authentication-Results</code> header which shows whether DKIM passed or failed:
</p>
<CodeBlock
language="text"
title="Example Authentication-Results Header"
code={`Authentication-Results: mx.google.com;
dkim=pass [email protected] header.s=default header.b=GJwP3Qr8;
spf=pass (google.com: domain of [email protected] designates 1.2.3.4 as permitted sender);
dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=yourdomain.com`}
/>
</div>
<div className="">
<h3 className="text-xl font-semibold text-neutral-900 mb-3">2. Use DNS Lookup Tools</h3>
<p className="text-neutral-700">
Verify your DKIM public key is correctly published in DNS by querying your DKIM TXT record:
</p>
<CodeBlock
language="bash"
title="DNS Lookup Command"
code={`# Check your DKIM record via DNS
dig TXT default._domainkey.yourdomain.com
# Or using nslookup
nslookup -type=TXT default._domainkey.yourdomain.com`}
/>
</div>
<div className="">
<h3 className="text-xl font-semibold text-neutral-900 mb-3">3. Send to Gmail and Check</h3>
<p className="text-neutral-700">
Send a test email to a Gmail address, then click the three-dot menu and select "Show original". The
"Summary" at the top will show DKIM: PASS or DKIM: FAIL, confirming your setup is working.
</p>
</div>
</div>
<InfoBox type="info" title="Common DKIM Issues">
<p>
If DKIM fails, check that: (1) The DNS record uses the correct selector name, (2) The record hasn't been
truncated by your DNS provider (long keys may need to be split), (3) DNS propagation is complete (can take
up to 48 hours), and (4) Your email service is configured to sign with the correct private key.
</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 Authentication Guides</h2>
@@ -2,15 +2,45 @@ import React from 'react';
import {GuideLayout, InfoBox} from '../../components/guides';
import {CodeBlock} from '../../components/CodeBlock';
import Link from 'next/link';
import type {FAQ} from '../../components/FAQSection';
const faqs: FAQ[] = [
{
question: 'What is DMARC?',
answer:
'DMARC (Domain-based Message Authentication, Reporting, and Conformance) is an email authentication protocol that builds on SPF and DKIM to protect your domain from spoofing and phishing. It tells receiving mail servers what to do when an email fails authentication checks—none (monitor), quarantine (spam), or reject (block)—and provides detailed reports about who is sending email using your domain.',
},
{
question: 'What is a DMARC policy?',
answer:
'A DMARC policy (the "p=" tag) determines how receiving mail servers handle emails that fail authentication. p=none means monitor only and take no action; p=quarantine sends failed emails to spam; p=reject completely blocks failed emails. Start with p=none to gather data, then progressively tighten to quarantine and reject as you confirm all your legitimate senders are properly authenticated.',
},
{
question: 'What does p=reject mean in DMARC?',
answer:
'p=reject is the strictest DMARC policy. Emails that fail DMARC authentication are completely rejected and not delivered to the recipient. This provides maximum protection against phishing and spoofing, but requires that all your legitimate email sources (newsletters, CRMs, transactional tools) are properly configured with SPF and DKIM before enabling it.',
},
{
question: 'How do I add a DMARC record?',
answer:
'Add a TXT record in your DNS with the name _dmarc.yourdomain.com. Start with a monitoring-only value: v=DMARC1; p=none; rua=mailto:[email protected]. This records email activity without affecting delivery. After reviewing reports for 2-4 weeks and confirming your SPF and DKIM setup, gradually strengthen to p=quarantine then p=reject.',
},
{
question: 'Is DMARC required for email deliverability?',
answer:
'Since February 2024, Google and Yahoo require DMARC authentication (with at least p=none) for bulk senders sending more than 5,000 emails per day to Gmail or Yahoo addresses. While not strictly required for smaller senders, implementing DMARC is strongly recommended for all domains to improve deliverability, prevent phishing, and meet industry best practices.',
},
];
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."
title="What is DMARC? Policy, Setup & Reporting Explained"
description="Learn how DMARC works with SPF and DKIM to protect your domain. Understand DMARC policies (none, quarantine, reject), how to set up a DMARC record, and read reports."
lastUpdated="2025-12-20"
readTime="9 min"
canonical="https://www.useplunk.com/guides/what-is-dmarc"
faqs={faqs}
>
{/* Introduction */}
<section id="introduction" className="mb-12">
@@ -2,6 +2,35 @@ import React from 'react';
import {GuideLayout, InfoBox} from '../../components/guides';
import {CodeBlock} from '../../components/CodeBlock';
import Link from 'next/link';
import type {FAQ} from '../../components/FAQSection';
const faqs: FAQ[] = [
{
question: 'What is SPF in email?',
answer:
'SPF (Sender Policy Framework) is an email authentication protocol that lets domain owners specify which mail servers are authorized to send email on behalf of their domain. It works by publishing a list of authorized IP addresses in your DNS as a TXT record. When an email arrives, the receiving server checks if the sending server\'s IP address is on your approved list.',
},
{
question: 'What is the difference between SPF and DKIM?',
answer:
'SPF verifies that the sending mail server is authorized to send from your domain by checking the server\'s IP address against your DNS record. DKIM adds a cryptographic signature to the email body and headers, verifying the content was not modified in transit. SPF validates who is sending; DKIM validates what was sent. Both work best together, and DMARC requires at least one of them to be properly configured.',
},
{
question: 'How do I create an SPF record?',
answer:
'Add a TXT record to your domain\'s DNS at the root domain (@ or yourdomain.com) with the format: v=spf1 include:[your-email-service] ~all. Replace the include: with the SPF value from your email provider. If you use multiple email services, combine them in one record: v=spf1 include:_spf.google.com include:spf.useplunk.com ~all. You can only have one SPF record per domain.',
},
{
question: 'What does ~all mean in an SPF record?',
answer:
'~all (tilde-all) at the end of an SPF record is a "soft fail" qualifier, meaning emails from unlisted servers should be accepted but flagged as potentially suspicious. The alternative -all (hard fail) completely rejects emails from unlisted servers. Most experts recommend ~all for initial setup to avoid blocking legitimate emails. Never use +all—it passes all emails and completely defeats SPF\'s purpose.',
},
{
question: 'Why is SPF failing even though I set it up correctly?',
answer:
'Common SPF failure causes: (1) You have multiple SPF records—you can only have one, combine all senders into a single record, (2) You exceeded the 10 DNS lookup limit—each include: counts as one lookup, (3) You added a new email service but forgot to add its SPF include, (4) DNS propagation is still in progress—can take up to 48 hours, (5) Your email is being forwarded, which changes the sending IP and breaks SPF (use DKIM too to handle forwarding).',
},
];
export default function WhatIsSPF() {
return (
@@ -11,6 +40,7 @@ export default function WhatIsSPF() {
lastUpdated="2025-12-20"
readTime="7 min"
canonical="https://www.useplunk.com/guides/what-is-spf"
faqs={faqs}
>
{/* Introduction */}
<section id="introduction" className="mb-12">
+12 -5
View File
@@ -4,7 +4,7 @@ import {DASHBOARD_URI} from '../../lib/constants';
import React from 'react';
import Link from 'next/link';
import {NextSeo} from 'next-seo';
import {ArrowRight, ArrowUpRight, Code2, Search} from 'lucide-react';
import {ArrowRight, ArrowUpRight, Code2, Search, ShieldAlert} from 'lucide-react';
import {Bricolage_Grotesque, Hanken_Grotesk, JetBrains_Mono} from 'next/font/google';
const display = Bricolage_Grotesque({
@@ -43,19 +43,26 @@ const tools = [
icon: Search,
number: '02',
},
{
name: 'Spam Checker',
slug: 'spam-checker',
description: 'Test your email subject line and content for spam trigger words and deliverability issues.',
icon: ShieldAlert,
number: '03',
},
];
export default function ToolsIndex() {
return (
<>
<NextSeo
title="Free Email Tools | Markdown to Email & Email Verification | Plunk"
description="Free tools for email developers: Convert markdown to email-safe HTML and verify email addresses instantly. No sign-up required."
title="Free Email Tools | Spam Checker, Email Validator & More | Plunk"
description="Free email developer tools: spam checker, email address validator, and markdown-to-email converter. No sign-up required."
canonical="https://www.useplunk.com/tools"
openGraph={{
title: 'Free Email Tools | Markdown to Email & Email Verification | Plunk',
title: 'Free Email Tools | Spam Checker, Email Validator & More | Plunk',
description:
'Free tools for email developers: Convert markdown to email-safe HTML and verify email addresses instantly.',
'Free email developer tools: spam checker, email address validator, and markdown-to-email converter. No sign-up required.',
url: 'https://www.useplunk.com/tools',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk Email Tools'}],
}}
@@ -0,0 +1,544 @@
import {FAQSection, Footer, Navbar, SectionHeader} from '../../components';
import {motion} from 'framer-motion';
import {DASHBOARD_URI} from '../../lib/constants';
import React, {useState} from 'react';
import {NextSeo} from 'next-seo';
import {AlertTriangle, ArrowRight, CheckCircle, ShieldAlert, XCircle} from 'lucide-react';
import {Button, Input} from '@plunk/ui';
import {Bricolage_Grotesque, Hanken_Grotesk, JetBrains_Mono} from 'next/font/google';
import Link from 'next/link';
import type {FAQ} from '../../components/FAQSection';
const display = Bricolage_Grotesque({
subsets: ['latin'],
variable: '--font-display',
display: 'swap',
weight: ['400', '500', '600', '700', '800'],
});
const body = Hanken_Grotesk({
subsets: ['latin'],
variable: '--font-body',
display: 'swap',
weight: ['400', '500', '600', '700'],
});
const mono = JetBrains_Mono({
subsets: ['latin'],
variable: '--font-mono',
display: 'swap',
weight: ['400', '500'],
});
const SPAM_TRIGGER_WORDS = [
'act now', 'act immediately', 'action required', 'apply now', 'apply online',
'as seen on', 'avoid bankruptcy', 'be your own boss', 'being a member',
'big bucks', 'bill 1618', 'billion dollars', 'bonus',
'buy direct', 'buy now', 'buyer protection', 'buying judgments',
'call free', 'call now', 'cancel at any time', 'can\'t live without',
'cash bonus', 'cash prize', 'celebrate', 'cent on the dollar',
'chance', 'cheap', 'check now', 'claim now', 'claim your', 'click below',
'click here', 'click now', 'click to remove', 'compare rates',
'compete for your business', 'congratulations', 'consolidate debt',
'copy accurately', 'copy dvds', 'deal', 'dear friend',
'earn per week', 'earn extra cash', 'earn extra income',
'eliminate bad credit', 'eliminate debt', 'excl', 'exclusive deal',
'exclusive offer', 'extra cash', 'extra income',
'f r e e', 'fantastic deal', 'fast cash', 'financial freedom',
'find out anything', 'for free', 'for just $', 'for only $',
'free access', 'free bonus', 'free cell phone', 'free consultation',
'free gift', 'free grant money', 'free info', 'free installation',
'free investment', 'free leads', 'free membership', 'free money',
'free offer', 'free preview', 'free prize', 'free quote', 'free sample',
'free trial', 'freedom', 'full refund', 'get it now', 'get out of debt',
'get paid', 'give it away', 'giving it away', 'great offer',
'guaranteed', 'hidden assets', 'hidden charges',
'home based business', 'hot deal', 'huge discount', 'incredible deal',
'incredible offer', 'information you requested', 'instant access',
'instant approval', 'insurance', 'it\'s effective', 'join millions',
'joining for free', 'junk mail', 'last chance', 'limited time',
'lose weight', 'lowest price', 'lowest rate', 'lucky winner',
'luxury car', 'luxury gift', 'make $', 'make money', 'make money fast',
'marketing solutions', 'mass email', 'meet singles', 'member',
'million dollars', 'miracle', 'money back', 'money making',
'monthly payment', 'mortgage', 'multi level marketing',
'name brand', 'new customer', 'new domain', 'now only',
'obligation free', 'off everything', 'offer expires',
'once in a lifetime', 'one hundred percent free', 'one hundred percent satisfied',
'open an account', 'opportunity', 'opt in', 'order now',
'order status', 'order today', 'outstanding values',
'pennies a day', 'per day', 'per month', 'per week',
'potential earnings', 'price protection', 'prices reduced',
'prize', 'profit', 'promise you', 'pure profit',
'refinance', 'refund', 'register for free', 'remove',
'reverses aging', 'risk free', 'satisfaction guaranteed',
'save big money', 'save up to', 'selected', 'serious cash',
'sign up free', 'special discount', 'special offer', 'special promotion',
'subject to credit', 'subscribe for free', 'super deal', 'supplies are limited',
'take action', 'tens of thousands', 'the best rates',
'time limited', 'trial offer', 'ultimate',
'unbeatable', 'unbelievable', 'urgent', 'valued customer',
'very cheap', 'want to make', 'while supplies last', 'winner',
'work at home', 'work from home', 'you are a winner', 'you have been selected',
'you have been chosen', 'you won', 'you\'ve won', 'your income',
];
interface SpamCheck {
type: 'error' | 'warning' | 'pass';
label: string;
detail: string;
}
interface SpamResult {
score: number;
checks: SpamCheck[];
triggeredWords: string[];
}
function analyzeSpam(subject: string, body: string): SpamResult {
const checks: SpamCheck[] = [];
const triggeredWords: string[] = [];
let deductions = 0;
const fullText = `${subject} ${body}`.toLowerCase();
// Check for spam trigger words
const foundWords = SPAM_TRIGGER_WORDS.filter(word => fullText.includes(word));
if (foundWords.length === 0) {
checks.push({type: 'pass', label: 'No spam trigger words', detail: 'Your content does not contain common spam trigger phrases.'});
} else if (foundWords.length <= 2) {
checks.push({type: 'warning', label: `${foundWords.length} spam trigger word${foundWords.length > 1 ? 's' : ''} found`, detail: `Found: ${foundWords.slice(0, 5).join(', ')}. Consider rephrasing these.`});
deductions += foundWords.length * 8;
triggeredWords.push(...foundWords.slice(0, 5));
} else {
checks.push({type: 'error', label: `${foundWords.length} spam trigger words found`, detail: `Found: ${foundWords.slice(0, 6).join(', ')}${foundWords.length > 6 ? ` and ${foundWords.length - 6} more` : ''}. Rewrite to use natural language.`});
deductions += Math.min(foundWords.length * 8, 45);
triggeredWords.push(...foundWords.slice(0, 6));
}
// Check subject line length
if (subject.length === 0) {
checks.push({type: 'error', label: 'Empty subject line', detail: 'A subject line is required. Missing subjects trigger spam filters.'});
deductions += 20;
} else if (subject.length < 10) {
checks.push({type: 'warning', label: 'Subject line too short', detail: 'Very short subjects may appear suspicious. Aim for 3050 characters.'});
deductions += 5;
} else if (subject.length > 70) {
checks.push({type: 'warning', label: 'Subject line too long', detail: `${subject.length} characters. Subject lines over 70 characters are truncated and may reduce opens.`});
deductions += 5;
} else {
checks.push({type: 'pass', label: 'Good subject line length', detail: `${subject.length} characters — within the recommended 3070 character range.`});
}
// Check for excessive capitalization in subject
const subjectWords = subject.split(' ').filter(w => w.length > 2);
const capsWords = subjectWords.filter(w => w === w.toUpperCase() && /[A-Z]/.test(w));
if (capsWords.length > 2) {
checks.push({type: 'error', label: 'Excessive capitalization in subject', detail: `"${capsWords.join('", "')}" — all-caps words look like shouting and trigger spam filters.`});
deductions += 15;
} else if (capsWords.length > 0) {
checks.push({type: 'warning', label: 'Capitalized words in subject', detail: `"${capsWords.join('", "')}" — use sentence case for a more professional appearance.`});
deductions += 5;
} else {
checks.push({type: 'pass', label: 'No excessive capitalization', detail: 'Subject line uses normal capitalization.'});
}
// Check for excessive exclamation marks in subject
const exclamationCount = (subject.match(/!/g) || []).length;
if (exclamationCount > 1) {
checks.push({type: 'error', label: 'Multiple exclamation marks in subject', detail: `${exclamationCount} exclamation marks found. Multiple "!" are a strong spam signal.`});
deductions += 10;
} else if (exclamationCount === 1) {
checks.push({type: 'warning', label: 'Exclamation mark in subject', detail: 'A single exclamation mark is borderline. Prefer natural punctuation.'});
deductions += 3;
} else {
checks.push({type: 'pass', label: 'No excessive punctuation', detail: 'No exclamation marks in the subject line.'});
}
// Check for $ in subject
if (subject.includes('$')) {
checks.push({type: 'warning', label: 'Dollar sign in subject', detail: 'The $ symbol in subject lines is a common spam trigger. Spell out "dollars" or reframe the message.'});
deductions += 8;
}
// Check for % in subject (common in discount spam)
if (subject.includes('%')) {
checks.push({type: 'warning', label: 'Percentage in subject', detail: 'Percentage symbols in subject lines are frequently associated with promotional spam.'});
deductions += 5;
}
// Check body length
if (body.length > 0 && body.length < 50) {
checks.push({type: 'warning', label: 'Very short email body', detail: 'Very short bodies with mostly links raise spam flags. Add more context and value.'});
deductions += 5;
} else if (body.length >= 50) {
checks.push({type: 'pass', label: 'Email body length acceptable', detail: 'Body content length looks reasonable for a legitimate email.'});
}
const score = Math.max(0, 100 - deductions);
return {score, checks, triggeredWords};
}
function ScoreBadge({score}: {score: number}) {
const color = score >= 80 ? 'text-green-700 bg-green-50 border-green-200' : score >= 60 ? 'text-amber-700 bg-amber-50 border-amber-200' : 'text-red-700 bg-red-50 border-red-200';
const label = score >= 80 ? 'Likely Clean' : score >= 60 ? 'Risky' : 'High Spam Risk';
return (
<div className={`inline-flex flex-col items-center rounded-2xl border-2 px-8 py-6 ${color}`}>
<span className={'text-5xl font-extrabold'}>{score}</span>
<span className={'mt-1 text-sm font-semibold uppercase tracking-widest'}>{label}</span>
</div>
);
}
const faqs: FAQ[] = [
{
question: 'What is a spam checker?',
answer:
'A spam checker analyzes email subject lines and content for characteristics that spam filters use to block or flag emails. It looks for spam trigger words, excessive capitalization, suspicious punctuation, and other signals that inbox providers associate with spam. Running your email through a spam checker before sending helps improve deliverability.',
},
{
question: 'What causes emails to go to spam?',
answer:
'Emails land in spam for many reasons: spam trigger words in the subject or body, poor sender reputation, missing SPF/DKIM/DMARC authentication, sending to purchased or unengaged lists with high bounce rates, excessive links or images, HTML-to-text ratio issues, or being reported as spam by previous recipients. Authentication issues and sender reputation are the most common causes.',
},
{
question: 'How do I check if my email will be spam?',
answer:
'Use a spam checker tool like this one to analyze your subject line and content. Also check your email authentication setup—verify that SPF, DKIM, and DMARC are correctly configured for your domain. Send test emails to spam testing services, and monitor your deliverability metrics (bounce rate, spam complaint rate) over time.',
},
{
question: 'What are spam trigger words?',
answer:
'Spam trigger words are phrases commonly associated with spam emails. They include words like "free", "guaranteed", "act now", "click here", "make money", "winner", "prize", "urgent", and many others. Spam filters assign point values to these words, and emails exceeding a threshold score are flagged or blocked. Avoiding these words and using natural language improves deliverability.',
},
{
question: 'Is email authentication important for avoiding spam?',
answer:
'Yes—email authentication (SPF, DKIM, DMARC) is critical. Without proper authentication, receiving mail servers have no way to verify your email is legitimate, making it more likely to be treated as spam. Since 2024, Gmail and Yahoo require DMARC authentication for bulk senders. Properly authenticated emails with a clean sender reputation reach the inbox far more reliably than unauthenticated emails.',
},
];
export default function SpamCheckerPage() {
const [subject, setSubject] = useState('');
const [bodyText, setBodyText] = useState('');
const [result, setResult] = useState<SpamResult | null>(null);
const handleCheck = (e: React.FormEvent) => {
e.preventDefault();
setResult(analyzeSpam(subject, bodyText));
};
return (
<>
<NextSeo
title="Email Spam Checker | Free Subject Line & Content Spam Test | Plunk"
description="Free spam checker tool. Test your email subject line and content for spam trigger words, capitalization issues, and other factors that cause emails to land in spam."
canonical="https://www.useplunk.com/tools/spam-checker"
openGraph={{
title: 'Email Spam Checker | Free Subject Line & Content Spam Test | Plunk',
description: 'Free spam checker. Test your email subject line and content for factors that cause emails to land in spam folders.',
url: 'https://www.useplunk.com/tools/spam-checker',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk Email Spam Checker'}],
}}
/>
<Navbar />
<div className={`${display.variable} ${body.variable} ${mono.variable}`}>
<main className={'text-neutral-800'}>
{/* ========== HERO ========== */}
<section className={'relative overflow-hidden'}>
<div
aria-hidden
className={
'absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#eeeeee_1px,transparent_1px),linear-gradient(to_bottom,#eeeeee_1px,transparent_1px)] bg-[size:6rem_6rem] [mask-image:radial-gradient(ellipse_70%_60%_at_50%_30%,#000_40%,transparent_95%)]'
}
/>
<div className={'mx-auto max-w-[88rem] px-6 pb-24 pt-20 sm:px-10 sm:pt-28 lg:pb-36'}>
<motion.div
initial={{opacity: 0, y: 8}}
animate={{opacity: 1, y: 0}}
transition={{duration: 0.5, ease: [0.22, 1, 0.36, 1]}}
style={{fontFamily: 'var(--font-mono)'}}
className={
'mb-16 flex items-center justify-between border-t border-neutral-900/90 pt-4 text-[11px] uppercase tracking-[0.18em] text-neutral-700 sm:mb-24'
}
>
<span className={'font-medium text-neutral-900'}>§ T-03 &nbsp; &nbsp;Tool</span>
<Link href="/tools" className={'text-neutral-500 transition hover:text-neutral-900'}>
All tools
</Link>
</motion.div>
<motion.div
initial={{opacity: 0, y: 16}}
animate={{opacity: 1, y: 0}}
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
className={'mx-auto max-w-5xl text-center'}
>
<h1
style={{fontFamily: 'var(--font-display)'}}
className={
'text-[clamp(2.5rem,7vw,6.5rem)] font-extrabold leading-[0.92] tracking-[-0.04em] text-neutral-900'
}
>
Email spam
<br />
checker
</h1>
<p className={'mx-auto mt-8 max-w-2xl text-lg leading-relaxed text-neutral-600 sm:text-xl'}>
Test your subject line and email content for spam trigger words, punctuation issues, and other
factors that cause emails to land in spam folders.
</p>
</motion.div>
</div>
</section>
{/* ========== CHECKER TOOL ========== */}
<section className={'mx-auto max-w-[88rem] px-6 py-16 sm:px-10 sm:py-20'}>
<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-2xl'}
>
<div className={'overflow-hidden rounded-[20px] border border-neutral-200 bg-white'}>
<div className={'border-b border-neutral-200 px-8 py-5'}>
<div className={'flex items-center gap-3'}>
<ShieldAlert className={'h-4 w-4 text-neutral-500'} strokeWidth={1.5} />
<span
style={{fontFamily: 'var(--font-mono)'}}
className={'text-[11px] uppercase tracking-[0.18em] text-neutral-500'}
>
Analyze email content
</span>
</div>
</div>
<form onSubmit={handleCheck} className={'space-y-4 p-8'}>
<div>
<label htmlFor="subject" className={'mb-2 block text-sm font-medium text-neutral-900'}>
Subject line <span className={'text-red-500'}>*</span>
</label>
<Input
id="subject"
type="text"
value={subject}
onChange={e => setSubject(e.target.value)}
placeholder="Your email subject line"
required
className={'w-full'}
/>
</div>
<div>
<label htmlFor="body" className={'mb-2 block text-sm font-medium text-neutral-900'}>
Email body text <span className={'text-neutral-400 text-xs font-normal'}>(optional)</span>
</label>
<textarea
id="body"
value={bodyText}
onChange={e => setBodyText(e.target.value)}
placeholder="Paste your email body text here (plain text, no HTML needed)..."
rows={6}
className={'w-full rounded-lg border border-neutral-200 bg-white px-4 py-3 text-sm text-neutral-900 placeholder:text-neutral-400 focus:border-neutral-900 focus:outline-none focus:ring-1 focus:ring-neutral-900 resize-none'}
/>
</div>
<Button type="submit" className={'w-full gap-2'}>
<ShieldAlert className={'h-4 w-4'} />
Check for spam signals
</Button>
</form>
</div>
{result && (
<motion.div
initial={{opacity: 0, y: 16}}
animate={{opacity: 1, y: 0}}
transition={{duration: 0.5, ease: [0.22, 1, 0.36, 1]}}
className={'mt-6 space-y-4'}
>
{/* Score */}
<div className={'rounded-[20px] border border-neutral-200 bg-white p-8'}>
<div className={'flex flex-col items-center gap-4 text-center'}>
<ScoreBadge score={result.score} />
<p className={'max-w-sm text-sm text-neutral-600'}>
{result.score >= 80
? 'Your email looks clean. No major spam signals detected.'
: result.score >= 60
? 'Some spam signals detected. Review the issues below and consider rewriting flagged sections.'
: 'High spam risk. Address the issues below before sending to protect deliverability.'}
</p>
</div>
</div>
{/* Issues */}
<div className={'rounded-[20px] border border-neutral-200 bg-white p-8'}>
<h3
style={{fontFamily: 'var(--font-display)'}}
className={'mb-6 text-lg font-bold text-neutral-900'}
>
Detailed analysis
</h3>
<ul className={'space-y-3'}>
{result.checks.map((check, i) => (
<li key={i} className={'flex items-start gap-3'}>
{check.type === 'pass' ? (
<CheckCircle className={'mt-0.5 h-5 w-5 shrink-0 text-green-600'} />
) : check.type === 'warning' ? (
<AlertTriangle className={'mt-0.5 h-5 w-5 shrink-0 text-amber-500'} />
) : (
<XCircle className={'mt-0.5 h-5 w-5 shrink-0 text-red-500'} />
)}
<div>
<p className={'text-sm font-medium text-neutral-900'}>{check.label}</p>
<p className={'mt-0.5 text-xs text-neutral-500'}>{check.detail}</p>
</div>
</li>
))}
</ul>
</div>
{result.triggeredWords.length > 0 && (
<div className={'rounded-[20px] border border-red-100 bg-red-50 p-6'}>
<h3 className={'mb-3 text-sm font-semibold text-red-900'}>Flagged phrases</h3>
<div className={'flex flex-wrap gap-2'}>
{result.triggeredWords.map((word, i) => (
<span key={i} className={'rounded-full bg-red-100 px-3 py-1 text-xs font-medium text-red-800'}>
{word}
</span>
))}
</div>
<p className={'mt-3 text-xs text-red-700'}>
Replace these with natural, conversational language to improve deliverability.
</p>
</div>
)}
</motion.div>
)}
</motion.div>
</section>
{/* ========== WHY EMAILS GO TO SPAM ========== */}
<section className={'border-t border-neutral-200 bg-neutral-50/60'}>
<div className={'mx-auto max-w-[88rem] px-6 py-28 sm:px-10 sm:py-36'}>
<SectionHeader
number={'01'}
label={'Spam factors'}
title={'Why emails go to spam.'}
subtitle={'Spam filters look at dozens of signals. Content is just one part of the picture.'}
/>
<div className={'mt-20 grid gap-6 sm:grid-cols-2 lg:grid-cols-3'}>
{[
{
title: 'Spam trigger words',
body: 'Words like "free", "guaranteed", "click here", and "act now" score heavily with spam filters. Even one or two can tip the scales.',
},
{
title: 'Missing authentication',
body: 'Without SPF, DKIM, and DMARC configured, receiving servers cannot verify your email is legitimate. Authentication failures are the leading cause of spam classification.',
},
{
title: 'Poor sender reputation',
body: 'Email providers track bounce rates, spam complaints, and engagement over time. A low sender reputation score means even clean emails land in spam.',
},
{
title: 'Excessive capitalization',
body: 'ALL CAPS SUBJECT LINES and words in all caps look like shouting and are heavily penalized by spam filters. Use sentence case.',
},
{
title: 'High bounce & complaint rates',
body: 'If many recipients report your emails as spam or addresses bounce, providers penalize future emails from your domain.',
},
{
title: 'Purchased email lists',
body: 'Bought lists have unverified addresses, old data, and spam traps. Sending to them destroys your sender reputation quickly.',
},
].map((item, i) => (
<motion.div
key={item.title}
initial={{opacity: 0, y: 16}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.5, delay: i * 0.05, ease: [0.22, 1, 0.36, 1]}}
className={
'flex flex-col gap-4 rounded-[20px] border border-neutral-200 bg-white p-8'
}
>
<h3
style={{fontFamily: 'var(--font-display)'}}
className={'text-xl font-bold tracking-[-0.02em] text-neutral-900'}
>
{item.title}
</h3>
<p className={'text-sm leading-relaxed text-neutral-600'}>{item.body}</p>
</motion.div>
))}
</div>
</div>
</section>
{/* ========== CTA ========== */}
<section className={'relative overflow-hidden border-t border-neutral-900 bg-neutral-900 text-white'}>
<div className={'mx-auto max-w-[88rem] px-6 py-32 sm:px-10 sm:py-40'}>
<div className={'flex flex-col items-start gap-12 lg:flex-row lg:items-end lg:justify-between'}>
<motion.h2
initial={{opacity: 0, y: 16}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.9, ease: [0.22, 1, 0.36, 1]}}
style={{fontFamily: 'var(--font-display)'}}
className={'text-[clamp(2.5rem,7vw,6rem)] font-extrabold leading-[0.95] tracking-[-0.035em]'}
>
Send emails that reach the inbox.
</motion.h2>
<motion.div
initial={{opacity: 0, y: 16}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.9, delay: 0.15, ease: [0.22, 1, 0.36, 1]}}
className={'flex max-w-md flex-col gap-6'}
>
<p className={'text-base text-neutral-300 sm:text-lg'}>
Plunk automatically handles SPF, DKIM, and DMARC authentication the most critical deliverability
factor. Start free, no credit card required.
</p>
<div className={'flex flex-wrap gap-3'}>
<motion.a
whileHover={{scale: 1.015}}
whileTap={{scale: 0.985}}
href={`${DASHBOARD_URI}/auth/signup`}
className={
'inline-flex items-center gap-2 rounded-full bg-white px-7 py-3.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-100'
}
>
Start with Plunk
<ArrowRight className={'h-4 w-4'} />
</motion.a>
<Link
href="/guides/email-deliverability"
className={
'inline-flex items-center gap-2 rounded-full border border-neutral-700 px-7 py-3.5 text-sm font-semibold text-white transition hover:border-white'
}
>
Deliverability guide
</Link>
</div>
</motion.div>
</div>
</div>
</section>
</main>
</div>
<FAQSection faqs={faqs} schemaId="faq-spam-checker" />
<Footer />
</>
);
}
@@ -58,14 +58,14 @@ export default function VerifyEmailPage() {
return (
<>
<NextSeo
title="Free Email Verification Tool | Check Email Validity | Plunk"
description="Verify email addresses instantly. Check for typos, disposable domains, MX records, and more. Free email validation tool with detailed results."
title="Email Validator | Free Email Address Verification Tool | Plunk"
description="Free email validator tool. Check email addresses for validity, typos, disposable domains, and MX record configuration. Verify any email instantly."
canonical="https://www.useplunk.com/tools/verify-email"
openGraph={{
title: 'Free Email Verification Tool | Check Email Validity | Plunk',
description: 'Verify email addresses instantly. Check for typos, disposable domains, MX records, and more.',
title: 'Email Validator | Free Email Address Verification Tool | Plunk',
description: 'Free email validator. Check email addresses for validity, typos, disposable domains, and MX records. Verify any email instantly.',
url: 'https://www.useplunk.com/tools/verify-email',
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk Email Verification Tool'}],
images: [{url: 'https://www.useplunk.com/assets/card.png', alt: 'Plunk Email Validator Tool'}],
}}
/>