Marketing Site
The Marketing Site is the public-facing website for MyStoryFlow, handling user acquisition, content marketing, and conversion optimization.
Overview
The marketing site (/apps/marketing-site) is a Next.js 15 application featuring:
- 39+ SEO-optimized landing pages for targeted acquisition
- Notion-powered blog system with category and tag filtering
- Dynamic pricing page with waitlist integration
- Advanced SEO features including sitemaps and structured data
- Google Analytics and ConvertKit integration
Architecture
Framework: Next.js 15.3.2 with App Router
Styling: Tailwind CSS 4.x
Content Management: Notion API via @notionhq/client
Deployment: Vercel (port 3002 for local development)
Directory Structure
src/
βββ app/
β βββ (landing-pages)/ # 39 SEO-optimized landing pages
β βββ blog/ # Blog system with dynamic routes
β β βββ page.tsx # Blog listing with filters
β β βββ [slug]/ # Individual blog posts
β β βββ category/[category]/ # Category filtering
β β βββ tag/[tag]/ # Tag-based filtering
β βββ pricing/ # Pricing page components
β βββ components/ # Reusable UI components
β βββ api/ # API routes (waitlist, analytics)
β βββ layout.tsx # Root layout with analytics
βββ lib/
β βββ notion-blog.ts # Notion CMS integration
β βββ seo-metadata.ts # SEO configuration
β βββ email/ # Email templates
βββ config/
β βββ pricing.ts # Pricing plans configuration
β βββ features.ts # Feature flags
βββ data/ # Static JSON dataBlog System - Notion CMS Integration
Notion Database Schema
The blog uses a Notion database with the following properties:
- Title (title): Post title
- Slug (rich_text): URL slug
- Category (select): Blog category
- Status (select): Published/Draft status
- Published Date (date): Publication date
- SEO Title (rich_text): Custom SEO title
- Meta Description (rich_text): SEO description
- Featured Image (files): Blog post image
- Featured Image URL (url): Direct URL (prioritized for Backblaze B2)
- Tags (multi_select): Post tags
- Read Time (number): Estimated read time in minutes
- FAQ (rich_text): Q&A content
- Video URL (url): Optional video embed
- Podcast URL (url): Optional podcast audio
Key Functions
getBlogPosts(): Fetches published posts with optional filtering by category, search query, tags, and limit. Supports tag-based content discovery with OR logic.
getBlogPost(slug): Retrieves a single post by slug, converts Notion blocks to Markdown, extracts table of contents, and parses FAQ data. Filters out internal child pages (e.g., βDistribution Assetsβ).
convertToBlogPostCustom(): Transforms Notion posts into homepage blog highlights format.
Features
- Server-Side Rendering: Posts pre-rendered at build time with ISR
- Revalidation: Blog listing (1 hour), individual posts (24 hours)
- Static Generation:
generateStaticParams()for all blog posts - Markdown Rendering: Notion content converted to Markdown with
notion-to-md - Rich Content: Support for videos, podcasts, FAQs, and table of contents
- SEO: Dynamic metadata, OpenGraph, Twitter cards, VideoObject schema
- Related Posts: Tag and category-based recommendations
Blog Routes
/blog- Main listing with search and category filters/blog/[slug]- Individual blog post with TOC, multimedia, and related posts/blog/category/[category]- Category-filtered posts/blog/tag/[tag]- Tag-filtered posts/api/blog/by-tags- API endpoint for tag-based post retrieval
Landing Pages
39 targeted landing pages optimized for different audiences and use cases:
Categories
Occasions (12 pages):
- Motherβs Day, Fatherβs Day, Grandparents Day
- Birthdays, anniversaries, weddings
- Baby showers, retirements, memorials
- Family reunions, holidays
Relationships (8 pages):
- Grandparents, parents, children
- Siblings, couples, friends, mentors
Features (6 pages):
- Voice-to-text, audio recording, AI-assisted creation
- Collaborative storytelling, photo/video integration
- Custom printing
Themes (5 pages):
- Family history/genealogy, immigrant heritage
- Military veterans, life lessons, travel/adventure
App Features (3 pages):
- How it works, privacy/security, accessibility
SEO Implementation
Each landing page has:
- Custom metadata in
/lib/seo-metadata.ts(SEO_TEMPLATES) - Unique title, description, and keywords
- OpenGraph and Twitter card images
- Canonical URLs
- Schema.org markup
Pricing System
Plans
Three tiers configured in /config/pricing.ts:
-
Starter ($29/month, $23/month annual)
- 5 recordings/month, basic AI, 50 photos, 1 digital book
-
Family ($49/month, $39/month annual) - Most Popular
- Unlimited recordings, advanced AI, unlimited photos/videos
- 5 family members, 5 digital books, PDF export
-
Premium ($69/month, $55/month annual)
- Everything in Family plus unlimited members/books
- 2 printed books/year, advanced AI, priority support
Features
- Monthly/annual billing toggle with savings calculator
- Plan selection persists to localStorage (24-hour expiration)
- FAQ section with 8 common questions
- Integration with waitlist/signup flow
Lead Generation
Waitlist System
Components:
StoryFlowWaitlistForm.tsx- Main form (compact and full variants)- API routes:
/api/waitlist/(create, verify, update, check, stats, resend-otp) - Email templates in
/lib/email/waitlist.ts
Features:
- OTP verification via email
- Supabase database storage
- ConvertKit newsletter integration
- Waitlist stats tracking
Integration Points:
- Homepage (conditional based on feature flag)
- Blog sidebar and CTAs
- Landing pages
Analytics Integration
Google Analytics
- Tracking ID: G-KTFB021W5R
- Implemented via Next.js Script component
- Loaded with
afterInteractivestrategy
ConvertKit
- Modal script UID: dcffaa41e7
- Newsletter signup integration
- Loaded in root layout
Custom Package
- Uses
@mystoryflow/analyticsworkspace package - Health check endpoint:
/api/analytics/health - Config endpoint:
/api/analytics/config
SEO Features
Sitemap Generation
/app/sitemap.ts generates dynamic sitemaps including:
- Static pages (home, about, pricing, blog)
- 39 landing pages
- Dynamic blog category pages (from
blogCategoryDescriptions.json) - Dynamic blog tag pages (from
blogTagDescriptions.json) - Tools subdomain reference
Metadata
- Global metadata in
layout.tsx - Page-specific metadata via
generateMetadata() - SEO utility functions in
/lib/seo-metadata.ts - 20+ pre-configured templates for different page types
Structured Data
- VideoObject schema for blog posts with videos
- Organization and Article schemas
- OpenGraph and Twitter cards on all pages
Environment Configuration
Required environment variables:
# Notion CMS
NOTION_TOKEN=secret_xxx
NOTION_BLOG_DATABASE_ID=xxx
# Supabase (auth, database)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=xxx
SUPABASE_SERVICE_ROLE_KEY=xxx
# Stripe (payments)
STRIPE_SECRET_KEY=sk_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_xxx
# Backblaze B2 (media storage)
BACKBLAZE_KEY_ID=xxx
BACKBLAZE_APPLICATION_KEY=xxx
BACKBLAZE_BUCKET_ID=xxx
BACKBLAZE_BUCKET_NAME=xxx
# Site configuration
NEXT_PUBLIC_SITE_URL=https://www.mystoryflow.com
REVALIDATE_TOKEN=xxxNavigation
Public Header (PublicHeader.tsx):
- Home, About, Blog, Pricing
- For Grandparents, For Parents
- Login/Signup CTAs
- Mobile-responsive navigation
Footer (SharedFooter.tsx):
- Product, Company, Resources, Legal sections
- Social media links
- Copyright and branding
Performance Optimizations
- ISR: Incremental Static Regeneration for blog content
- Image Optimization: Next.js Image component with Backblaze B2 URLs
- Code Splitting: Dynamic imports for heavy components
- Font Optimization: Next.js font optimization with Inter
- Bundle Analysis: Production builds optimized for performance
Key Dependencies
@notionhq/client: ^3.1.3 - Notion API integrationnotion-to-md: ^3.1.9 - Markdown conversionnext: 15.3.2 - Frameworkreact: ^19.0.0 - UI libraryframer-motion: ^12.16.0 - Animationsreact-markdown: ^10.1.0 - Markdown renderingstripe: ^18.1.1 - Payment processing@supabase/supabase-js: ^2.49.8 - Database and auth
Testing
Test suite in __tests__/ directory:
- Auth flows (login, signup, forgot password)
- Gift purchase flow
- API route tests
- Component unit tests
Run tests: npm test
Development
npm run dev # Start dev server on port 3002
npm run build # Production build
npm run start # Start production server
npm run lint # ESLintCurrent Limitations
- A/B Testing: No dedicated A/B testing framework implemented (would require additional tooling)
- Analytics: Basic Google Analytics only, no advanced conversion tracking or user journey analysis
- Blog Authors: Static author info, not dynamic from Notion database
- Video Hosting: External URLs only, no native video hosting
- Newsletter: ConvertKit integration is basic, no advanced segmentation