<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Naveen Gautam | Blog]]></title><description><![CDATA[Naveen Gautam | Blog]]></description><link>https://blog.trynaveen.com</link><image><url>https://cdn.hashnode.com/uploads/logos/69cfab1f21e7d6350645320e/cd3b9587-7632-4e65-a3d4-ea6a5e2e527e.jpg</url><title>Naveen Gautam | Blog</title><link>https://blog.trynaveen.com</link></image><generator>RSS for Node</generator><lastBuildDate>Sun, 17 May 2026 11:19:48 GMT</lastBuildDate><atom:link href="https://blog.trynaveen.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I Built an AI-Powered Lead Capture System?]]></title><description><![CDATA[How I Built an AI-Powered Lead Capture System

Every lead matters. Are you capturing all of them?


Every Lead Matters. Are You Capturing All of Them?
Picture this.
It's 2am. Someone visits your websi]]></description><link>https://blog.trynaveen.com/ai-lead-capture</link><guid isPermaLink="true">https://blog.trynaveen.com/ai-lead-capture</guid><category><![CDATA[AI]]></category><category><![CDATA[automation]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[n8n]]></category><category><![CDATA[lead generation]]></category><dc:creator><![CDATA[Naveen Gautam]]></dc:creator><pubDate>Sun, 05 Apr 2026 18:24:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69cfab1f21e7d6350645320e/2c3a64fc-6313-4fe1-a001-28723c549516.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>How I Built an AI-Powered Lead Capture System</h1>
<blockquote>
<p>Every lead matters. Are you capturing all of them?</p>
</blockquote>
<hr />
<h2>Every Lead Matters. Are You Capturing All of Them?</h2>
<p>Picture this.</p>
<p>It's 2am. Someone visits your website, fills out your contact form, and waits for a response.</p>
<p>But you're asleep.</p>
<p>By morning — they've already hired someone else.</p>
<p><strong>This is the silent killer of freelance businesses.</strong> And it happened to me. Until I built a system that never sleeps.</p>
<hr />
<h2>The Problem I Was Trying to Solve</h2>
<p>As a freelancer, I was:</p>
<ul>
<li>❌ Manually checking emails every few hours</li>
<li>❌ Forgetting to follow up with leads</li>
<li>❌ Losing potential clients to slow response times</li>
<li>❌ Spending hours on tasks that should take seconds</li>
</ul>
<p>I needed a system that would <strong>capture every lead, respond instantly, and never miss a follow-up</strong> — without me being online 24/7.</p>
<p>So I built one.</p>
<hr />
<h2>What I Built</h2>
<p>A fully automated AI-powered lead capture system that:</p>
<pre><code>Visitor fills contact form
          ↓
Lead is instantly saved to database
          ↓
AI generates a personalized response
          ↓
Welcome email sent automatically
          ↓
Lead added to CRM
          ↓
I get notified on my phone
</code></pre>
<p><strong>All of this happens in under 30 seconds. Automatically.</strong></p>
<hr />
<h2>Tech Stack</h2>
<p>Here's everything I used:</p>
<table>
<thead>
<tr>
<th>Tool</th>
<th>Purpose</th>
</tr>
</thead>
<tbody><tr>
<td>Next.js</td>
<td>Frontend + API Routes</td>
</tr>
<tr>
<td>MongoDB</td>
<td>Lead storage</td>
</tr>
<tr>
<td>n8n</td>
<td>Automation workflows</td>
</tr>
<tr>
<td>OpenAI API</td>
<td>AI response generation</td>
</tr>
<tr>
<td>Resend</td>
<td>Email delivery</td>
</tr>
<tr>
<td>Slack</td>
<td>Real-time notifications</td>
</tr>
</tbody></table>
<hr />
<h2>Step 1 — Build the Contact Form</h2>
<p>First, I built a simple contact form in Next.js that captures:</p>
<pre><code class="language-javascript">// /app/api/contact/route.js
import connectDB from '@/lib/mongodb'
import Lead from '@/models/Lead'

export async function POST(req) {
  const { name, email, message } = await req.json()
  
  await connectDB()
  
  // Save lead to database
  await Lead.create({
    name,
    email,
    message,
    createdAt: new Date()
  })

  // Trigger n8n webhook
  await fetch(process.env.N8N_WEBHOOK_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name, email, message })
  })

  return Response.json({ success: true })
}
</code></pre>
<hr />
<h2>Step 2 — Create the Lead Model</h2>
<pre><code class="language-javascript">// /models/Lead.js
import mongoose from 'mongoose'

const LeadSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true },
  message: { type: String, required: true },
  responded: { type: Boolean, default: false },
  createdAt: { type: Date, default: Date.now }
})

export default mongoose.models.Lead || 
  mongoose.model('Lead', LeadSchema)
</code></pre>
<hr />
<h2>Step 3 — Build the n8n Workflow</h2>
<p>This is where the magic happens. My n8n workflow has 4 nodes:</p>
<p><strong>Node 1 — Webhook Trigger:</strong></p>
<pre><code>Receives data from Next.js API
Fields: name, email, message
</code></pre>
<p><strong>Node 2 — OpenAI Node:</strong></p>
<pre><code>Prompt:
"Write a short, friendly, professional email response 
for a freelancer named Naveen to a potential client 
named {{ $json.name }} who sent this message: 
{{ $json.message }}. 
Keep it under 100 words. Sign off as Naveen."
</code></pre>
<p><strong>Node 3 — Resend Email Node:</strong></p>
<pre><code>To      → {{ $json.email }}
Subject → "Re: Your message — Naveen Gautam"
Body    → {{ $json.openai_response }}
</code></pre>
<p><strong>Node 4 — Slack Notification:</strong></p>
<pre><code>🔥 New Lead!
Name: {{ $json.name }}
Email: {{ $json.email }}
Message: {{ $json.message }}
</code></pre>
<hr />
<h2>Step 4 — AI Response Generation</h2>
<p>The most powerful part of this system is the AI-generated response. Instead of sending a generic "Thanks for reaching out" email — the AI reads the client's message and writes a <strong>personalized, context-aware reply</strong>.</p>
<p>Here's an example:</p>
<p><strong>Client message:</strong></p>
<pre><code>"Hi, I need a website for my restaurant. 
Budget is around $500. Can you help?"
</code></pre>
<p><strong>AI generated response:</strong></p>
<pre><code>"Hi Sarah,

Thanks for reaching out! A restaurant website at $500 
is absolutely doable. I'd love to understand more about 
your vision — menu pages, online reservations, or 
something else?

Let's jump on a quick call this week. 
What time works for you?

— Naveen"
</code></pre>
<p><strong>Personal. Professional. Instant.</strong> ✅</p>
<hr />
<h2>Step 5 — Connect Everything</h2>
<p>Add these to your <code>.env.local</code>:</p>
<pre><code class="language-bash">MONGODB_URI=your_mongodb_uri
N8N_WEBHOOK_URL=your_n8n_webhook_url
OPENAI_API_KEY=your_openai_key
RESEND_API_KEY=your_resend_key
</code></pre>
<hr />
<h2>The Results</h2>
<p>After running this system for 30 days:</p>
<pre><code>📈 Response time      → From hours to 30 seconds
📈 Lead response rate → Increased by 80%
📈 Client conversions → 3x more replies
⏰ Time saved          → 2+ hours every day
</code></pre>
<hr />
<h2>What I Learned</h2>
<p>Building this system taught me 3 important things:</p>
<p><strong>1. Speed wins</strong> — The faster you respond, the higher your chances of closing the deal.</p>
<p><strong>2. Personalization matters</strong> — A generic response gets ignored. An AI-personalized response gets replies.</p>
<p><strong>3. Automation is not laziness</strong> — It's intelligence. The best businesses run on systems, not hustle.</p>
<hr />
<h2>You Can Build This Too</h2>
<p>This entire system took me less than a day to build. And now it works for me every single day — whether I'm working, sleeping, or on vacation.</p>
<blockquote>
<p><strong>The goal isn't to work harder. It's to build systems that work harder for you.</strong></p>
</blockquote>
<hr />
<h2>What's Next?</h2>
<p>Want to take this further? Here's what I'm adding next:</p>
<ul>
<li>🤖 AI chatbot on the website for instant visitor engagement</li>
<li>📊 Lead scoring system — prioritize high-value clients</li>
<li>📅 Automatic calendar booking — let clients schedule calls directly</li>
<li>💬 WhatsApp notifications — get alerted on the go</li>
</ul>
<hr />
<p><em>Building something similar? Have questions? Drop a comment below — I read every single one.</em></p>
]]></content:encoded></item><item><title><![CDATA[How to Integrate Stripe Payments in Next.js?]]></title><description><![CDATA[How to Integrate Stripe Payments in Next.js

Your app is built. Now make it make money.


Your App is Built. Now Make it Make Money.
You've spent weeks building your SaaS app. The UI is clean. The fea]]></description><link>https://blog.trynaveen.com/stripe-nextjs</link><guid isPermaLink="true">https://blog.trynaveen.com/stripe-nextjs</guid><category><![CDATA[stripe]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[payments]]></category><category><![CDATA[SaaS]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Naveen Gautam]]></dc:creator><pubDate>Sun, 05 Apr 2026 18:11:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69cfab1f21e7d6350645320e/790bbfe0-6c08-4687-bfd1-c55e7f057045.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>How to Integrate Stripe Payments in Next.js</h1>
<blockquote>
<p>Your app is built. Now make it make money.</p>
</blockquote>
<hr />
<h2>Your App is Built. Now Make it Make Money.</h2>
<p>You've spent weeks building your SaaS app. The UI is clean. The features work. Users love it.</p>
<p>But there's one problem.</p>
<p><strong>You're not charging anyone.</strong></p>
<p>Every day your app runs for free is a day you're leaving money on the table. And the #1 reason developers delay adding payments?</p>
<p><em>"It seems complicated."</em></p>
<p>It's not. I'll prove it to you in this guide.</p>
<hr />
<h2>Why Stripe?</h2>
<p>Before we dive in — why Stripe over everything else?</p>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Stripe</th>
<th>PayPal</th>
<th>Razorpay</th>
</tr>
</thead>
<tbody><tr>
<td>Developer Experience</td>
<td>⭐⭐⭐⭐⭐</td>
<td>⭐⭐⭐</td>
<td>⭐⭐⭐⭐</td>
</tr>
<tr>
<td>Documentation</td>
<td>Best in class</td>
<td>Average</td>
<td>Good</td>
</tr>
<tr>
<td>Subscriptions</td>
<td>Very easy</td>
<td>Complex</td>
<td>Good</td>
</tr>
<tr>
<td>Webhooks</td>
<td>Simple</td>
<td>Complicated</td>
<td>Good</td>
</tr>
<tr>
<td>Global reach</td>
<td>✅</td>
<td>✅</td>
<td>India only</td>
</tr>
<tr>
<td>Test mode</td>
<td>✅</td>
<td>✅</td>
<td>✅</td>
</tr>
</tbody></table>
<p><strong>Stripe wins on developer experience — every time.</strong></p>
<hr />
<h2>What We're Building</h2>
<p>By the end of this guide, you'll have:</p>
<ul>
<li>✅ A working Stripe checkout page</li>
<li>✅ Subscription billing system</li>
<li>✅ Webhook handler for payment events</li>
<li>✅ User plan upgrade after payment</li>
</ul>
<hr />
<h2>What You'll Need</h2>
<ul>
<li><strong>Next.js 14</strong> project</li>
<li><strong>Stripe account</strong> — stripe.com (free)</li>
<li><strong>MongoDB</strong> — for storing user data</li>
<li><strong>Basic JavaScript</strong> knowledge</li>
</ul>
<hr />
<h2>Step 1 — Install Stripe</h2>
<pre><code class="language-bash">npm install stripe @stripe/stripe-js
</code></pre>
<p>Add to <code>.env.local</code>:</p>
<pre><code class="language-bash">STRIPE_SECRET_KEY=sk_test_your_secret_key
STRIPE_PUBLISHABLE_KEY=pk_test_your_publishable_key
STRIPE_PRICE_ID=price_your_price_id
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret
NEXT_PUBLIC_URL=http://localhost:3000
</code></pre>
<hr />
<h2>Step 2 — Create Stripe Instance</h2>
<p>Create <code>/lib/stripe.js</code>:</p>
<pre><code class="language-javascript">import Stripe from 'stripe'

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: '2023-10-16'
})

export default stripe
</code></pre>
<hr />
<h2>Step 3 — Create Checkout Session</h2>
<p>Create <code>/app/api/create-checkout/route.js</code>:</p>
<pre><code class="language-javascript">import stripe from '@/lib/stripe'
import { getServerSession } from 'next-auth'
import { authOptions } from '../auth/[...nextauth]/route'

export async function POST(req) {
  // Get logged in user
  const session = await getServerSession(authOptions)

  if (!session) {
    return Response.json(
      { error: 'Please login first' }, 
      { status: 401 }
    )
  }

  try {
    // Create Stripe checkout session
    const checkoutSession = await stripe.checkout.sessions.create({
      mode: 'subscription',
      customer_email: session.user.email,
      payment_method_types: ['card'],
      line_items: [
        {
          price: process.env.STRIPE_PRICE_ID,
          quantity: 1,
        },
      ],
      success_url: `${process.env.NEXT_PUBLIC_URL}/dashboard?success=true`,
      cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`,
      metadata: {
        userId: session.user.id,
      }
    })

    return Response.json({ url: checkoutSession.url })
  } catch (error) {
    return Response.json(
      { error: error.message }, 
      { status: 500 }
    )
  }
}
</code></pre>
<hr />
<h2>Step 4 — Add Checkout Button</h2>
<p>Create your pricing page component:</p>
<pre><code class="language-jsx">// /app/pricing/page.jsx
'use client'

import { useState } from 'react'
import { useSession } from 'next-auth/react'
import { useRouter } from 'next/navigation'

export default function PricingPage() {
  const { data: session } = useSession()
  const router = useRouter()
  const [loading, setLoading] = useState(false)

  const handleCheckout = async () =&gt; {
    if (!session) {
      router.push('/login')
      return
    }

    setLoading(true)

    try {
      const res = await fetch('/api/create-checkout', {
        method: 'POST',
      })
      const data = await res.json()

      if (data.url) {
        window.location.href = data.url
      }
    } catch (error) {
      console.error('Checkout error:', error)
    } finally {
      setLoading(false)
    }
  }

  return (
    &lt;div className="min-h-screen flex items-center justify-center"&gt;
      &lt;div className="bg-white rounded-2xl p-8 shadow-lg max-w-sm w-full"&gt;
        &lt;h2 className="text-2xl font-bold mb-2"&gt;Pro Plan&lt;/h2&gt;
        &lt;p className="text-gray-500 mb-6"&gt;Everything you need to scale&lt;/p&gt;
        &lt;div className="text-4xl font-bold mb-6"&gt;
          $29&lt;span className="text-lg text-gray-400"&gt;/month&lt;/span&gt;
        &lt;/div&gt;
        &lt;ul className="space-y-3 mb-8"&gt;
          &lt;li&gt;✅ Unlimited projects&lt;/li&gt;
          &lt;li&gt;✅ Priority support&lt;/li&gt;
          &lt;li&gt;✅ Advanced analytics&lt;/li&gt;
          &lt;li&gt;✅ Custom domain&lt;/li&gt;
        &lt;/ul&gt;
        &lt;button
          onClick={handleCheckout}
          disabled={loading}
          className="w-full bg-black text-white py-3 rounded-xl font-medium hover:bg-gray-800 transition-all"
        &gt;
          {loading ? 'Loading...' : 'Get Started →'}
        &lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  )
}
</code></pre>
<hr />
<h2>Step 5 — Handle Webhooks</h2>
<p>This is the most important step. Webhooks tell your app what happened after payment.</p>
<p>Create <code>/app/api/webhooks/stripe/route.js</code>:</p>
<pre><code class="language-javascript">import stripe from '@/lib/stripe'
import connectDB from '@/lib/mongodb'
import User from '@/models/User'

export async function POST(req) {
  const body = await req.text()
  const sig = req.headers.get('stripe-signature')

  let event

  try {
    event = stripe.webhooks.constructEvent(
      body,
      sig,
      process.env.STRIPE_WEBHOOK_SECRET
    )
  } catch (err) {
    console.error('Webhook signature failed:', err)
    return Response.json(
      { error: 'Webhook error' }, 
      { status: 400 }
    )
  }

  await connectDB()

  switch (event.type) {
    
    // Payment successful → upgrade user
    case 'checkout.session.completed':
      const session = event.data.object
      await User.findOneAndUpdate(
        { email: session.customer_email },
        { 
          isPro: true,
          stripeCustomerId: session.customer,
          subscriptionId: session.subscription
        }
      )
      console.log('✅ User upgraded to Pro:', session.customer_email)
      break

    // Subscription cancelled → downgrade user  
    case 'customer.subscription.deleted':
      const subscription = event.data.object
      await User.findOneAndUpdate(
        { subscriptionId: subscription.id },
        { isPro: false }
      )
      console.log('❌ Subscription cancelled')
      break

    // Payment failed → notify user
    case 'invoice.payment_failed':
      console.log('⚠️ Payment failed:', event.data.object.customer_email)
      break
  }

  return Response.json({ received: true })
}
</code></pre>
<hr />
<h2>Step 6 — Test Your Integration</h2>
<p>Stripe gives you test card numbers — no real money involved:</p>
<pre><code>Card Number  → 4242 4242 4242 4242
Expiry       → Any future date (e.g., 12/26)
CVC          → Any 3 digits (e.g., 123)
</code></pre>
<p>Test the full flow:</p>
<pre><code>1. Click "Get Started" on pricing page
2. Enter test card details
3. Complete payment
4. Check your database — user should be isPro: true
5. Check Stripe dashboard — payment should appear
</code></pre>
<hr />
<h2>Step 7 — Protect Pro Features</h2>
<p>Now that you know who's a Pro user — protect your premium features:</p>
<pre><code class="language-javascript">// /app/api/premium-feature/route.js
import { getServerSession } from 'next-auth'
import connectDB from '@/lib/mongodb'
import User from '@/models/User'

export async function GET(req) {
  const session = await getServerSession(authOptions)
  
  if (!session) {
    return Response.json({ error: 'Not logged in' }, { status: 401 })
  }

  await connectDB()
  const user = await User.findOne({ email: session.user.email })

  if (!user?.isPro) {
    return Response.json(
      { error: 'Upgrade to Pro to access this feature' }, 
      { status: 403 }
    )
  }

  // Return premium content
  return Response.json({ data: 'Premium content here' })
}
</code></pre>
<hr />
<h2>Common Mistakes to Avoid</h2>
<pre><code>❌ Using live keys in development — always use test keys
❌ Not verifying webhook signatures — security risk
❌ Forgetting to handle subscription cancellation
❌ Not testing with Stripe test cards
❌ Storing card details yourself — let Stripe handle it
</code></pre>
<hr />
<h2>The Bigger Picture</h2>
<p>Adding Stripe to your app isn't just a technical task. It's a mindset shift.</p>
<p>The moment you add a payment button — your side project becomes a business.</p>
<pre><code>Before Stripe → "Cool project"
After Stripe  → "Real business"
</code></pre>
<blockquote>
<p><strong>Your skills have value. Start charging for them.</strong></p>
</blockquote>
<hr />
<h2>What's Next?</h2>
<p>Once payments are working, here's what to add:</p>
<ul>
<li>📧 <strong>Payment confirmation emails</strong> via Resend</li>
<li>📊 <strong>Revenue dashboard</strong> — track MRR, churn</li>
<li>🔄 <strong>Annual billing</strong> — offer discount for yearly plans</li>
<li>🎁 <strong>Free trial</strong> — 14 days before charging</li>
<li>💳 <strong>Customer portal</strong> — let users manage their subscription</li>
</ul>
<hr />
<p><em>Building a SaaS? Have questions about Stripe? Drop a comment — happy to help.</em></p>
]]></content:encoded></item><item><title><![CDATA[How to Add Authentication to Your SaaS App with NextAuth.js?]]></title><description><![CDATA[How to Add Authentication to Your SaaS App with NextAuth.js

Secure your app the right way — step by step.


Your App is Open to Everyone. That's a Problem.
Imagine building a SaaS app with premium fe]]></description><link>https://blog.trynaveen.com/nextauth-js</link><guid isPermaLink="true">https://blog.trynaveen.com/nextauth-js</guid><category><![CDATA[nextauth.js]]></category><category><![CDATA[authentication]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[SaaS]]></category><category><![CDATA[MongoDB]]></category><dc:creator><![CDATA[Naveen Gautam]]></dc:creator><pubDate>Sun, 05 Apr 2026 17:46:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69cfab1f21e7d6350645320e/270e4ce5-b470-417f-9d6f-08257e5d5593.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>How to Add Authentication to Your SaaS App with NextAuth.js</h1>
<blockquote>
<p>Secure your app the right way — step by step.</p>
</blockquote>
<hr />
<h2>Your App is Open to Everyone. That's a Problem.</h2>
<p>Imagine building a SaaS app with premium features, user dashboards, and private data.</p>
<p>Now imagine anyone can access all of it — without logging in.</p>
<p>No accounts. No passwords. No protection.</p>
<p><strong>That's a security nightmare.</strong> And it's more common than you think.</p>
<p>Authentication is the foundation of every serious web application. Get it wrong — and your entire app is exposed. Get it right — and you have a professional, secure product that users trust.</p>
<p>Let me show you how to get it right. With NextAuth.js.</p>
<hr />
<h2>Why NextAuth.js?</h2>
<p>There are many authentication solutions out there. Here's why NextAuth.js is my go-to:</p>
<table>
<thead>
<tr>
<th>Feature</th>
<th>NextAuth.js</th>
<th>Clerk</th>
<th>Firebase Auth</th>
</tr>
</thead>
<tbody><tr>
<td>Price</td>
<td>Free</td>
<td>Paid after limit</td>
<td>Free tier</td>
</tr>
<tr>
<td>Control</td>
<td>Full</td>
<td>Limited</td>
<td>Limited</td>
</tr>
<tr>
<td>Open Source</td>
<td>✅</td>
<td>❌</td>
<td>❌</td>
</tr>
<tr>
<td>Next.js integration</td>
<td>Perfect</td>
<td>Good</td>
<td>Manual</td>
</tr>
<tr>
<td>Custom database</td>
<td>✅</td>
<td>❌</td>
<td>❌</td>
</tr>
<tr>
<td>OAuth providers</td>
<td>50+</td>
<td>20+</td>
<td>10+</td>
</tr>
</tbody></table>
<p><strong>NextAuth.js gives you full control — for free. Forever.</strong></p>
<hr />
<h2>What We're Building</h2>
<p>By the end of this guide, you'll have:</p>
<ul>
<li>✅ Google OAuth login</li>
<li>✅ Email/password login</li>
<li>✅ Protected routes — only logged in users can access</li>
<li>✅ User data saved to MongoDB</li>
<li>✅ Session management</li>
</ul>
<hr />
<h2>What You'll Need</h2>
<ul>
<li><strong>Next.js 14</strong> project</li>
<li><strong>MongoDB Atlas</strong> account</li>
<li><strong>Google Cloud Console</strong> account — for OAuth</li>
<li><strong>Basic JavaScript</strong> knowledge</li>
</ul>
<hr />
<h2>Step 1 — Install NextAuth.js</h2>
<pre><code class="language-bash">npm install next-auth bcryptjs
npm install -D @types/bcryptjs
</code></pre>
<p>Add to <code>.env.local</code>:</p>
<pre><code class="language-bash">NEXTAUTH_SECRET=your_random_secret_key_here
NEXTAUTH_URL=http://localhost:3000
GOOGLE_ID=your_google_client_id
GOOGLE_SECRET=your_google_client_secret
MONGODB_URI=your_mongodb_connection_string
</code></pre>
<hr />
<h2>Step 2 — Create User Model</h2>
<p>Create <code>/models/User.js</code>:</p>
<pre><code class="language-javascript">import mongoose from 'mongoose'

const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true,
    unique: true
  },
  password: {
    type: String,
    // Not required — Google users won't have password
  },
  image: {
    type: String,
  },
  isPro: {
    type: Boolean,
    default: false
  },
  createdAt: {
    type: Date,
    default: Date.now
  }
})

export default mongoose.models.User || 
  mongoose.model('User', UserSchema)
</code></pre>
<hr />
<h2>Step 3 — Setup Google OAuth</h2>
<p>Before writing code — get your Google credentials:</p>
<pre><code>1. Go to console.cloud.google.com
2. Create new project → "My SaaS App"
3. APIs &amp; Services → Credentials
4. Create Credentials → OAuth Client ID
5. Application type → Web application
6. Authorized redirect URIs:
   → http://localhost:3000/api/auth/callback/google
7. Copy Client ID and Client Secret
8. Paste in .env.local
</code></pre>
<hr />
<h2>Step 4 — Configure NextAuth</h2>
<p>Create <code>/app/api/auth/[...nextauth]/route.js</code>:</p>
<pre><code class="language-javascript">import NextAuth from 'next-auth'
import GoogleProvider from 'next-auth/providers/google'
import CredentialsProvider from 'next-auth/providers/credentials'
import bcrypt from 'bcryptjs'
import connectDB from '@/lib/mongodb'
import User from '@/models/User'

export const authOptions = {
  providers: [
    // Google OAuth
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),

    // Email + Password
    CredentialsProvider({
      name: 'credentials',
      credentials: {
        email: { label: 'Email', type: 'email' },
        password: { label: 'Password', type: 'password' }
      },
      async authorize(credentials) {
        await connectDB()

        // Find user by email
        const user = await User.findOne({ 
          email: credentials.email 
        })

        if (!user) {
          throw new Error('No user found with this email')
        }

        // Check password
        const isValid = await bcrypt.compare(
          credentials.password, 
          user.password
        )

        if (!isValid) {
          throw new Error('Incorrect password')
        }

        return user
      }
    })
  ],

  callbacks: {
    // Save Google user to database
    async signIn({ user, account }) {
      if (account.provider === 'google') {
        await connectDB()
        const existingUser = await User.findOne({ 
          email: user.email 
        })
        if (!existingUser) {
          await User.create({
            name: user.name,
            email: user.email,
            image: user.image,
          })
        }
      }
      return true
    },

    // Add user data to session
    async session({ session }) {
      await connectDB()
      const dbUser = await User.findOne({ 
        email: session.user.email 
      })
      session.user.id = dbUser._id.toString()
      session.user.isPro = dbUser.isPro
      return session
    }
  },

  pages: {
    signIn: '/login',
    error: '/login',
  },

  secret: process.env.NEXTAUTH_SECRET,
}

const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }
</code></pre>
<hr />
<h2>Step 5 — Register New Users</h2>
<p>Create <code>/app/api/register/route.js</code>:</p>
<pre><code class="language-javascript">import bcrypt from 'bcryptjs'
import connectDB from '@/lib/mongodb'
import User from '@/models/User'

export async function POST(req) {
  const { name, email, password } = await req.json()

  // Validate input
  if (!name || !email || !password) {
    return Response.json(
      { error: 'All fields are required' },
      { status: 400 }
    )
  }

  await connectDB()

  // Check if user already exists
  const existingUser = await User.findOne({ email })
  if (existingUser) {
    return Response.json(
      { error: 'User already exists' },
      { status: 400 }
    )
  }

  // Hash password
  const hashedPassword = await bcrypt.hash(password, 12)

  // Create user
  await User.create({
    name,
    email,
    password: hashedPassword,
  })

  return Response.json({ 
    message: 'Account created successfully' 
  })
}
</code></pre>
<hr />
<h2>Step 6 — Build Login Page</h2>
<p>Create <code>/app/login/page.jsx</code>:</p>
<pre><code class="language-jsx">'use client'

import { useState } from 'react'
import { signIn } from 'next-auth/react'
import { useRouter } from 'next/navigation'

export default function LoginPage() {
  const router = useRouter()
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState('')

  const handleSubmit = async (e) =&gt; {
    e.preventDefault()
    setLoading(true)
    setError('')

    const result = await signIn('credentials', {
      email,
      password,
      redirect: false,
    })

    if (result?.error) {
      setError('Invalid email or password')
      setLoading(false)
      return
    }

    router.push('/dashboard')
  }

  return (
    &lt;div className="min-h-screen flex items-center justify-center bg-gray-50"&gt;
      &lt;div className="bg-white rounded-2xl p-8 shadow-lg w-full max-w-md"&gt;
        &lt;h1 className="text-2xl font-bold mb-6"&gt;Welcome back&lt;/h1&gt;

        {error &amp;&amp; (
          &lt;div className="bg-red-50 text-red-500 p-3 rounded-lg mb-4"&gt;
            {error}
          &lt;/div&gt;
        )}

        &lt;form onSubmit={handleSubmit} className="space-y-4"&gt;
          &lt;input
            type="email"
            placeholder="Email"
            value={email}
            onChange={(e) =&gt; setEmail(e.target.value)}
            className="w-full border rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-black"
            required
          /&gt;
          &lt;input
            type="password"
            placeholder="Password"
            value={password}
            onChange={(e) =&gt; setPassword(e.target.value)}
            className="w-full border rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-black"
            required
          /&gt;
          &lt;button
            type="submit"
            disabled={loading}
            className="w-full bg-black text-white py-3 rounded-xl font-medium hover:bg-gray-800 transition-all"
          &gt;
            {loading ? 'Signing in...' : 'Sign In'}
          &lt;/button&gt;
        &lt;/form&gt;

        &lt;div className="my-4 text-center text-gray-400"&gt;or&lt;/div&gt;

        &lt;button
          onClick={() =&gt; signIn('google', { callbackUrl: '/dashboard' })}
          className="w-full border py-3 rounded-xl font-medium hover:bg-gray-50 transition-all flex items-center justify-center gap-2"
        &gt;
          Continue with Google
        &lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  )
}
</code></pre>
<hr />
<h2>Step 7 — Protect Routes with Middleware</h2>
<p>Create <code>middleware.js</code> in root directory:</p>
<pre><code class="language-javascript">export { default } from 'next-auth/middleware'

export const config = {
  matcher: [
    '/dashboard/:path*',
    '/settings/:path*',
    '/profile/:path*'
  ]
}
</code></pre>
<p><strong>Done.</strong> Anyone trying to access <code>/dashboard</code> without logging in gets redirected to <code>/login</code> automatically. ✅</p>
<hr />
<h2>Step 8 — Use Session in Components</h2>
<pre><code class="language-jsx">'use client'

import { useSession, signOut } from 'next-auth/react'

export default function Dashboard() {
  const { data: session, status } = useSession()

  if (status === 'loading') return &lt;div&gt;Loading...&lt;/div&gt;
  if (!session) return &lt;div&gt;Not logged in&lt;/div&gt;

  return (
    &lt;div&gt;
      &lt;h1&gt;Welcome, {session.user.name}! 👋&lt;/h1&gt;
      &lt;p&gt;Email: {session.user.email}&lt;/p&gt;
      &lt;p&gt;Plan: {session.user.isPro ? '⭐ Pro' : 'Free'}&lt;/p&gt;
      
      &lt;button onClick={() =&gt; signOut({ callbackUrl: '/' })}&gt;
        Sign Out
      &lt;/button&gt;
    &lt;/div&gt;
  )
}
</code></pre>
<hr />
<h2>Common Mistakes to Avoid</h2>
<pre><code>❌ Forgetting NEXTAUTH_SECRET — app won't work in production
❌ Not adding redirect URIs in Google Console
❌ Storing plain text passwords — always hash with bcrypt
❌ Not protecting API routes — anyone can call them
❌ Forgetting to wrap app with SessionProvider
</code></pre>
<hr />
<h2>Wrap App with SessionProvider</h2>
<p>In <code>/app/layout.js</code>:</p>
<pre><code class="language-jsx">import { SessionProvider } from 'next-auth/react'

export default function RootLayout({ children }) {
  return (
    &lt;html&gt;
      &lt;body&gt;
        &lt;SessionProvider&gt;
          {children}
        &lt;/SessionProvider&gt;
      &lt;/body&gt;
    &lt;/html&gt;
  )
}
</code></pre>
<hr />
<h2>The Bigger Picture</h2>
<p>Authentication isn't just a technical feature. It's the first impression users have of your product.</p>
<p>A smooth, fast login experience builds trust instantly.</p>
<pre><code>Slow/broken login  → User leaves forever
Smooth login       → User trusts your product
</code></pre>
<blockquote>
<p><strong>Authentication done right is invisible. Users don't notice it — because it just works.</strong></p>
</blockquote>
<hr />
<h2>What's Next?</h2>
<p>Now that authentication is solid, here's what to add:</p>
<ul>
<li>🔑 <strong>Forgot password</strong> — email reset flow</li>
<li>📱 <strong>Two-factor authentication</strong> — extra security</li>
<li>🎭 <strong>Role-based access</strong> — admin vs user</li>
<li>📊 <strong>Login analytics</strong> — track user activity</li>
<li>🔒 <strong>Rate limiting</strong> — prevent brute force attacks</li>
</ul>
<hr />
<p><em>Have questions about NextAuth.js? Drop a comment below — I read every single one.</em></p>
]]></content:encoded></item><item><title><![CDATA[Next.js vs React — Which One Should You Use?]]></title><description><![CDATA[Next.js vs React — Which One Should You Use?

The question every developer asks — answered honestly.


First — Let's Clear the Confusion
Here's the thing most tutorials get wrong:

Next.js IS React. I]]></description><link>https://blog.trynaveen.com/nextjs-vs-react</link><guid isPermaLink="true">https://blog.trynaveen.com/nextjs-vs-react</guid><category><![CDATA[Next.js]]></category><category><![CDATA[React]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[frontend]]></category><dc:creator><![CDATA[Naveen Gautam]]></dc:creator><pubDate>Sun, 05 Apr 2026 17:19:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69cfab1f21e7d6350645320e/569384c6-aab3-4545-b54a-e7bbefdef1cd.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Next.js vs React — Which One Should You Use?</h1>
<blockquote>
<p>The question every developer asks — answered honestly.</p>
</blockquote>
<hr />
<h2>First — Let's Clear the Confusion</h2>
<p>Here's the thing most tutorials get wrong:</p>
<blockquote>
<p><strong>Next.js IS React. It's not a competitor.</strong></p>
</blockquote>
<p>Next.js is a framework built ON TOP of React. It takes everything React does and adds superpowers — server-side rendering, routing, API routes, image optimization, and more.</p>
<p>Think of it this way:</p>
<pre><code>React    = Engine of a car
Next.js  = The full car — engine + body + wheels + GPS
</code></pre>
<p>You can build a car from scratch with just an engine. But why would you?</p>
<hr />
<h2>What is React?</h2>
<p>React is a JavaScript library for building user interfaces. It's component-based, fast, and incredibly flexible.</p>
<pre><code class="language-jsx">// Simple React component
function Welcome({ name }) {
  return (
    &lt;div&gt;
      &lt;h1&gt;Hello, {name}!&lt;/h1&gt;
      &lt;p&gt;Welcome to my app.&lt;/p&gt;
    &lt;/div&gt;
  )
}
</code></pre>
<p><strong>React gives you:</strong></p>
<ul>
<li>✅ Component-based architecture</li>
<li>✅ Virtual DOM for fast rendering</li>
<li>✅ Huge ecosystem</li>
<li>✅ Complete flexibility</li>
</ul>
<p><strong>But React alone lacks:</strong></p>
<ul>
<li>❌ Built-in routing</li>
<li>❌ Server-side rendering</li>
<li>❌ SEO optimization</li>
<li>❌ API routes</li>
<li>❌ Image optimization</li>
</ul>
<hr />
<h2>What is Next.js?</h2>
<p>Next.js is a React framework that solves all of React's limitations — out of the box.</p>
<pre><code class="language-jsx">// Next.js page — automatic routing
// File: /app/about/page.jsx
export default function About() {
  return (
    &lt;div&gt;
      &lt;h1&gt;About Page&lt;/h1&gt;
      &lt;p&gt;This route is automatic — no setup needed.&lt;/p&gt;
    &lt;/div&gt;
  )
}
</code></pre>
<p><strong>Next.js gives you everything React has, plus:</strong></p>
<ul>
<li>✅ File-based routing — automatic</li>
<li>✅ Server-side rendering (SSR)</li>
<li>✅ Static site generation (SSG)</li>
<li>✅ API routes — backend in the same project</li>
<li>✅ Image optimization — automatic</li>
<li>✅ SEO friendly — out of the box</li>
<li>✅ Edge functions</li>
<li>✅ Middleware support</li>
</ul>
<hr />
<h2>Head to Head Comparison</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>React</th>
<th>Next.js</th>
</tr>
</thead>
<tbody><tr>
<td>Routing</td>
<td>Manual (React Router)</td>
<td>Automatic (file-based)</td>
</tr>
<tr>
<td>SSR</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td>SSG</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td>SEO</td>
<td>Poor</td>
<td>Excellent</td>
</tr>
<tr>
<td>API Routes</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td>Image Optimization</td>
<td>Manual</td>
<td>Automatic</td>
</tr>
<tr>
<td>Learning Curve</td>
<td>Medium</td>
<td>Slightly higher</td>
</tr>
<tr>
<td>Bundle Size</td>
<td>Smaller</td>
<td>Larger</td>
</tr>
<tr>
<td>Deployment</td>
<td>Anywhere</td>
<td>Vercel (best)</td>
</tr>
<tr>
<td>Full-Stack</td>
<td>❌</td>
<td>✅</td>
</tr>
</tbody></table>
<hr />
<h2>Performance — The Real Difference</h2>
<p>This is where Next.js truly shines.</p>
<p><strong>React (Client-Side Rendering):</strong></p>
<pre><code>User visits page
      ↓
Browser downloads JavaScript
      ↓
JavaScript runs
      ↓
Page renders
      ↓
User sees content
</code></pre>
<p><strong>Problem:</strong> User sees blank screen while JS loads. Bad for SEO. Bad for slow connections.</p>
<p><strong>Next.js (Server-Side Rendering):</strong></p>
<pre><code>User visits page
      ↓
Server renders HTML
      ↓
User sees content instantly
      ↓
JavaScript loads in background
</code></pre>
<p><strong>Result:</strong> Faster load times. Better SEO. Better user experience. ✅</p>
<hr />
<h2>Real World Use Cases</h2>
<p><strong>Use React when:</strong></p>
<pre><code>✅ Building a dashboard (no SEO needed)
✅ Internal tools
✅ Mobile apps with React Native
✅ Learning web development basics
✅ Simple SPAs (Single Page Applications)
</code></pre>
<p><strong>Use Next.js when:</strong></p>
<pre><code>✅ Building a portfolio website
✅ E-commerce store (SEO critical)
✅ SaaS application
✅ Blog or content website
✅ Any production application
✅ Full-stack project
</code></pre>
<hr />
<h2>The SEO Argument</h2>
<p>If your project needs to be found on Google — <strong>Next.js wins. Every time.</strong></p>
<p>Here's why:</p>
<p>Google crawls HTML. React renders everything in JavaScript — which Google struggles to index properly.</p>
<p>Next.js pre-renders pages as HTML on the server. Google reads it perfectly. Your pages rank higher.</p>
<pre><code>React   → Google sees empty page → Bad ranking
Next.js → Google sees full HTML  → Good ranking
</code></pre>
<p>For a portfolio, a SaaS landing page, or any public-facing website — this alone makes Next.js the obvious choice.</p>
<hr />
<h2>My Personal Opinion</h2>
<p>I've built projects with both. Here's my honest take:</p>
<p><strong>Learn React first.</strong> Understand components, state, props, hooks. Build something small. Get comfortable.</p>
<p><strong>Then move to Next.js.</strong> Once you know React, Next.js feels like a natural upgrade. Everything clicks faster.</p>
<blockquote>
<p><strong>For any serious project in 2025 — Next.js is the answer.</strong></p>
</blockquote>
<p>The industry has spoken. Vercel, Notion, TikTok, Twitch — they all use Next.js. There's a reason for that.</p>
<hr />
<h2>Quick Decision Guide</h2>
<pre><code>Learning web dev?          → Start with React
Building a portfolio?      → Next.js
Building a SaaS?           → Next.js
Building a blog?           → Next.js
Need SEO?                  → Next.js
Internal dashboard?        → React is fine
Already know React?        → Switch to Next.js now
</code></pre>
<hr />
<h2>The Bottom Line</h2>
<p>Stop debating. Stop overthinking.</p>
<p>If you're building something that real users will see — <strong>use Next.js.</strong></p>
<p>If you're just learning — <strong>start with React, then upgrade.</strong></p>
<p>The longer you wait to learn Next.js, the more you're falling behind. The ecosystem has moved. The industry has moved.</p>
<blockquote>
<p><strong>It's time you move too.</strong></p>
</blockquote>
<hr />
<p><em>Found this helpful? Follow me for more honest takes on web development, Next.js, and building real products.</em></p>
]]></content:encoded></item><item><title><![CDATA[Automate Your Business with n8n — Complete Guide]]></title><description><![CDATA[Stop Wasting Time on Tasks a Robot Can Do
You wake up, 47 unread emails, 12 Slack messages, 3 spreadsheets to update. And your actual work hasn't even started yet.
Sound familiar?
What if I told you t]]></description><link>https://blog.trynaveen.com/automation-n8n</link><guid isPermaLink="true">https://blog.trynaveen.com/automation-n8n</guid><category><![CDATA[n8n]]></category><category><![CDATA[automation]]></category><category><![CDATA[business automation]]></category><category><![CDATA[Workflow Automation]]></category><dc:creator><![CDATA[Naveen Gautam]]></dc:creator><pubDate>Sun, 05 Apr 2026 12:10:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69cfab1f21e7d6350645320e/a5879349-4721-47a6-a5f5-ceae8d960bd5.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Stop Wasting Time on Tasks a Robot Can Do</h2>
<p>You wake up, 47 unread emails, 12 Slack messages, 3 spreadsheets to update. And your actual work hasn't even started yet.</p>
<p>Sound familiar?</p>
<p>What if I told you that 90% of those repetitive tasks could run themselves — automatically, accurately, and while you sleep?</p>
<p>That's not a dream. That's n8n.</p>
<h2>What Exactly is n8n?</h2>
<p>n8n is an open-source workflow automation tool that acts as the nervous system of your business. It connects your apps, watches for events, and triggers actions — all without you touching a single button.</p>
<p>Think of it like this:</p>
<pre><code class="language-bash">Something happens somewhere
          ↓
n8n notices it
          ↓
n8n does exactly what you told it to do
          ↓
You get the result — automatically
</code></pre>
<p>No code. No manual work. No missed follow-ups. Ever again.</p>
<h2>What We're Building Today</h2>
<p>By the end of this guide, you'll have a workflow that:</p>
<ul>
<li><p>✅ Captures a new lead from your website</p>
</li>
<li><p>✅ Saves it to Google Sheets automatically</p>
</li>
<li><p>✅ Sends a personalized welcome email</p>
</li>
<li><p>✅ Notifies your Slack channel instantly</p>
</li>
</ul>
<p>All triggered the moment someone submits your form. Zero manual effort.</p>
<h2>What You'll Need</h2>
<p>Before we dive in, grab these:</p>
<ul>
<li><p>n8n account → n8n.io (free cloud trial)</p>
</li>
<li><p>Google account → for Sheets + Gmail</p>
</li>
<li><p>Slack workspace → for notifications</p>
</li>
<li><p>10 minutes → seriously, that's all</p>
</li>
</ul>
<h2>Step 1 — Get n8n Running</h2>
<p>Cloud (easiest):</p>
<pre><code class="language-bash">1. Go to n8n.io
2. Click "Start for free"
3. Sign up → You're in
</code></pre>
<p>Self-hosted with Docker (for full control):</p>
<pre><code class="language-bash">docker run -it --rm \
  --name n8n \
  -p 5678:5678 \
  n8nio/n8n
</code></pre>
<p>Open <a href="http://localhost:5678">http://localhost:5678</a> — your n8n dashboard is ready.</p>
<h2>Step 2 — Create Your First Workflow</h2>
<pre><code class="language-bash">1. Click "New Workflow"
2. Click "+" to add your first node
3. Search "Webhook"
4. Select "Webhook" as your trigger
5. Copy the webhook URL — this is your entry point
</code></pre>
<p>Every time data hits this URL, your workflow fires. Simple as that.</p>
<h2>Step 3 — Save to Google Sheets</h2>
<pre><code class="language-plaintext">1. Click "+" after the webhook node
2. Search "Google Sheets"
3. Select "Append Row"
4. Connect your Google account
5. Choose your spreadsheet
6. Map your fields:
</code></pre>
<pre><code class="language-javascript">Name  → {{ $json.name }}
Email → {{ $json.email }}
Date  → {{ $now }}
</code></pre>
<p>Every new lead → instantly saved. No more copy-pasting. ✅</p>
<h2>Step 4 — Send a Welcome Email</h2>
<pre><code class="language-plaintext">1. Click "+" after Google Sheets
2. Search "Gmail"
3. Select "Send Email"
4. Connect Gmail
5. Configure:
</code></pre>
<pre><code class="language-plaintext">To      → {{ $json.email }}
Subject → "Hey {{ $json.name }}, you're in! 🎉"
Body    → "Hi {{ $json.name }},

Thanks for reaching out! I've received your message 
and will get back to you within 24 hours.

Looking forward to working with you.

— Naveen"
</code></pre>
<p>Your leads get an instant, personalized response — even at 3am. ✅</p>
<h2>Step 5 — Slack Notification</h2>
<pre><code class="language-plaintext">1. Click "+" after Gmail
2. Search "Slack"
3. Select "Send Message"
4. Connect Slack
5. Message:
</code></pre>
<pre><code class="language-plaintext">🔥 New Lead Alert!
Name: {{ $json.name }}
Email: {{ $json.email }}
Time: {{ $now }}
</code></pre>
<p>You'll know the second someone reaches out — wherever you are. ✅</p>
<h2>Step 6 — Go Live</h2>
<pre><code class="language-plaintext">1. Click "Save"
2. Toggle "Active" → ON
3. Your workflow is now running 24/7
</code></pre>
<p>Test it right now:</p>
<pre><code class="language-javascript">fetch('your_webhook_url', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    name: 'Naveen Gautam',
    email: 'naveen@trynaveen.com'
  })
})
</code></pre>
<p>Check your Google Sheet. Check your email. Check Slack. It works.You just automated your first business process. 🚀</p>
<hr />
<h2>Real Businesses Using This Right Now</h2>
<p>This exact workflow is saving hours every week for:</p>
<pre><code class="language-plaintext">🛒 E-commerce     → Order → Invoice → Shipping update
🏠 Real Estate    → Lead → CRM → Automated follow-up
🍕 Restaurant     → Booking → Confirmation → Calendar
💼 Agencies       → Client signup → Onboarding → Welcome kit
⚡ SaaS Products  → New user → Email sequence → Analytics
</code></pre>
<hr />
<h2>The Bigger Picture</h2>
<p>This is just one workflow. One use case. But once you understand how n8n thinks — the possibilities are literally endless.</p>
<p>Imagine:</p>
<ul>
<li><p>Your entire sales pipeline running on autopilot</p>
</li>
<li><p>Invoice generation triggered by payment</p>
</li>
<li><p>Social media posts scheduled automatically</p>
</li>
<li><p>Weekly reports sent without you touching a thing</p>
</li>
</ul>
<blockquote>
<p>One workflow at a time. That's how you build a business that runs itself.</p>
</blockquote>
<hr />
<h2>What's Next?</h2>
<p>Now that you've built your first automation:</p>
<ol>
<li><p>Add more triggers — forms, payments, emails</p>
</li>
<li><p>Connect more apps — CRM, calendars, databases</p>
</li>
<li><p>Add conditions — if/else logic for smarter workflows</p>
</li>
<li><p>Schedule workflows — run at specific times</p>
</li>
</ol>
<p>The rabbit hole goes deep. And it's worth every minute.</p>
<hr />
<p><em>Enjoyed this? Follow me for more content on n8n, AI automation, and full-stack development. New tutorials every week</em>.</p>
]]></content:encoded></item><item><title><![CDATA[How to Build a Full-Stack SaaS App with Next.js?]]></title><description><![CDATA[Why Next.js for SaaS
Next.js is the go-to framework for building modern SaaS applications in 2025. It gives you server-side rendering, API routes, and seamless deployment — all in one package. Combine]]></description><link>https://blog.trynaveen.com/saas-nextjs</link><guid isPermaLink="true">https://blog.trynaveen.com/saas-nextjs</guid><category><![CDATA[Next.js]]></category><category><![CDATA[stripe]]></category><category><![CDATA[SaaS]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[full stack]]></category><dc:creator><![CDATA[Naveen Gautam]]></dc:creator><pubDate>Sat, 04 Apr 2026 11:31:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69cfab1f21e7d6350645320e/92fa9186-6f2c-473f-8006-1493b212ec24.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Why Next.js for SaaS</h2>
<p>Next.js is the go-to framework for building modern SaaS applications in 2025. It gives you server-side rendering, API routes, and seamless deployment — all in one package. Combined with MongoDB and Stripe, you can ship a complete SaaS product faster than ever.</p>
<p>In this guide, I'll show you exactly how I build full-stack SaaS apps — from project setup to live deployment.</p>
<h2>What You'll Need</h2>
<p>Before we start, make sure you have these ready:</p>
<ul>
<li><p>✅ Node.js — v18 or higher</p>
</li>
<li><p>✅ MongoDB Atlas account</p>
</li>
<li><p>✅ Stripe account — for payments</p>
</li>
<li><p>✅ Vercel account — for deployment</p>
</li>
<li><p>✅ Basic knowledge of React and JavaScript</p>
</li>
</ul>
<h2>🧰 Tech Stack</h2>
<table>
<thead>
<tr>
<th>Tool</th>
<th>Role</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Next.js 14</strong></td>
<td>Full-stack framework</td>
</tr>
<tr>
<td><strong>MongoDB Atlas</strong></td>
<td>Cloud database</td>
</tr>
<tr>
<td><strong>Mongoose</strong></td>
<td>MongoDB ORM</td>
</tr>
<tr>
<td><strong>NextAuth.js</strong></td>
<td>Authentication</td>
</tr>
<tr>
<td><strong>Stripe</strong></td>
<td>Subscription payments</td>
</tr>
<tr>
<td><strong>Tailwind CSS</strong></td>
<td>Styling</td>
</tr>
<tr>
<td><strong>Vercel</strong></td>
<td>Deployment</td>
</tr>
</tbody></table>
<h2>Step 1 — Project Setup</h2>
<p>Open your terminal and run:</p>
<pre><code class="language-bash">npx create-next-app@latest my-saas-app
cd my-saas-app
npm install mongoose next-auth stripe @stripe/stripe-js
</code></pre>
<p>Create your .env.local file:</p>
<pre><code class="language-javascript">MONGODB_URI=your_mongodb_connection_string
GOOGLE_ID=your_google_client_id
GOOGLE_SECRET=your_google_client_secret
NEXTAUTH_SECRET=your_random_secret
NEXTAUTH_URL=http://localhost:3000
STRIPE_SECRET_KEY=your_stripe_secret_key
STRIPE_PRICE_ID=your_stripe_price_id
NEXT_PUBLIC_URL=http://localhost:3000
</code></pre>
<h2>Step 2 — Connect MongoDB</h2>
<p>Create /lib/mongodb.js:</p>
<pre><code class="language-bash">import mongoose from 'mongoose'

const connectDB = async () =&gt; {
  if (mongoose.connections[0].readyState) return
  
  try {
    await mongoose.connect(process.env.MONGODB_URI)
    console.log('MongoDB connected successfully')
  } catch (error) {
    console.error('MongoDB connection error:', error)
  }
}

export default connectDB
</code></pre>
<h2>Step 3 — Setup Authentication</h2>
<p>Create /app/api/auth/[...nextauth]/route.js:</p>
<pre><code class="language-javascript">import NextAuth from 'next-auth'
import GoogleProvider from 'next-auth/providers/google'
import connectDB from '@/lib/mongodb'
import User from '@/models/User'

export const authOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    })
  ],
  callbacks: {
    async signIn({ user }) {
      await connectDB()
      const existingUser = await User.findOne({ email: user.email })
      if (!existingUser) {
        await User.create({
          name: user.name,
          email: user.email,
          image: user.image,
        })
      }
      return true
    }
  }
}

const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }
</code></pre>
<h2>Step 4 — Stripe Subscription</h2>
<p>Create /app/api/create-checkout/route.js:</p>
<pre><code class="language-javascript">import Stripe from 'stripe'
import { getServerSession } from 'next-auth'
import { authOptions } from '../auth/[...nextauth]/route'

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)

export async function POST(req) {
  const session = await getServerSession(authOptions)
  
  if (!session) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 })
  }

  const checkoutSession = await stripe.checkout.sessions.create({
    mode: 'subscription',
    customer_email: session.user.email,
    payment_method_types: ['card'],
    line_items: [{
      price: process.env.STRIPE_PRICE_ID,
      quantity: 1,
    }],
    success_url: `${process.env.NEXT_PUBLIC_URL}/dashboard?success=true`,
    cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`,
  })

  return Response.json({ url: checkoutSession.url })
}
</code></pre>
<h2>Step 5 — Protect Routes</h2>
<p>Create middleware.js in root:</p>
<pre><code class="language-javascript">export { default } from 'next-auth/middleware'

export const config = {
  matcher: ['/dashboard/:path*', '/settings/:path*']
}
</code></pre>
<h2>Step 6 — Handle Stripe Webhooks</h2>
<p>Create /app/api/webhooks/stripe/route.js:</p>
<pre><code class="language-bash">import Stripe from 'stripe'
import connectDB from '@/lib/mongodb'
import User from '@/models/User'

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)

export async function POST(req) {
  const body = await req.text()
  const sig = req.headers.get('stripe-signature')

  let event
  try {
    event = stripe.webhooks.constructEvent(
      body, sig, process.env.STRIPE_WEBHOOK_SECRET
    )
  } catch (err) {
    return Response.json({ error: 'Webhook error' }, { status: 400 })
  }

  await connectDB()

  if (event.type === 'checkout.session.completed') {
    const session = event.data.object
    await User.findOneAndUpdate(
      { email: session.customer_email },
      { isPro: true }
    )
  }

  return Response.json({ received: true })
}
</code></pre>
<h2>Step 7 — Deploy on Vercel</h2>
<pre><code class="language-plaintext"># Install Vercel CLI
npm install -g vercel

# Deploy
vercel

# Set environment variables in Vercel dashboard
# Then deploy to production
vercel --prod
</code></pre>
<h2>Wrapping Up</h2>
<p>Building a SaaS app with Next.js becomes easy when you break it into small steps:</p>
<ul>
<li>✅ Setup project</li>
<li>✅ Connect database</li>
<li>✅ Add authentication</li>
<li>✅ Integrate payments</li>
<li>✅ Protect routes</li>
<li>✅ Handle webhooks</li>
<li>✅ Deploy</li>
</ul>
<blockquote>
<p>The best SaaS is the one that ships. Start small, iterate fast, and keep building.</p>
</blockquote>
<p><em>Found this helpful? Follow me for more full-stack development content. 🚀</em></p>
]]></content:encoded></item></channel></rss>