GROWTH PATTERN

Adding Retention to Next.js + PlanetScale + NextAuth Apps

Users complete onboarding with Next.js + PlanetScale + NextAuth, but after the initial excitement fades, there's no system to detect when they stop engaging.

Next.js + PlanetScale + NextAuth

Last updated:

What's Missing in Standard Next.js + PlanetScale + NextAuth Architecture

Next.js + PlanetScale + NextAuth manages data correctly, but lacks the infrastructure to track user activity and automatically segment users by engagement levels without custom implementation.

Standard Next.js + PlanetScale + NextAuth Flow vs Optimized Skene Flow

Standard Flow
1

User completes onboarding

2

User activity tracked manually (if at all)

3

No automated re-engagement when activity drops

Skene Flow
1

Monitor PlanetScale 'events' table for user activity patterns via branching

2

Detect when user becomes dormant (hasn't logged in for 14 days)

3

Trigger re-engagement email sequence with personalized content

4

Track re-engagement success and adjust campaigns

Visual comparison of the flows:

Loading diagram...

How Skene Fixes This

The Skene setup for Next.js + PlanetScale + NextAuth tracks user activity and segments users by engagement. It automatically triggers retention campaigns for dormant users and celebrates milestones for active users.

Implementation Comparison

Using Skene Infrastructure

Install via Prompt

cursor.mdc
@task: Initialize Skene.
@action: Analyze my local code, validating subscription via `npx skene login`, and generate `skene.config.ts` to implement the Retention Loop pattern for Next.js + PlanetScale + NextAuth.

Copy Skene Prompt for Cursor

Generated skene.config.ts

skene.config.ts
// skene.config.ts - The Automated Way
import { defineLoop } from '@skene/sdk';

export default defineLoop({
  type: 'retention',
  opinion: 'Detect dormant users and trigger personalized re-engagement campaigns',
  steps: [
    {
      trigger: {
        type: 'schedule',
        cron: '0 9 * * *' // Daily at 9 AM
      },
      condition: {
        type: 'query',
        query: `SELECT * FROM users WHERE last_activity_at < NOW() - INTERVAL '7 days' AND re_engagement_sent = false`,
        timeout: '10m'
      },
      action: {
        type: 'email',
        provider: 'resend',
        template: 're_engagement',
        personalization: {
          name: '{{user.name}}',
          lastActivity: '{{user.last_activity_at}}'
        }
      }
    }
  ],
  recovery: {
    retries: 3,
    backoff: 'exponential'
  }
});

Frequently asked questions