How I Would Fix emails landing in spam in a React Native and Expo mobile app Using Launch Ready.
The symptom is simple: users sign up, reset passwords, or get receipts, but the email shows up in spam or promotions instead of inbox. In a React Native...
How I Would Fix emails landing in spam in a React Native and Expo mobile app Using Launch Ready
The symptom is simple: users sign up, reset passwords, or get receipts, but the email shows up in spam or promotions instead of inbox. In a React Native and Expo app, the app is usually not the problem by itself. The real issue is almost always sender identity, DNS, content quality, or provider reputation.
The first thing I would inspect is the sending domain setup: SPF, DKIM, DMARC, and whether the app is sending through a verified provider domain or a random default sender. If that foundation is wrong, every other fix is just noise.
For this failure mode, I would focus on DNS, production mail configuration, and safe verification so we stop losing password resets and onboarding emails to spam folders.
Triage in the First Hour
1. Check which emails are affected.
- Password reset?
- Welcome emails?
- Transactional receipts?
- Marketing emails?
Different message types get filtered differently.
2. Inspect the sender address and domain.
- Is it using `no-reply@gmail.com`, a bare IP, or a mismatched domain?
- Is the "From" domain aligned with the sending service?
3. Open the email headers from a spammed message.
- Look for SPF pass/fail.
- Look for DKIM pass/fail.
- Look for DMARC alignment status.
- Check if the message was marked as bulk or suspicious.
4. Review DNS records in the domain registrar and Cloudflare.
- SPF TXT record
- DKIM CNAME or TXT records
- DMARC TXT record
- MX records if inbound mail matters
5. Check the email provider dashboard.
- Suppression list
- Bounce rate
- Complaint rate
- Domain verification status
- Sending limits or reputation warnings
6. Inspect Expo app environment variables and build config.
- Are production credentials hardcoded?
- Is staging accidentally sending from prod?
- Are secrets exposed in client code?
7. Verify what backend actually sends the email.
- API route
- serverless function
- third-party automation tool
The mobile app should trigger mail indirectly, not send raw SMTP credentials from the device.
8. Confirm whether users are receiving duplicate emails. Duplicate sends can trigger spam filters fast.
9. Test one controlled send to Gmail and Outlook. Compare inbox placement across providers before changing anything else.
10. Review recent changes. A new domain, new provider, changed templates, or a redeployed backend often causes this within 24 to 72 hours.
dig txt yourdomain.com dig txt _dmarc.yourdomain.com dig txt selector1._domainkey.yourdomain.com
Root Causes
| Likely cause | How to confirm | Why it lands in spam | |---|---|---| | SPF missing or wrong | Header shows SPF fail; DNS TXT record does not include your sender | Mail servers cannot verify who is allowed to send | | DKIM not set or broken | Header shows DKIM fail; selector record missing or mismatched | Message integrity cannot be trusted | | DMARC missing or too weak | No `_dmarc` record or policy set to `none` forever | Receiving servers have no enforcement signal | | Sender domain mismatch | Email says `From: app@yourapp.com` but sends through another domain without alignment | Authentication passes poorly or fails alignment checks | | Poor reputation from shared IP/provider abuse | Provider dashboard shows high bounce/complaint rates; test mail goes to spam only on some inboxes | Your messages inherit bad neighborhood reputation | | Bad content patterns | Subject lines are salesy, too many links/images, broken HTML, URL shorteners | Filters flag suspicious formatting |
1. SPF misconfiguration
SPF tells receivers which systems can send on behalf of your domain. If you use Resend, SendGrid, Postmark, Mailgun, Amazon SES, or similar tools without adding their include rule correctly, you will fail authentication.
I confirm this by checking the raw headers of a delivered message and comparing them against DNS records. If SPF fails even once on critical transactional mail, I treat it as a launch blocker.
2. DKIM absent or broken
DKIM signs each message so receivers can verify it was not altered after sending. If your DNS selector is missing or your provider key changed during setup, inbox placement drops quickly.
I check both the provider console and DNS propagation. If DKIM passes in one mailbox but fails in another after recent edits, I assume stale DNS caching or an incorrect selector value.
3. DMARC policy not enforced
DMARC ties SPF and DKIM together and tells inbox providers what to do when authentication fails. A policy of `none` gives you reports but does not protect deliverability enough for production traffic.
I usually see founders stop at "we added DMARC" without ever moving from monitoring to enforcement. That leaves spoofing risk open and weakens trust signals.
4. App sends from the wrong place
In React Native and Expo apps, founders sometimes call SMTP directly from client-side code or embed email keys inside environment files that ship with the build. That is both insecure and fragile.
The better pattern is: mobile app -> authenticated API -> email service -> inbox. If credentials live in the app bundle or Expo public env vars, I treat that as a security incident waiting to happen.
5. Reputation damage from volume spikes
A cold domain that suddenly sends hundreds of welcome emails can look abusive even if everything is configured correctly. Shared sending infrastructure can also inherit poor reputation from other customers.
I confirm this by looking at send volume history versus complaint/bounce rates. If you launched yesterday and sent 2 emails before today then suddenly sent 5,000 verification messages after an ad campaign, that spike alone may explain it.
6. Template quality issues
Spam filters react badly to thin content: all-image emails, broken HTML tables from drag-and-drop builders, misleading subjects like "URGENT", too many tracking links, and URL shorteners.
I confirm this by sending test variants with plain text plus minimal HTML versus heavily branded templates. If one version lands in inbox consistently while another goes to spam, content is part of the problem.
The Fix Plan
First I would stop making changes in multiple places at once. Email deliverability problems get worse when founders tweak DNS, templates, providers, and app code simultaneously without knowing what helped.
My sequence would be:
1. Freeze mail changes for production.
- No new templates
- No provider swaps
- No secret rotations until we know current state
2. Move all sending into one backend path. In Expo apps I prefer an API endpoint over client-side sending every time. The mobile app should request an action like "send reset email", then server code handles delivery securely.
3. Verify sender identity end-to-end.
- Set SPF for only approved providers
- Publish DKIM keys correctly
- Add DMARC with reporting enabled first if needed
- Align `From`, `Return-Path`, and authenticated domains where possible
4. Use a reputable transactional provider. For product emails like verification codes and receipts, I would choose one provider and keep it consistent instead of mixing multiple services unless there is a clear reason.
5. Clean up templates. Keep subject lines plain and honest.
6. Remove risky elements. Avoid URL shorteners. Avoid image-only content.
7. Separate transactional from marketing traffic. Password resets should not share reputation with newsletters or promos.
8. Add suppression handling. Hard bounces should not keep retrying forever.
9. Test across Gmail, Outlook, Yahoo, and Apple Mail before shipping again.
10. Monitor after release. Watch bounce rate, complaint rate, delivery delay, and support tickets for at least 72 hours.
If needed, I would also tighten Cloudflare, SSL, and deployment settings so your API endpoint stays stable while mail traffic moves through production safely under Launch Ready's handover checklist.
Regression Tests Before Redeploy
Before I ship any fix, I want proof that we improved deliverability without breaking onboarding or account recovery.
Acceptance criteria:
- SPF passes for all production sends.
- DKIM passes on every test message from production domains.
- DMARC aligns correctly for core transactional flows.
- Password reset emails arrive in inbox for at least 4 major providers in under 60 seconds on average.
- No secrets are exposed in Expo client bundles or public env vars.
- No duplicate emails are sent on retry failures.
- Bounce handling writes cleanly to logs without leaking user data.
- Support team can trace one message end-to-end from click to delivery status.
QA checks:
1. Send 10 test messages per flow: signup, reset password, invoice/receipt, and notification alerts.
2. Compare inbox placement: inbox, spam, promotions, or delayed delivery.
3. Verify both mobile platforms: iOS builds and Android builds may call different backend paths if config drift exists.
4. Test failure states: provider timeout, invalid address, rate limit reached, and expired token link.
5. Confirm observability: logs, provider event webhooks, and alerting all work before full rollout.
6 .Check accessibility of email content: plain text alternative present, links readable on mobile, and CTA buttons large enough for taps if users open on phones.
Prevention
I would prevent this class of issue with guardrails across security, code review, QA, and operations.
- Treat email auth records as production infrastructure:
SPF, DKIM, DMARC should be reviewed like deploy configs because they directly affect launch success and account recovery reliability.
- Keep secrets out of client apps:
Expo public env vars are not secret storage; anything used to send mail must live server-side with least privilege access only.
- Add monitoring:
alert on bounce rate above 5 percent, complaint rate above 0 point 1 percent , or delivery delays above 60 seconds.
- Review outbound mail changes like code changes:
any template edit, sender change , or provider switch gets checked before release.
- Run periodic deliverability tests:
monthly seed tests across Gmail , Outlook , Yahoo , and Apple Mail catch reputation drift early.
- Keep transactional flows minimal:
clear subject lines , one primary CTA , plain text fallback , and no aggressive promo language.
- Document rollback steps:
if deliverability drops after a release , you need one known-good sender path ready within minutes .
When to Use Launch Ready
Use Launch Ready when you want me to fix this fast without turning it into a long cleanup project . The sprint fits best when you already have a working React Native and Expo product , but email delivery is hurting activation , support load , or payment recovery .
I would cover:
- DNS audit and correction
- Cloudflare setup where relevant
- SSL validation for backend endpoints
- Production deployment review
- Secrets cleanup
- SPF/DKIM/DMARC setup
- Uptime monitoring
- Handover checklist with exact next steps
What you should prepare before booking:
1 . Domain registrar access . 2 . Cloudflare access if already used . 3 . Email provider access . 4 . Backend repo access . 5 . Expo project access . 6 . A list of affected email types . 7 . One example header from a spammed message .
If you bring those items , I can usually isolate whether this is an auth problem , a reputation problem , or an implementation bug within the first few hours .
References
- https://roadmap.sh/api-security-best-practices
- https://roadmap.sh/cyber-security
- https://roadmap.sh/code-review-best-practices
- https://roadmap.sh/qa
- https://developers.google.com/gmail/sender-guidelines
---
Take the next step
If this is a problem in your product right now, here is what to do next:
- [Use the free Cyprian tools](/tools) - estimate cost, score app risk, check launch readiness, or pick the right service sprint.
- [Book a discovery call](/contact) - I will tell you honestly whether you need a sprint or if you can DIY the next step.
*Written by Cyprian Tinashe Aarons - senior full-stack and AI engineer helping founders rescue, launch, automate, and scale AI-built products.*
Cyprian Tinashe Aarons — Senior Full Stack & AI Engineer
Cyprian helps founders rescue, secure, deploy, and automate AI-built apps with production-grade engineering, launch systems, and AI integration.