Initial commit: Portfolio Website
Vollständige Next.js 15 Portfolio-Website mit: - Blog-System mit 100+ Artikeln - Supabase-Integration - Responsive Design mit Tailwind CSS - TypeScript-Konfiguration - Testing-Setup mit Vitest und Playwright Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,690 @@
|
||||
# Conversion Rate Optimization (CRO)
|
||||
|
||||
**Meta-Description:** Conversion Rate Optimization für SaaS. Landing Pages, User Funnels, Micro-Conversions und datengetriebene Optimierung.
|
||||
|
||||
**Keywords:** CRO, Conversion Rate, Landing Page, User Funnel, Micro-Conversions, UX Optimization, Growth Hacking
|
||||
|
||||
---
|
||||
|
||||
## Einführung
|
||||
|
||||
**Conversion Rate Optimization (CRO)** maximiert den Wert bestehenden Traffics. Statt mehr Besucher zu kaufen, werden bestehende Nutzer besser konvertiert. Dieser Guide zeigt systematische Ansätze für **Landing Pages**, **Funnels** und **Micro-Conversions**.
|
||||
|
||||
---
|
||||
|
||||
## CRO Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ CONVERSION OPTIMIZATION FUNNEL │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ TOFU (Top of Funnel): │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Awareness → Interest │ │
|
||||
│ │ ├── Landing Page Views │ │
|
||||
│ │ ├── Blog Post Reads │ │
|
||||
│ │ ├── Social Media Clicks │ │
|
||||
│ │ └── Target: Reduce Bounce Rate │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ MOFU (Middle of Funnel): │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Consideration → Intent │ │
|
||||
│ │ ├── Email Signups │ │
|
||||
│ │ ├── Free Trial Starts │ │
|
||||
│ │ ├── Demo Requests │ │
|
||||
│ │ └── Target: Increase Lead Quality │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ BOFU (Bottom of Funnel): │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Purchase → Retention │ │
|
||||
│ │ ├── Trial to Paid Conversion │ │
|
||||
│ │ ├── Checkout Completion │ │
|
||||
│ │ ├── Upsells / Cross-sells │ │
|
||||
│ │ └── Target: Maximize Revenue │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Key Metrics: │
|
||||
│ ├── Conversion Rate = Conversions / Visitors × 100 │
|
||||
│ ├── Micro-Conversion Rate (Email, Trial, etc.) │
|
||||
│ ├── Revenue per Visitor (RPV) │
|
||||
│ └── Customer Acquisition Cost (CAC) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Landing Page Optimization
|
||||
|
||||
```tsx
|
||||
// components/landing/OptimizedHero.tsx
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { track } from '@/lib/analytics';
|
||||
|
||||
interface HeroProps {
|
||||
headline: string;
|
||||
subheadline: string;
|
||||
ctaText: string;
|
||||
ctaUrl: string;
|
||||
trustBadges: string[];
|
||||
videoUrl?: string;
|
||||
}
|
||||
|
||||
export function OptimizedHero({
|
||||
headline,
|
||||
subheadline,
|
||||
ctaText,
|
||||
ctaUrl,
|
||||
trustBadges,
|
||||
videoUrl
|
||||
}: HeroProps) {
|
||||
const [videoPlaying, setVideoPlaying] = useState(false);
|
||||
|
||||
const handleCTAClick = () => {
|
||||
track('hero_cta_clicked', {
|
||||
headline,
|
||||
ctaText
|
||||
});
|
||||
};
|
||||
|
||||
const handleVideoPlay = () => {
|
||||
setVideoPlaying(true);
|
||||
track('hero_video_played');
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="relative py-20 lg:py-32">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="grid lg:grid-cols-2 gap-12 items-center">
|
||||
{/* Copy Side */}
|
||||
<div className="space-y-6">
|
||||
{/* Social Proof Mini */}
|
||||
<div className="flex items-center gap-2 text-sm text-gray-600">
|
||||
<span className="flex -space-x-2">
|
||||
{[1, 2, 3, 4, 5].map(i => (
|
||||
<img
|
||||
key={i}
|
||||
src={`/avatars/${i}.jpg`}
|
||||
alt=""
|
||||
className="w-8 h-8 rounded-full border-2 border-white"
|
||||
/>
|
||||
))}
|
||||
</span>
|
||||
<span>Join 10,000+ happy customers</span>
|
||||
</div>
|
||||
|
||||
{/* Headline - Max 6 words */}
|
||||
<h1 className="text-4xl lg:text-6xl font-bold leading-tight">
|
||||
{headline}
|
||||
</h1>
|
||||
|
||||
{/* Subheadline - Benefits focused */}
|
||||
<p className="text-xl text-gray-600 max-w-lg">
|
||||
{subheadline}
|
||||
</p>
|
||||
|
||||
{/* CTA Group */}
|
||||
<div className="flex flex-col sm:flex-row gap-4">
|
||||
<a
|
||||
href={ctaUrl}
|
||||
onClick={handleCTAClick}
|
||||
className="btn-primary text-lg px-8 py-4 text-center"
|
||||
>
|
||||
{ctaText}
|
||||
</a>
|
||||
<span className="text-sm text-gray-500 self-center">
|
||||
No credit card required
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Trust Badges */}
|
||||
<div className="flex flex-wrap gap-4 pt-4">
|
||||
{trustBadges.map((badge, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="flex items-center gap-2 text-sm text-gray-600"
|
||||
>
|
||||
<CheckIcon className="w-5 h-5 text-green-500" />
|
||||
{badge}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Visual Side */}
|
||||
<div className="relative">
|
||||
{videoUrl ? (
|
||||
<VideoPlayer
|
||||
url={videoUrl}
|
||||
onPlay={handleVideoPlay}
|
||||
playing={videoPlaying}
|
||||
/>
|
||||
) : (
|
||||
<img
|
||||
src="/hero-image.webp"
|
||||
alt="Product screenshot"
|
||||
className="rounded-lg shadow-2xl"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
// components/landing/SocialProof.tsx
|
||||
interface Testimonial {
|
||||
quote: string;
|
||||
author: string;
|
||||
role: string;
|
||||
company: string;
|
||||
avatar: string;
|
||||
logo: string;
|
||||
metric?: string;
|
||||
}
|
||||
|
||||
export function SocialProofSection({
|
||||
testimonials
|
||||
}: {
|
||||
testimonials: Testimonial[]
|
||||
}) {
|
||||
return (
|
||||
<section className="py-20 bg-gray-50">
|
||||
<div className="container mx-auto px-4">
|
||||
{/* Logos Bar */}
|
||||
<div className="text-center mb-12">
|
||||
<p className="text-sm text-gray-500 mb-6">
|
||||
Trusted by leading companies
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center items-center gap-8 opacity-60">
|
||||
{testimonials.map((t, i) => (
|
||||
<img
|
||||
key={i}
|
||||
src={t.logo}
|
||||
alt={t.company}
|
||||
className="h-8 grayscale hover:grayscale-0 transition"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Testimonials Grid */}
|
||||
<div className="grid md:grid-cols-3 gap-8">
|
||||
{testimonials.map((testimonial, i) => (
|
||||
<TestimonialCard key={i} {...testimonial} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Aggregate Stats */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 mt-16 text-center">
|
||||
<Stat value="10,000+" label="Active Users" />
|
||||
<Stat value="99.9%" label="Uptime" />
|
||||
<Stat value="4.9/5" label="Customer Rating" />
|
||||
<Stat value="24/7" label="Support" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function TestimonialCard({
|
||||
quote,
|
||||
author,
|
||||
role,
|
||||
company,
|
||||
avatar,
|
||||
metric
|
||||
}: Testimonial) {
|
||||
return (
|
||||
<div className="bg-white p-6 rounded-xl shadow-sm">
|
||||
{metric && (
|
||||
<div className="text-3xl font-bold text-blue-600 mb-4">
|
||||
{metric}
|
||||
</div>
|
||||
)}
|
||||
<blockquote className="text-gray-700 mb-4">
|
||||
"{quote}"
|
||||
</blockquote>
|
||||
<div className="flex items-center gap-3">
|
||||
<img
|
||||
src={avatar}
|
||||
alt={author}
|
||||
className="w-12 h-12 rounded-full"
|
||||
/>
|
||||
<div>
|
||||
<div className="font-semibold">{author}</div>
|
||||
<div className="text-sm text-gray-500">{role}, {company}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Funnel Tracking
|
||||
|
||||
```typescript
|
||||
// lib/cro/funnel.ts
|
||||
export interface FunnelStep {
|
||||
id: string;
|
||||
name: string;
|
||||
pagePattern: string | RegExp;
|
||||
requiredEvents?: string[];
|
||||
}
|
||||
|
||||
export interface FunnelConfig {
|
||||
id: string;
|
||||
name: string;
|
||||
steps: FunnelStep[];
|
||||
}
|
||||
|
||||
export const signupFunnel: FunnelConfig = {
|
||||
id: 'signup',
|
||||
name: 'Signup Funnel',
|
||||
steps: [
|
||||
{ id: 'landing', name: 'Landing Page', pagePattern: '/' },
|
||||
{ id: 'pricing', name: 'Pricing Page', pagePattern: '/pricing' },
|
||||
{ id: 'signup-start', name: 'Signup Started', pagePattern: '/signup', requiredEvents: ['signup_form_viewed'] },
|
||||
{ id: 'signup-complete', name: 'Signup Complete', pagePattern: '/welcome', requiredEvents: ['signup_completed'] },
|
||||
{ id: 'onboarding', name: 'Onboarding', pagePattern: '/onboarding' },
|
||||
{ id: 'activated', name: 'Activated', pagePattern: '/dashboard', requiredEvents: ['first_action_completed'] }
|
||||
]
|
||||
};
|
||||
|
||||
// Funnel Analytics
|
||||
export async function getFunnelAnalytics(
|
||||
funnelId: string,
|
||||
startDate: Date,
|
||||
endDate: Date
|
||||
): Promise<FunnelAnalytics> {
|
||||
const funnel = funnels.get(funnelId);
|
||||
if (!funnel) throw new Error(`Funnel ${funnelId} not found`);
|
||||
|
||||
const stepData = await Promise.all(
|
||||
funnel.steps.map(async (step, index) => {
|
||||
const count = await getStepCount(step, startDate, endDate);
|
||||
const previousCount = index > 0
|
||||
? await getStepCount(funnel.steps[index - 1], startDate, endDate)
|
||||
: count;
|
||||
|
||||
return {
|
||||
step: step.name,
|
||||
count,
|
||||
conversionRate: previousCount > 0 ? (count / previousCount) * 100 : 100,
|
||||
dropoffRate: previousCount > 0 ? ((previousCount - count) / previousCount) * 100 : 0
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
const overallConversion = stepData[0].count > 0
|
||||
? (stepData[stepData.length - 1].count / stepData[0].count) * 100
|
||||
: 0;
|
||||
|
||||
return {
|
||||
funnel: funnel.name,
|
||||
period: { start: startDate, end: endDate },
|
||||
steps: stepData,
|
||||
overallConversion
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
// components/analytics/FunnelVisualization.tsx
|
||||
'use client';
|
||||
|
||||
interface FunnelStep {
|
||||
step: string;
|
||||
count: number;
|
||||
conversionRate: number;
|
||||
dropoffRate: number;
|
||||
}
|
||||
|
||||
export function FunnelVisualization({ steps }: { steps: FunnelStep[] }) {
|
||||
const maxCount = Math.max(...steps.map(s => s.count));
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{steps.map((step, index) => {
|
||||
const width = (step.count / maxCount) * 100;
|
||||
const isLastStep = index === steps.length - 1;
|
||||
|
||||
return (
|
||||
<div key={step.step} className="relative">
|
||||
{/* Step Bar */}
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-32 text-sm font-medium">{step.step}</div>
|
||||
<div className="flex-1 h-12 bg-gray-100 rounded-lg overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-blue-500 flex items-center justify-end px-4 transition-all"
|
||||
style={{ width: `${width}%` }}
|
||||
>
|
||||
<span className="text-white font-semibold">
|
||||
{step.count.toLocaleString()}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-20 text-right">
|
||||
<span className={`text-sm font-medium ${
|
||||
step.conversionRate >= 50 ? 'text-green-600' : 'text-red-600'
|
||||
}`}>
|
||||
{step.conversionRate.toFixed(1)}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Dropoff Indicator */}
|
||||
{!isLastStep && step.dropoffRate > 0 && (
|
||||
<div className="ml-32 pl-4 py-2 text-sm text-red-500">
|
||||
↳ {step.dropoffRate.toFixed(1)}% dropoff ({Math.round(step.count * step.dropoffRate / 100).toLocaleString()} users)
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Micro-Conversions
|
||||
|
||||
```typescript
|
||||
// lib/cro/micro-conversions.ts
|
||||
export const microConversions = {
|
||||
engagement: [
|
||||
{ id: 'scroll_depth_50', name: 'Scrolled 50%', weight: 1 },
|
||||
{ id: 'scroll_depth_90', name: 'Scrolled 90%', weight: 2 },
|
||||
{ id: 'time_on_page_60s', name: '60s on page', weight: 2 },
|
||||
{ id: 'video_played', name: 'Video Played', weight: 3 },
|
||||
{ id: 'video_completed', name: 'Video Completed', weight: 5 }
|
||||
],
|
||||
intent: [
|
||||
{ id: 'pricing_viewed', name: 'Viewed Pricing', weight: 5 },
|
||||
{ id: 'feature_comparison', name: 'Compared Features', weight: 4 },
|
||||
{ id: 'faq_expanded', name: 'Expanded FAQ', weight: 2 },
|
||||
{ id: 'live_chat_started', name: 'Started Live Chat', weight: 8 }
|
||||
],
|
||||
lead: [
|
||||
{ id: 'email_captured', name: 'Email Signup', weight: 10 },
|
||||
{ id: 'demo_requested', name: 'Demo Request', weight: 15 },
|
||||
{ id: 'trial_started', name: 'Trial Started', weight: 20 }
|
||||
]
|
||||
};
|
||||
|
||||
// Calculate Lead Score
|
||||
export function calculateLeadScore(events: string[]): number {
|
||||
let score = 0;
|
||||
|
||||
Object.values(microConversions).flat().forEach(conversion => {
|
||||
if (events.includes(conversion.id)) {
|
||||
score += conversion.weight;
|
||||
}
|
||||
});
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
// hooks/useMicroConversions.ts
|
||||
'use client';
|
||||
|
||||
import { useEffect, useCallback } from 'react';
|
||||
import { track } from '@/lib/analytics';
|
||||
|
||||
export function useMicroConversions() {
|
||||
// Scroll Depth Tracking
|
||||
useEffect(() => {
|
||||
let maxScroll = 0;
|
||||
const milestones = [25, 50, 75, 90];
|
||||
const triggered = new Set<number>();
|
||||
|
||||
const handleScroll = () => {
|
||||
const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
|
||||
const scrollPercent = Math.round((window.scrollY / scrollHeight) * 100);
|
||||
|
||||
if (scrollPercent > maxScroll) {
|
||||
maxScroll = scrollPercent;
|
||||
|
||||
milestones.forEach(milestone => {
|
||||
if (scrollPercent >= milestone && !triggered.has(milestone)) {
|
||||
triggered.add(milestone);
|
||||
track(`scroll_depth_${milestone}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
// Time on Page Tracking
|
||||
useEffect(() => {
|
||||
const milestones = [30, 60, 120, 300];
|
||||
let elapsed = 0;
|
||||
|
||||
const interval = setInterval(() => {
|
||||
elapsed += 1;
|
||||
|
||||
if (milestones.includes(elapsed)) {
|
||||
track(`time_on_page_${elapsed}s`);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
// Track specific actions
|
||||
const trackMicro = useCallback((eventId: string, metadata?: Record<string, unknown>) => {
|
||||
track(eventId, metadata);
|
||||
}, []);
|
||||
|
||||
return { trackMicro };
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Form Optimization
|
||||
|
||||
```tsx
|
||||
// components/forms/OptimizedSignupForm.tsx
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { z } from 'zod';
|
||||
import { track } from '@/lib/analytics';
|
||||
|
||||
const signupSchema = z.object({
|
||||
email: z.string().email('Please enter a valid email'),
|
||||
password: z.string().min(8, 'Password must be at least 8 characters'),
|
||||
name: z.string().min(2, 'Name is required')
|
||||
});
|
||||
|
||||
type SignupData = z.infer<typeof signupSchema>;
|
||||
|
||||
export function OptimizedSignupForm() {
|
||||
const [step, setStep] = useState(1);
|
||||
const [startTime] = useState(Date.now());
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors, isSubmitting },
|
||||
watch
|
||||
} = useForm<SignupData>({
|
||||
resolver: zodResolver(signupSchema),
|
||||
mode: 'onBlur'
|
||||
});
|
||||
|
||||
// Track form interactions
|
||||
useEffect(() => {
|
||||
track('signup_form_viewed');
|
||||
}, []);
|
||||
|
||||
const email = watch('email');
|
||||
|
||||
useEffect(() => {
|
||||
if (email && email.includes('@')) {
|
||||
track('signup_email_entered');
|
||||
}
|
||||
}, [email]);
|
||||
|
||||
const onSubmit = async (data: SignupData) => {
|
||||
const timeToComplete = Date.now() - startTime;
|
||||
|
||||
track('signup_form_submitted', {
|
||||
timeToComplete,
|
||||
step
|
||||
});
|
||||
|
||||
try {
|
||||
await createAccount(data);
|
||||
track('signup_completed', { timeToComplete });
|
||||
} catch (error) {
|
||||
track('signup_error', { error: (error as Error).message });
|
||||
}
|
||||
};
|
||||
|
||||
// Field focus tracking
|
||||
const trackFieldFocus = (field: string) => {
|
||||
track('form_field_focused', { field });
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
|
||||
{/* Progress Indicator */}
|
||||
<div className="flex gap-2 mb-6">
|
||||
{[1, 2, 3].map(s => (
|
||||
<div
|
||||
key={s}
|
||||
className={`h-1 flex-1 rounded ${
|
||||
s <= step ? 'bg-blue-600' : 'bg-gray-200'
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Step 1: Email */}
|
||||
{step >= 1 && (
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Work Email
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
{...register('email')}
|
||||
onFocus={() => trackFieldFocus('email')}
|
||||
className="w-full px-4 py-3 border rounded-lg focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="you@company.com"
|
||||
autoComplete="email"
|
||||
/>
|
||||
{errors.email && (
|
||||
<p className="text-red-500 text-sm mt-1">{errors.email.message}</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Step 2: Password */}
|
||||
{step >= 2 && (
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Create Password
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
{...register('password')}
|
||||
onFocus={() => trackFieldFocus('password')}
|
||||
className="w-full px-4 py-3 border rounded-lg"
|
||||
placeholder="8+ characters"
|
||||
/>
|
||||
{errors.password && (
|
||||
<p className="text-red-500 text-sm mt-1">{errors.password.message}</p>
|
||||
)}
|
||||
{/* Password Strength */}
|
||||
<PasswordStrengthMeter password={watch('password') || ''} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* CTA Button */}
|
||||
<button
|
||||
type={step < 2 ? 'button' : 'submit'}
|
||||
onClick={() => step < 2 && setStep(step + 1)}
|
||||
disabled={isSubmitting}
|
||||
className="w-full py-4 bg-blue-600 text-white rounded-lg font-semibold hover:bg-blue-700 disabled:opacity-50"
|
||||
>
|
||||
{isSubmitting ? 'Creating account...' : step < 2 ? 'Continue' : 'Create Free Account'}
|
||||
</button>
|
||||
|
||||
{/* Trust Signals */}
|
||||
<div className="flex items-center justify-center gap-4 text-sm text-gray-500">
|
||||
<span className="flex items-center gap-1">
|
||||
<LockIcon className="w-4 h-4" />
|
||||
Secure
|
||||
</span>
|
||||
<span>No credit card required</span>
|
||||
<span>Cancel anytime</span>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CRO Checklist
|
||||
|
||||
| Element | Best Practice |
|
||||
|---------|--------------|
|
||||
| **Headline** | Clear value proposition, max 6 words |
|
||||
| **CTA** | Action-oriented, contrasting color |
|
||||
| **Social Proof** | Numbers, logos, testimonials |
|
||||
| **Trust Signals** | Security badges, guarantees |
|
||||
| **Forms** | Progressive, minimal fields |
|
||||
| **Mobile** | Touch-friendly, fast loading |
|
||||
| **Urgency** | Scarcity, limited time (honest!) |
|
||||
| **Exit Intent** | Offer value, not desperation |
|
||||
|
||||
---
|
||||
|
||||
## Fazit
|
||||
|
||||
Conversion Rate Optimization erfordert:
|
||||
|
||||
1. **Datenanalyse**: Funnels und Micro-Conversions tracken
|
||||
2. **User Research**: Verstehen warum Nutzer konvertieren
|
||||
3. **Testing**: Systematisches A/B Testing
|
||||
4. **Iteration**: Kontinuierliche Verbesserung
|
||||
|
||||
Kleine Verbesserungen summieren sich zu großen Ergebnissen.
|
||||
|
||||
---
|
||||
|
||||
## Bildprompts
|
||||
|
||||
1. "Conversion funnel visualization, colorful stages with dropoff points"
|
||||
2. "Landing page wireframe with CRO annotations, best practices highlighted"
|
||||
3. "A/B test results dashboard, winner variant celebration"
|
||||
|
||||
---
|
||||
|
||||
## Quellen
|
||||
|
||||
- [CXL Conversion Optimization Guide](https://cxl.com/blog/conversion-optimization-guide/)
|
||||
- [Unbounce Landing Page Best Practices](https://unbounce.com/landing-page-articles/)
|
||||
- [Hotjar CRO Resources](https://www.hotjar.com/conversion-rate-optimization/)
|
||||
- [Neil Patel CRO Guide](https://neilpatel.com/blog/conversion-rate-optimization/)
|
||||
Reference in New Issue
Block a user