Claude Code Boilerplate
FeaturesPricingBlogDocs
Get started →

Product

  • Features
  • Pricing
  • Skills

Compare

  • vs ShipFast
  • vs MakerKit
  • vs supastarter

Resources

  • Docs
  • Blog
  • Discord

Legal

  • License
  • Privacy Policy
  • Terms of Service
Claude Code Boilerplate

© 2026 Claude Code Boilerplate. All rights reserved.

← All posts

Weekly Digest Emails in Your Next.js SaaS -- Keep Users Coming Back Without a New Feature

August 14, 2026
nextjssaasresendvercelretention

The retention problem nobody talks about

You ship a new feature. Power users try it immediately. Then two weeks pass and your daily active user count barely moves.

The problem usually is not the feature. It is that most of your users are not thinking about your product unless something pulls them back. They signed up, got value once, and moved on to whatever is in front of them today.

You can spend another month building the next feature. Or you can send an email on Monday morning that says: "here is what happened in your account this week."

That email -- a weekly digest -- is one of the highest-ROI retention tactics available to a SaaS founder. It requires no new UI, no design work, and no third-party retention tool. It just needs a scheduled job, an email template, and a database query.

If you are building on this Next.js SaaS boilerplate, you already have all three.

What a weekly digest does that a push notification cannot

A digest email works for two reasons push notifications do not:

  1. It arrives when the user is already in email mode -- reading messages, not resisting a browser popup
  2. It gives them a specific reason to return ("you got 4 new comments") rather than a generic prompt ("come back!")

The difference between a digest and a newsletter is personalization. A newsletter goes to everyone and says the same thing. A digest pulls each user's real data -- their projects, their activity, the things relevant to them -- and wraps it in a short email that takes 10 seconds to scan.

Users do not unsubscribe from digests that are genuinely personal. They unsubscribe from ones that feel like marketing dressed up as data.

How to build it with this boilerplate

The boilerplate has Vercel Cron for background jobs, Resend for transactional email, and Drizzle ORM for database queries. Here is how the three pieces connect.

Step 1 -- the Cron route

Add a protected route in app/api/cron/weekly-digest/route.ts:

export async function GET(req: Request) {
  const secret = req.headers.get('authorization');
  if (secret !== `Bearer ${process.env.CRON_SECRET}`) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 });
  }
  await digestService.sendWeeklyDigests();
  return Response.json({ ok: true });
}

Register it in vercel.json:

{
  "crons": [{ "path": "/api/cron/weekly-digest", "schedule": "0 9 * * 1" }]
}

This fires every Monday at 9am UTC. Vercel injects CRON_SECRET as a Bearer token automatically -- any outside caller gets a 401.

Step 2 -- the database query

In your digest service, query active users and their week's activity. The exact fields depend on what your app tracks, but the pattern is the same:

const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
 
const users = await db
  .select()
  .from(userTable)
  .where(eq(userTable.digestEnabled, true));
 
for (const user of users) {
  const activity = await db
    .select()
    .from(activityTable)
    .where(
      and(
        eq(activityTable.userId, user.id),
        gte(activityTable.createdAt, oneWeekAgo)
      )
    );
 
  if (activity.length === 0) continue; // skip quiet weeks
}

Skipping users with zero activity is important. A digest that says "nothing happened" trains users to ignore it.

Step 3 -- the email template

Create a react-email template in emails/WeeklyDigestEmail.tsx. Keep it short: a greeting, a summary of the week's highlights, and one link back into the app.

Then send it from the service:

await emailService.sendEmail({
  to: user.email,
  subject: `Your week on AppName -- ${activity.length} updates`,
  react: React.createElement(WeeklyDigestEmail, { user, activity }),
});

That is the full loop -- one Cron route, one DB query, one email per user per week.

What to put in the digest

The data depends on your product. These patterns get the highest open rates:

  • What happened to them: new comments, replies, followers, or team signups
  • What they completed: posts published, tasks closed, projects updated
  • One thing to do next: a single CTA that links to the relevant page, not your homepage

Do not fill the digest with product news or feature announcements. That is what a newsletter is for. This email is about their data, not yours.

A checklist before you ship

  • Cron route is protected by CRON_SECRET -- reject everything else
  • Users can opt out -- add a digestEnabled boolean to userTable
  • Digest skips users with zero activity that week
  • Every link in the email goes to the specific page, not the homepage
  • You triggered the route manually with a direct HTTP call before trusting the schedule

The opt-out field matters. Digest emails are close enough to marketing that GDPR and CAN-SPAM both require an unsubscribe path. A toggle in the user settings page is enough.

Retention is cheaper than acquisition

A weekly digest will not fix a product people do not want. But if your users signed up, got value once, and drifted away -- this is the lowest-effort way to bring them back.

The Vercel Cron, Resend, and Drizzle ORM pieces are already in this Next.js SaaS boilerplate. You are not adding a third-party retention tool or rebuilding an email infrastructure. You are connecting three things that are already there.

Get the boilerplate, wire up the digest, and start pulling your users back on Monday morning.