md files
This commit is contained in:
249
QR-Master-Analysis-April-2026.md
Normal file
249
QR-Master-Analysis-April-2026.md
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
# QR Master — Deep Analysis & Growth Potential
|
||||||
|
**Date:** April 1, 2026 | **Project Age:** 3 months (launched Jan 1, 2026)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
QR Master is a young but well-built QR code SaaS entering a **$1–7B market growing at 16%+ CAGR**. After just 3 months, the numbers tell an interesting story: explosive impression growth in Google Search (0 → 4,100/month), strong AI citation momentum (1,849 citations across 11 pages), and 169 unique visitors in the last 90 days with promising engagement metrics (8m 36s avg session, 16% bounce rate). However, organic search clicks remain very low, and there are zero paying customers visible yet. The opportunity is real, but execution over the next 6 months will determine everything.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Your Numbers — What They Tell Me
|
||||||
|
|
||||||
|
### Google Search Console (Jan–Mar 2026)
|
||||||
|
|
||||||
|
| Metric | January | February | March | Growth |
|
||||||
|
|--------|---------|----------|-------|--------|
|
||||||
|
| Impressions | 158 | 44 | 4,115 | **+2,504%** |
|
||||||
|
| Clicks | 0 | 0 | 23 | From zero |
|
||||||
|
| Avg Position | ~1.3 | ~3.3 | ~68.4 | Widened (more keywords) |
|
||||||
|
|
||||||
|
**What this means:** Google discovered your site in late January, but the real indexing explosion happened in March. The jump from 44 impressions in February to 4,115 in March is dramatic — this is the "Google sandbox" lifting. The average position being ~68 means most of your keywords are on pages 6–7 of Google. That's normal for a 3-month-old domain, but it also means you're not getting meaningful organic traffic yet from competitive terms.
|
||||||
|
|
||||||
|
**Top performing pages by impressions:**
|
||||||
|
|
||||||
|
| Page | Impressions | Clicks | Avg Position |
|
||||||
|
|------|-------------|--------|-------------|
|
||||||
|
| Homepage | 356 | 15 | 4.0 |
|
||||||
|
| Barcode Generator | 1,160 | 4 | 71.4 |
|
||||||
|
| Dynamic QR Code Generator | 536 | 0 | 81.1 |
|
||||||
|
| Restaurant Menu QR Blog | 425 | 0 | 80.9 |
|
||||||
|
| Geolocation QR Code | 281 | 0 | 73.2 |
|
||||||
|
| URL QR Code | 205 | 0 | 83.6 |
|
||||||
|
| Twitter QR Code | 169 | 0 | 71.3 |
|
||||||
|
|
||||||
|
**Key insight:** Your barcode generator page has 1,160 impressions but only 4 clicks because it's ranking at position 71. If you can move that to page 1, even position 8–10, you'd capture 20–50 clicks/day from that keyword cluster alone. Same story for "dynamic QR code generator" (536 impressions, position 81).
|
||||||
|
|
||||||
|
### AI Citations (Google AI Overviews)
|
||||||
|
|
||||||
|
| Week | Citations | Avg/Day | Trend |
|
||||||
|
|------|-----------|---------|-------|
|
||||||
|
| Week 9 (late Feb) | 123 | 30.8 | Baseline |
|
||||||
|
| Week 10 | 328 | 46.9 | +167% |
|
||||||
|
| Week 11 | 343 | 49.0 | +5% |
|
||||||
|
| Week 12 | 514 | 73.4 | +50% |
|
||||||
|
| Week 13 | 541 | 77.3 | +5% |
|
||||||
|
|
||||||
|
**Total: 1,849 citations across up to 11 unique pages.**
|
||||||
|
|
||||||
|
This is genuinely impressive for a 3-month-old site. AI citations at 77/day means Google's AI is actively referencing your content when answering QR-related queries. This is a leading indicator — AI citations often precede organic ranking improvements. You're building topical authority faster than traditional SEO alone would deliver.
|
||||||
|
|
||||||
|
### PostHog Analytics (Last 90 Days)
|
||||||
|
|
||||||
|
| Metric | Value | Assessment |
|
||||||
|
|--------|-------|-----------|
|
||||||
|
| Unique Visitors | 169 | Low, but expected for 3 months |
|
||||||
|
| Page Views | 2,120 | ~12.5 pages/visitor — very high engagement |
|
||||||
|
| Sessions | 417 | 2.5 sessions/visitor average |
|
||||||
|
| Session Duration | 8m 36s | Excellent — users are exploring deeply |
|
||||||
|
| Bounce Rate | 16% | Outstanding (industry avg is 40-60%) |
|
||||||
|
|
||||||
|
**Traffic sources:**
|
||||||
|
|
||||||
|
| Channel | Visitors | Views |
|
||||||
|
|---------|----------|-------|
|
||||||
|
| Referral | 100 | 803 |
|
||||||
|
| Organic Social | 64 | 89 |
|
||||||
|
| Direct | 17 | 1,123 |
|
||||||
|
| Organic Search | 6 | 70 |
|
||||||
|
|
||||||
|
**Critical insight:** Your 16% bounce rate and 8.5-minute session duration are exceptional. People who find your site actually use it. The problem isn't product quality — it's distribution. Only 6 visitors from organic search in 90 days confirms you're still in the early SEO growth phase.
|
||||||
|
|
||||||
|
**Retention concern:** The cohort data shows near-zero retention after week 1 for most cohorts. This is the biggest red flag — users come, try the tool, but don't come back. This is typical for free QR generator users, but it means conversion to paid will depend heavily on capturing value during that first session.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Competitive Landscape
|
||||||
|
|
||||||
|
### The Market You're Entering
|
||||||
|
|
||||||
|
The QR code generator market is valued at **$1.1–6.8B in 2025** (estimates vary by definition) and growing at **16–17% CAGR**. Dynamic QR codes specifically are the revenue driver, accounting for 55-64% of market value.
|
||||||
|
|
||||||
|
### Key Competitors
|
||||||
|
|
||||||
|
| Company | Est. Revenue (2025) | Pricing | Key Strength |
|
||||||
|
|---------|-------------------|---------|-------------|
|
||||||
|
| **Flowcode** | $15.7M | Free / $5-25/mo | VC-backed, design-focused, landing pages |
|
||||||
|
| **Bitly** | $200M+ (link shortening + QR) | $8–199/mo | Brand recognition, link ecosystem |
|
||||||
|
| **Uniqode** (fka Beaconstac) | ~$10M est. | $5–99/mo | Enterprise (SOC2, HIPAA, ISO) |
|
||||||
|
| **QR Tiger** | ~$5M est. | $7–37/mo | SEO-aggressive, content marketing |
|
||||||
|
| **Trycon/Scanova** | $7.2M | $5–49/mo | 2,000+ businesses, enterprise |
|
||||||
|
| **Mobilo** | $5.4M | $4.99–14.99/mo | Digital business cards focus |
|
||||||
|
| **Unitag** | $2.3M | Free / $9.90+/mo | European market, design tools |
|
||||||
|
| **QR Code Creator** | $1.5M | $4.99–14.99/mo | Long-established (since 2009) |
|
||||||
|
| **QRCode Monkey** | Unknown | Free (ad-supported) | SEO dominant, free tools |
|
||||||
|
|
||||||
|
### What This Means for QR Master
|
||||||
|
|
||||||
|
The market has room. Even QR Code Creator, which has been around since 2009, only does $1.5M. The winner-take-all dynamics of pure SaaS don't apply as strongly here because QR codes are a utility — businesses often try 2-3 tools before settling. Key entry angles that still work: niche verticals (restaurants, real estate), better free tier to build SEO traffic, and superior analytics.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. SEO Assessment
|
||||||
|
|
||||||
|
### Current State: Early but Promising
|
||||||
|
|
||||||
|
Your site is showing 700+ unique keywords with impressions — that's a lot of keyword surface area for a 3-month-old site. But almost all rankings are on pages 5-10 of Google (positions 50-100).
|
||||||
|
|
||||||
|
### Biggest Keyword Opportunities (High Impression, Improvable Position)
|
||||||
|
|
||||||
|
| Keyword | Monthly Impressions | Current Position | Difficulty |
|
||||||
|
|---------|-------------------|-----------------|-----------|
|
||||||
|
| barcode generator | 148+ | 74.8 | Very High |
|
||||||
|
| dynamic qr code | 115+ | 80.3 | High |
|
||||||
|
| dynamic qr code generator | 81+ | 85.8 | High |
|
||||||
|
| restaurant qr code | 51+ | 75.0 | Medium |
|
||||||
|
| qr code restaurant menu | 48+ | 82.8 | Medium |
|
||||||
|
| twitter qr code | 46+ | 76.7 | Low-Medium |
|
||||||
|
| instagram qr code generator | 35+ | 54.9 | Medium |
|
||||||
|
| bulk qr code generator | 28+ | 94.4 | Medium |
|
||||||
|
| vcard qr code generator | 9+ | 74.9 | Low-Medium |
|
||||||
|
| teams qr code | 3+ | 34.7 | Low |
|
||||||
|
|
||||||
|
### Quick Wins (Already Close to Page 1)
|
||||||
|
|
||||||
|
- **"teams qr code"** — Position 34.7 with dedicated tool page already built. You already have traffic to this page (20 visitors in PostHog). Push this to page 1.
|
||||||
|
- **"zoom qr code"** — Position 40.3. Similar opportunity.
|
||||||
|
- **"qrmaster"** branded terms — Position 4.3 (already strong, but should be #1)
|
||||||
|
- **"qr master"** — Position 8.1. Should be #1 for your own brand.
|
||||||
|
|
||||||
|
### What's Holding You Back
|
||||||
|
|
||||||
|
1. **Domain age (3 months):** Google inherently trusts older domains more. This improves automatically with time.
|
||||||
|
2. **Backlink profile:** Likely thin. Your referral traffic (100 visitors) suggests some links, but you need more authoritative ones.
|
||||||
|
3. **Competition on head terms:** "QR code generator" is dominated by Bitly, QRCode Monkey, QR Tiger with DA 50+ domains. You won't rank for this soon.
|
||||||
|
4. **Content depth vs. competitors:** QR Tiger and Uniqode have 100+ blog posts each. You're early in content production.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Revenue Potential — Realistic Projections
|
||||||
|
|
||||||
|
### Assumptions
|
||||||
|
|
||||||
|
Based on your current pricing model (FREE / PRO / BUSINESS tiers) and market benchmarks:
|
||||||
|
|
||||||
|
- **Free-to-paid conversion rate for QR tools:** 2-4% (industry benchmark)
|
||||||
|
- **Average revenue per user (ARPU):** $10-20/month for SMB QR tools
|
||||||
|
- **Churn rate:** 5-8% monthly for SMB SaaS
|
||||||
|
|
||||||
|
### Scenario Modeling
|
||||||
|
|
||||||
|
#### Conservative (SEO-only growth, no paid acquisition)
|
||||||
|
|
||||||
|
| Month | Monthly Visitors | Signups (15% CVR) | Paying Users (cum.) | MRR |
|
||||||
|
|-------|-----------------|-------------------|--------------------|----|
|
||||||
|
| Month 3 (now) | 170 | 39 | 0 | $0 |
|
||||||
|
| Month 6 | 1,000 | 150 | 8 | $120 |
|
||||||
|
| Month 12 | 5,000 | 750 | 60 | $900 |
|
||||||
|
| Month 18 | 15,000 | 2,250 | 200 | $3,000 |
|
||||||
|
| Month 24 | 40,000 | 6,000 | 500 | $7,500 |
|
||||||
|
|
||||||
|
**Year 1 ARR: ~$10,800 | Year 2 ARR: ~$90,000**
|
||||||
|
|
||||||
|
#### Moderate (SEO + content marketing + some link building)
|
||||||
|
|
||||||
|
| Month | Monthly Visitors | Signups | Paying Users (cum.) | MRR |
|
||||||
|
|-------|-----------------|---------|--------------------|----|
|
||||||
|
| Month 6 | 3,000 | 450 | 25 | $375 |
|
||||||
|
| Month 12 | 15,000 | 2,250 | 180 | $2,700 |
|
||||||
|
| Month 18 | 40,000 | 6,000 | 500 | $7,500 |
|
||||||
|
| Month 24 | 80,000 | 12,000 | 1,200 | $18,000 |
|
||||||
|
|
||||||
|
**Year 1 ARR: ~$32,400 | Year 2 ARR: ~$216,000**
|
||||||
|
|
||||||
|
#### Aggressive (SEO + paid + partnerships + viral loops)
|
||||||
|
|
||||||
|
| Month | Monthly Visitors | Signups | Paying Users (cum.) | MRR |
|
||||||
|
|-------|-----------------|---------|--------------------|----|
|
||||||
|
| Month 12 | 50,000 | 7,500 | 600 | $9,000 |
|
||||||
|
| Month 24 | 200,000 | 30,000 | 3,000 | $45,000 |
|
||||||
|
|
||||||
|
**Year 2 ARR: ~$540,000**
|
||||||
|
|
||||||
|
### Revenue Benchmarks from Comparable Companies
|
||||||
|
|
||||||
|
- QR Code Creator (17 years old): **$1.5M/year**
|
||||||
|
- Unitag (10+ years old): **$2.3M/year**
|
||||||
|
- Flowcode (7 years, VC-backed): **$15.7M/year**
|
||||||
|
- Indie SaaS benchmarks: $5K–25K MRR is very achievable within 18-24 months with focused execution
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Strengths & Risks
|
||||||
|
|
||||||
|
### What's Working
|
||||||
|
|
||||||
|
1. **Product quality is high.** 8.5-minute sessions, 16% bounce rate, 12.5 pages/visitor — these are remarkable engagement metrics. The product holds attention.
|
||||||
|
2. **AI citations growing fast.** 77 citations/day after 3 months is a strong signal Google's AI trusts your content.
|
||||||
|
3. **Broad keyword footprint.** 700+ keywords showing impressions means Google is indexing and considering your pages for a wide range of queries.
|
||||||
|
4. **Niche tool pages (Teams, Zoom, WiFi, Instagram).** These long-tail pages are your fastest path to page 1 rankings.
|
||||||
|
5. **Technical foundation is solid.** Next.js 14, Stripe, analytics, dynamic QR codes — the infrastructure is already at a paid-product level.
|
||||||
|
|
||||||
|
### Risks & Concerns
|
||||||
|
|
||||||
|
1. **Near-zero retention.** Cohort data shows almost no users returning after week 1. Without solving retention, paid conversion will be extremely difficult.
|
||||||
|
2. **No revenue yet.** 3 months with 0 MRR is normal, but the clock is ticking. Need to see first paying user by month 4-5.
|
||||||
|
3. **Competitive head terms are years away.** You won't rank for "QR code generator" anytime soon. The long-tail strategy is correct but requires patience.
|
||||||
|
4. **Single-channel dependency.** Currently SEO-reliant. If Google changes its algorithm or sandbox behavior, growth stalls.
|
||||||
|
5. **service_account.json in root.** If this is a live credential, it's a security risk. Remove from version control immediately.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Recommendations — Next 90 Days
|
||||||
|
|
||||||
|
### Immediate (This Month)
|
||||||
|
|
||||||
|
1. **Fix retention first.** Add email capture on first QR creation, build a "My QR Codes" dashboard value prop, and implement a follow-up email sequence showing scan analytics. Users need a reason to come back.
|
||||||
|
2. **Push "quick win" keywords to page 1.** Teams QR code (pos 34), Zoom QR code (pos 40), and your branded terms. These need targeted backlinks and content optimization.
|
||||||
|
3. **Add pricing friction at the right moment.** If you're not gating anything, users have no reason to pay. Consider limiting dynamic QR codes to 1-3 on free tier, then upsell.
|
||||||
|
|
||||||
|
### Short-term (Months 4-6)
|
||||||
|
|
||||||
|
4. **Build 10-15 high-quality backlinks.** Guest posts on marketing blogs, HARO/Connectively responses, tool directories. Domain authority is your bottleneck.
|
||||||
|
5. **Double down on restaurant/menu niche.** You have 425 impressions on the restaurant menu QR blog. This is a vertical where local businesses actually pay for QR tools. Build a dedicated landing page.
|
||||||
|
6. **Launch on Product Hunt, Indie Hackers, and relevant subreddits.** Free exposure that also builds backlinks.
|
||||||
|
|
||||||
|
### Medium-term (Months 6-12)
|
||||||
|
|
||||||
|
7. **Expand content to 50+ blog posts.** Target every long-tail QR keyword cluster. QR Tiger's content machine is the model to emulate.
|
||||||
|
8. **Add a freemium viral loop.** "Powered by QR Master" branding on free QR codes (with option to remove on paid plan).
|
||||||
|
9. **Consider German market positioning.** Your GSC data shows German-language queries (dynamische QR codes, etc.) and you appear to be German-speaking. The German QR code market is underserved compared to English.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Bottom Line
|
||||||
|
|
||||||
|
**Is there real potential here?** Yes, absolutely. The QR code market is large, growing, and the barrier to entry is manageable with good technical execution — which you clearly have. Companies doing $1.5M–$15M in this space prove the model works.
|
||||||
|
|
||||||
|
**How much can you realistically make?** With sustained effort, **$3K–$10K MRR by month 18** is realistic under a moderate growth scenario. That's $36K–$120K ARR — meaningful side-project revenue. The top end of $200K+ ARR is achievable within 24 months if you invest in content, backlinks, and conversion optimization.
|
||||||
|
|
||||||
|
**What's the biggest risk?** Not retention, not competition — it's giving up too early. SEO-driven SaaS is a compounding game. Months 1-6 feel slow because organic traffic takes time to build. The hockey stick starts around months 9-12 when domain authority compounds with content volume. QR Code Creator took 17 years to hit $1.5M, but the market was 10x smaller then.
|
||||||
|
|
||||||
|
**Your 3-month scorecard: B+.** Excellent product, strong engagement, growing search visibility. The missing pieces are retention mechanics, first revenue, and backlink authority. All fixable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Analysis based on Google Search Console data (Jan–Mar 2026), PostHog analytics (90 days), Google AI Performance data, and market research as of April 2026.*
|
||||||
|
|
||||||
|
*Sources: [Mordor Intelligence QR Market Report](https://www.mordorintelligence.com/industry-reports/qr-codes-market), [GetLatka QR SaaS Companies](https://getlatka.com/companies/industries/i-qr-code-generator-software), [Bitly QR Code Statistics](https://bitly.com/blog/qr-code-statistics/), [360iResearch QR Market](https://www.360iresearch.com/library/intelligence/qr-code-generator), [QR Code Chimp Statistics](https://www.qrcodechimp.com/qr-code-statistics/)*
|
||||||
461
TODO.md
Normal file
461
TODO.md
Normal file
@@ -0,0 +1,461 @@
|
|||||||
|
# QR Master — Growth TODO
|
||||||
|
|
||||||
|
Based on: 3-month audit (PostHog + GSC + AI citations + full codebase review, April 2026)
|
||||||
|
Domain age at audit: ~3 months | Visitors (90d): 169 | AI citations (33d): 1,849
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How to use this file
|
||||||
|
|
||||||
|
Sections are ordered by impact-per-hour-of-work. Don't skip to section 5 before section 1.
|
||||||
|
Each task has the exact file to touch and what to change. No hand-waving.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Section 1 — Retention (do this week, nothing else matters until it's done)
|
||||||
|
|
||||||
|
Cohort data shows ~10% week-1 retention, near-zero by week 3. Root cause: **no email is sent after signup**. Zero. The `sendWelcomeEmail` function does not exist. Users sign up and hear nothing.
|
||||||
|
|
||||||
|
### 1.1 — Welcome email sequence (3 emails)
|
||||||
|
|
||||||
|
**File to edit:** `src/lib/email.ts`
|
||||||
|
Add three new exported functions after the existing `sendPasswordResetEmail`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// Email 1: Sent immediately on signup
|
||||||
|
export async function sendWelcomeEmail(email: string, name: string) {}
|
||||||
|
|
||||||
|
// Email 2: Sent on Day 3 if user has 0 QR codes (check via cron or on login)
|
||||||
|
export async function sendActivationNudgeEmail(email: string, name: string) {}
|
||||||
|
|
||||||
|
// Email 3: Sent on Day 7 if user has ≥1 QR code but is still on FREE plan
|
||||||
|
export async function sendUpgradeNudgeEmail(email: string, name: string, qrCount: number) {}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Email 1 — Welcome (Day 0)**
|
||||||
|
- Subject: `Your QR Master account is ready`
|
||||||
|
- Body: One action only → create first QR code. Link to `/create`.
|
||||||
|
- Mention the 3 free dynamic codes.
|
||||||
|
- 4–5 sentences max, plain layout.
|
||||||
|
- Sender: `Timo from QR Master <timo@qrmaster.net>`
|
||||||
|
|
||||||
|
**Email 2 — Activation nudge (Day 3, no QR codes created)**
|
||||||
|
- Subject: `Still haven't made your first QR code?`
|
||||||
|
- Trigger condition: `user.createdAt < now - 3 days AND qrCodes.count === 0`
|
||||||
|
- Body: One screenshot or step-by-step (3 steps). One CTA → `/create`.
|
||||||
|
- Don't send if they've already created one.
|
||||||
|
|
||||||
|
**Email 3 — Upgrade nudge (Day 7, has codes, still FREE)**
|
||||||
|
- Subject: `You've created {n} QR codes — here's what you're missing`
|
||||||
|
- Trigger condition: `qrCodes.count >= 1 AND plan === 'FREE' AND createdAt < now - 7 days`
|
||||||
|
- Body: 3 specific things they can't do on free: analytics breakdown, custom branding, more than 3 codes.
|
||||||
|
- CTA → `/pricing`
|
||||||
|
|
||||||
|
**File to edit:** `src/app/(main)/api/auth/signup/route.ts`
|
||||||
|
Add `sendWelcomeEmail` call after the user is created (line ~88, after `db.user.create`):
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// After db.user.create(...)
|
||||||
|
try {
|
||||||
|
await sendWelcomeEmail(user.email, user.name ?? 'there');
|
||||||
|
} catch (emailError) {
|
||||||
|
// Don't fail signup if email fails
|
||||||
|
console.error('Welcome email failed:', emailError);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**For emails 2 and 3:** Either add a cron job (`/api/cron/retention-emails`) or check + send on each login in `/api/auth/simple-login` route. Cron is cleaner. Vercel cron syntax:
|
||||||
|
|
||||||
|
```json
|
||||||
|
// vercel.json
|
||||||
|
{
|
||||||
|
"crons": [{ "path": "/api/cron/retention-emails", "schedule": "0 10 * * *" }]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1.2 — Cancel flow (before Stripe portal)
|
||||||
|
|
||||||
|
**File to edit:** `src/app/(main)/(app)/settings/page.tsx`
|
||||||
|
Right now: button → Stripe portal. Users cancel without any friction or reason capture.
|
||||||
|
|
||||||
|
Replace the `Manage Subscription` button with a handler that opens a modal first:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// Add state
|
||||||
|
const [showCancelModal, setShowCancelModal] = useState(false);
|
||||||
|
const [cancelReason, setCancelReason] = useState('');
|
||||||
|
|
||||||
|
// Replace direct portal redirect with:
|
||||||
|
const handleManageSubscription = () => {
|
||||||
|
if (plan !== 'FREE') {
|
||||||
|
setShowCancelModal(true); // intercept — show exit survey first
|
||||||
|
} else {
|
||||||
|
// FREE users can just go to portal normally
|
||||||
|
openStripePortal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Cancel modal — 4 steps:**
|
||||||
|
|
||||||
|
1. **Survey:** "Before you go — what's the main reason?" (radio: too expensive / not using it / missing feature / other)
|
||||||
|
2. **Save offer** based on reason:
|
||||||
|
- `too_expensive` → *"What if we gave you 25% off for 2 months?"* → button calls `/api/stripe/apply-discount`
|
||||||
|
- `not_using` → *"Want to pause instead of cancel?"* → pause link or info
|
||||||
|
- `missing_feature` → *"Tell us what's missing"* → textarea → submit to `/api/feedback`, then let them proceed
|
||||||
|
- `other` → short text → submit to `/api/feedback`, then proceed
|
||||||
|
3. **Confirm:** "Still want to cancel? Your plan stays active until [end of billing period]." → button opens Stripe portal
|
||||||
|
4. **Post-cancel:** Stripe webhook already exists at `/api/stripe/webhook` — add a case for `customer.subscription.deleted` that logs the cancellation reason and (optionally) triggers a win-back email in 30 days.
|
||||||
|
|
||||||
|
**Save the reasons to DB.** Add a `cancellationReason` field to the User model in `prisma/schema.prisma` so you actually learn why people leave.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Section 2 — Signup flow (2–3 hours of work, immediate conversion lift)
|
||||||
|
|
||||||
|
Current form: Name → Email → Password → Confirm Password → [Create Account] → divider → Google button
|
||||||
|
Problem: Google should be first. Confirm Password should not exist.
|
||||||
|
|
||||||
|
### 2.1 — Move Google OAuth above the form
|
||||||
|
|
||||||
|
**File:** `src/app/(main)/(auth)/signup/SignupClient.tsx`
|
||||||
|
|
||||||
|
Move the Google button block (currently after the `<form>`) to above the `<form>`. The divider "Or continue with" becomes "Or sign up with email" below the Google button.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// New order in the Card:
|
||||||
|
<CardContent className="p-6">
|
||||||
|
{/* Google FIRST */}
|
||||||
|
<Button type="button" variant="outline" className="w-full" onClick={handleGoogleSignIn}>
|
||||||
|
{/* Google SVG */} Sign up with Google
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<div className="relative my-6">
|
||||||
|
{/* divider */}
|
||||||
|
<span className="px-2 bg-white text-gray-500">Or sign up with email</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Email form SECOND */}
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
...
|
||||||
|
</form>
|
||||||
|
</CardContent>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 — Remove the Confirm Password field
|
||||||
|
|
||||||
|
**File:** `src/app/(main)/(auth)/signup/SignupClient.tsx`
|
||||||
|
|
||||||
|
Delete the `confirmPassword` state, the `confirmPassword` Input field, and the `if (password !== confirmPassword)` check. Replace with a password visibility toggle on the Password field instead:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
|
// In the Input:
|
||||||
|
<div className="relative">
|
||||||
|
<Input
|
||||||
|
label="Password"
|
||||||
|
type={showPassword ? 'text' : 'password'}
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
|
placeholder="••••••••"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setShowPassword(!showPassword)}
|
||||||
|
className="absolute right-3 top-9 text-gray-400 hover:text-gray-600"
|
||||||
|
>
|
||||||
|
{showPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 — Add value reinforcement to the signup page
|
||||||
|
|
||||||
|
**File:** `src/app/(main)/(auth)/signup/SignupClient.tsx`
|
||||||
|
|
||||||
|
Change the subtitle under "Create Account" from:
|
||||||
|
> *"Start creating QR codes in seconds"*
|
||||||
|
|
||||||
|
To:
|
||||||
|
> *"No credit card required — 3 dynamic QR codes free forever"*
|
||||||
|
|
||||||
|
Also remove the prominent "← Back to Home" bordered button. It's visually competing with the form. Replace with a small text link at the bottom of the card:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<p className="text-center text-xs text-gray-400 mt-4">
|
||||||
|
Already have an account? <Link href="/login">Sign in</Link> · <Link href="/">Back to home</Link>
|
||||||
|
</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Section 3 — Homepage copy (half a day)
|
||||||
|
|
||||||
|
### 3.1 — Headline rewrite
|
||||||
|
|
||||||
|
**File:** `src/i18n/en.json`
|
||||||
|
Current: `"title": "Create QR Codes That Work Everywhere"`
|
||||||
|
|
||||||
|
Replace with one of (pick based on your gut for the audience):
|
||||||
|
|
||||||
|
```json
|
||||||
|
"title": "The Free QR Code Generator That Doesn't Expire"
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```json
|
||||||
|
"title": "Track Every Scan. Update Every Link. Free Forever."
|
||||||
|
```
|
||||||
|
|
||||||
|
Subtitle — current: *"Generate static and dynamic QR codes with tracking, custom branding, and bulk generation. Free forever."*
|
||||||
|
Replace:
|
||||||
|
```json
|
||||||
|
"subtitle": "Dynamic QR codes you can edit anytime without reprinting — see exactly who scanned, where, and on what device. Starts free, no credit card."
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 — Feature bullets: features → outcomes
|
||||||
|
|
||||||
|
**File:** `src/i18n/en.json`, `hero.features` array
|
||||||
|
|
||||||
|
```json
|
||||||
|
"features": [
|
||||||
|
"Change your link anytime — no reprinting needed",
|
||||||
|
"See scan location, device, and time of day",
|
||||||
|
"Your QR codes work forever, even on the free plan",
|
||||||
|
"Match your brand: custom colors in under a minute"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 — Hero right column: replace animation with product screenshot
|
||||||
|
|
||||||
|
**File:** `src/components/marketing/Hero.tsx`
|
||||||
|
|
||||||
|
The flipping cards grid (lines ~130–175) should be replaced with either:
|
||||||
|
- A static screenshot of the analytics dashboard (real scan data, anonymized)
|
||||||
|
- A live mini-generator: paste a URL → QR code renders inline (highest conversion)
|
||||||
|
|
||||||
|
A live mini-generator in the hero is the highest-impact change on the whole homepage. Even a simplified version that just renders a basic QR code and links to `/create` for customization would work.
|
||||||
|
|
||||||
|
### 3.4 — Add a social proof number to the hero
|
||||||
|
|
||||||
|
**File:** `src/components/marketing/Hero.tsx` or `src/components/marketing/StatsStrip.tsx`
|
||||||
|
|
||||||
|
Add one concrete number directly in or immediately below the hero — before the fold. Options:
|
||||||
|
- `"1M+ QR codes generated"` (if true or close)
|
||||||
|
- `"Trusted by 500+ businesses"` (if defensible)
|
||||||
|
- `"Cited by ChatGPT, Perplexity & Google AI"` (actually true based on your AI data — this is a unique claim almost no competitor can make)
|
||||||
|
|
||||||
|
The last one is genuinely differentiated and verified.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Section 4 — Content: the 5 posts that will move GSC rankings
|
||||||
|
|
||||||
|
These are ordered by current GSC impression data — they already have Google's attention, they just need the content to justify moving up.
|
||||||
|
|
||||||
|
### 4.1 — Barcode generator companion post
|
||||||
|
|
||||||
|
**Current situation:** `/tools/barcode-generator` has 1,160 GSC impressions at position 71. No blog post supports it.
|
||||||
|
|
||||||
|
**Create:** `src/app/(main)/(marketing)/blog/barcode-vs-qr-code/` (or add to `src/lib/blog-data.ts`)
|
||||||
|
**Title:** *"Barcode vs QR Code: What's the Difference and When to Use Each"*
|
||||||
|
**Target query:** `barcode vs qr code` / `difference between barcode and qr code`
|
||||||
|
**Must include:** a comparison table (scanners required, data capacity, use cases, editability), a "when to use each" section, internal links to `/tools/barcode-generator` and `/dynamic-qr-code-generator`.
|
||||||
|
|
||||||
|
### 4.2 — Teams QR code blog post
|
||||||
|
|
||||||
|
**Current situation:** `/tools/teams-qr-code` gets 20 PostHog visitors with 0% bounce and ranks ~position 22 in GSC — the closest page to page 1 you have.
|
||||||
|
|
||||||
|
**Create:** blog post targeting `microsoft teams qr code` / `teams meeting qr code`
|
||||||
|
**Title:** *"How to Create a Microsoft Teams QR Code for Instant Meeting Joins"*
|
||||||
|
**Internal link:** back to `/tools/teams-qr-code` from the post and vice versa (the tool page should link to this post for content depth).
|
||||||
|
|
||||||
|
### 4.3 — WiFi QR code post update
|
||||||
|
|
||||||
|
**Current situation:** `/tools/wifi-qr-code` ranks ~position 44 (close to page 4). 14 PostHog visitors, 0% bounce.
|
||||||
|
|
||||||
|
**File:** The wifi tool page has German keywords mixed into English metadata (`wlan qr code erstellen`, `wifi passwort qr code`). Decide: is this page targeting English or German? Mixed intent hurts both. For the English version, clean up to English-only keywords. For German, create a dedicated `/de/` route (there's already a German path at `(marketing-de)`).
|
||||||
|
|
||||||
|
**Action:** Add a content section below the WiFi generator tool with at minimum: a "common WiFi QR code uses" section (restaurants, hotels, offices, Airbnb), a FAQ block (3–5 questions), and an internal link to the main QR generator.
|
||||||
|
|
||||||
|
### 4.4 — Fix the 2025-dated content
|
||||||
|
|
||||||
|
**File:** `src/lib/blog-data.ts`
|
||||||
|
|
||||||
|
The post with slug `qr-code-tracking-guide-2025` has `2025` in its URL. Update:
|
||||||
|
- `slug`: change to `qr-code-tracking-guide` or `qr-code-tracking-guide-2026`
|
||||||
|
- `title`: update year references in the content
|
||||||
|
- `dateModified`: set to current date
|
||||||
|
- Add a redirect in `next.config.mjs` from the old slug to the new one:
|
||||||
|
|
||||||
|
```js
|
||||||
|
async redirects() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: '/blog/qr-code-tracking-guide-2025',
|
||||||
|
destination: '/blog/qr-code-tracking-guide-2026',
|
||||||
|
permanent: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.5 — "Best QR code generator 2026" — make it actually compete
|
||||||
|
|
||||||
|
**File:** `src/lib/blog-data.ts` — post slug `best-qr-code-generator-2026` exists but has ~9 GSC position and 0 clicks from 38 impressions.
|
||||||
|
|
||||||
|
This post needs to be the most comprehensive comparison page on the site. It currently isn't doing the job. It needs:
|
||||||
|
- A feature comparison table: QR Master vs Bitly vs QR Code Generator vs Beaconstac (columns: free plan limits, dynamic QR, analytics, branding, bulk, pricing)
|
||||||
|
- Honest pros/cons for each (being fake-neutral is immediately obvious and AI systems penalise it)
|
||||||
|
- A `FAQPage` schema block
|
||||||
|
- Statistics with cited sources (e.g., "QR code scans grew X% in 2025 — [source]")
|
||||||
|
- `dateModified` updated to current month
|
||||||
|
|
||||||
|
This post alone, done properly, is the highest-value AI-citation target on the whole site.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Section 5 — AI SEO quick fixes (1–2 hours)
|
||||||
|
|
||||||
|
These are code-level changes, not content work.
|
||||||
|
|
||||||
|
### 5.1 — Add cited sources to every statistic in blog posts
|
||||||
|
|
||||||
|
**File:** `src/lib/blog-data.ts`
|
||||||
|
|
||||||
|
Every blog post `content` field that contains a statistic without a source link needs one. Example fix in the restaurant post:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- Before -->
|
||||||
|
<p>over 60% of restaurants that adopted QR menus during 2020–2021 kept them afterward</p>
|
||||||
|
|
||||||
|
<!-- After -->
|
||||||
|
<p>over 60% of restaurants that adopted QR menus during 2020–2021 kept them afterward
|
||||||
|
<a href="https://nationalrestaurantassociation.org/..." target="_blank" rel="noopener">[NRA, 2022]</a></p>
|
||||||
|
```
|
||||||
|
|
||||||
|
Per Princeton GEO research: adding cited sources increases AI citation rate by +40%. This is the single highest-ROI AI SEO action available.
|
||||||
|
|
||||||
|
### 5.2 — Add definition blocks to tool pages
|
||||||
|
|
||||||
|
**Which pages:** barcode generator, WiFi QR generator, Teams QR generator, URL QR generator
|
||||||
|
**What to add:** A one-paragraph definition in the first `<p>` tag that directly answers "What is a [X] generator?" in 40–60 words. AI systems extract from the opening paragraph first.
|
||||||
|
|
||||||
|
Example for barcode generator:
|
||||||
|
```html
|
||||||
|
<p>A barcode generator creates machine-readable linear barcodes (EAN-13, UPC-A, Code 128)
|
||||||
|
from numeric or alphanumeric data. Unlike QR codes, barcodes store data in parallel lines
|
||||||
|
and are scanned by dedicated readers. Use this free tool to generate printable barcodes
|
||||||
|
for retail products, inventory labels, or shipping.</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 — Add `dateModified` display to blog post pages
|
||||||
|
|
||||||
|
**File:** whichever component renders the blog post header — search for `publishDate` or `datePublished` usage in `src/app/(main)/(marketing)/blog/`
|
||||||
|
|
||||||
|
AI tools penalise undated content. Every post already has `dateModified` in `blog-data.ts` — it just needs to render visibly on the page. Add "Last updated: [date]" next to the author line. It's one line of JSX.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Section 6 — Pricing page (1 hour)
|
||||||
|
|
||||||
|
**File:** `src/i18n/en.json`, pricing section + the Pricing component
|
||||||
|
|
||||||
|
### 6.1 — Add upgrade trigger context to the Pro plan
|
||||||
|
|
||||||
|
Under the Pro plan title, add a single explanatory sentence that explains *when* someone should upgrade:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"pro": {
|
||||||
|
"trigger": "When you hit 3 dynamic QR codes or need scan analytics"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Render this in the Pricing component under the plan title, above the price.
|
||||||
|
|
||||||
|
### 6.2 — Free plan: explain the limit as a feature, not a restriction
|
||||||
|
|
||||||
|
Current: `"3 active dynamic QR codes (8 types available)"`
|
||||||
|
Rewrite: `"3 dynamic QR codes — enough to start. Unlimited static codes."`
|
||||||
|
|
||||||
|
The current copy leads with the limit. Lead with what they get.
|
||||||
|
|
||||||
|
### 6.3 — Annual pricing
|
||||||
|
|
||||||
|
There's no annual discount mentioned anywhere in the pricing UI. If Stripe supports annual billing, surface it. A toggle (Monthly / Annual — save 20%) on the pricing page typically lifts plan revenue by 15–30% by locking in longer commitments. Check `src/lib/stripe.ts` for whether annual price IDs exist.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Section 7 — Dashboard first-run experience (2–3 hours)
|
||||||
|
|
||||||
|
### 7.1 — Empty state when user has 0 QR codes
|
||||||
|
|
||||||
|
**File:** `src/app/(main)/(app)/dashboard/page.tsx`
|
||||||
|
|
||||||
|
Currently, a new user lands on a dashboard with stats showing all zeros and an empty grid. There's a loading skeleton for QR codes but no empty state when `qrCodes.length === 0`.
|
||||||
|
|
||||||
|
Add an empty state component:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
{!loading && qrCodes.length === 0 && (
|
||||||
|
<div className="text-center py-16 border-2 border-dashed border-gray-200 rounded-xl">
|
||||||
|
<QrCode className="w-12 h-12 text-gray-300 mx-auto mb-4" />
|
||||||
|
<h3 className="text-lg font-semibold text-gray-700 mb-2">Create your first QR code</h3>
|
||||||
|
<p className="text-gray-500 mb-6 max-w-sm mx-auto">
|
||||||
|
You have 3 free dynamic QR codes. They redirect wherever you want and track every scan.
|
||||||
|
</p>
|
||||||
|
<Link href="/create">
|
||||||
|
<Button>Create QR Code — it takes 90 seconds</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 — Remove the mock QR codes from the dashboard code
|
||||||
|
|
||||||
|
**File:** `src/app/(main)/(app)/dashboard/page.tsx`, lines ~45–100
|
||||||
|
|
||||||
|
There's a `mockQRCodes` array defined but it doesn't appear to be rendered (the real fetch path is used). Verify and remove the dead code to keep the file clean.
|
||||||
|
|
||||||
|
### 7.3 — Dashboard subtitle should be contextual
|
||||||
|
|
||||||
|
**File:** `src/app/(main)/(app)/dashboard/page.tsx`
|
||||||
|
|
||||||
|
Current subtitle: `{t('dashboard.subtitle')}` → "Manage and track your QR codes"
|
||||||
|
|
||||||
|
For users with 0 QR codes, show: *"Start here — create your first QR code in under 2 minutes"*
|
||||||
|
For users with QR codes, show the current text.
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
<p className="text-gray-600 mt-2">
|
||||||
|
{qrCodes.length === 0
|
||||||
|
? 'Start here — create your first QR code in under 2 minutes'
|
||||||
|
: t('dashboard.subtitle')}
|
||||||
|
</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Metrics to watch
|
||||||
|
|
||||||
|
| Thing changed | Metric to check | Where |
|
||||||
|
|---|---|---|
|
||||||
|
| Welcome email | Cohort retention week 1 | PostHog → Retention |
|
||||||
|
| Signup form (Google first, remove confirm PW) | Signup completion rate | PostHog → Funnels |
|
||||||
|
| Cancel flow | Cancelled users / month | Stripe dashboard |
|
||||||
|
| Hero headline | Bounce rate on `/` | PostHog → Paths |
|
||||||
|
| Barcode + Teams blog posts | GSC impressions & position | Search Console |
|
||||||
|
| Cited statistics in posts | AI citations/day | AI perf CSV |
|
||||||
|
| Empty state dashboard | `/create` conversion from dashboard | PostHog → Paths |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What not to do right now
|
||||||
|
|
||||||
|
- Don't build new QR code types — the product breadth is already sufficient for the current user base
|
||||||
|
- Don't chase Google Ads or paid social — organic signals are still too early to know which pages convert, and CAC will be high with a 10% retention rate
|
||||||
|
- Don't redesign the homepage visually — copy and CRO changes will outperform a design refresh at this stage
|
||||||
|
- Don't add more blog posts until the existing ones have cited sources and proper date signals (Sections 4.4 and 5.1)
|
||||||
Reference in New Issue
Block a user