> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hooked.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Personalization

> Create highly personalized videos that resonate with each viewer

## Overview

Personalization is the key to creating engaging videos that connect with your audience. Hooked's template system allows you to dynamically replace variables to create unique content for each recipient.

## Variable Basics

### Defining Variables in Templates

Variables are placeholders in your script surrounded by double curly braces:

```
Hi {{name}}, welcome to {{company}}!
```

### Variable Replacement

When generating from a template, provide values for each variable:

```javascript theme={null}
{
  "variables": [
    { "key": "name", "value": "Sarah" },
    { "key": "company", "value": "TechCorp" }
  ]
}
```

**Result:** `"Hi Sarah, welcome to TechCorp!"`

## Types of Personalization

### 1. Basic Information

<CodeGroup>
  ```javascript Name & Company theme={null}
  {
    "name": "John Smith",
    "company": "Acme Corp",
    "role": "CEO"
  }
  ```

  ```javascript Location theme={null}
  {
    "city": "San Francisco",
    "country": "United States",
    "timezone": "PST"
  }
  ```

  ```javascript Contact Info theme={null}
  {
    "email": "john@acme.com",
    "phone": "+1-555-0123"
  }
  ```
</CodeGroup>

### 2. Metrics & Data

```javascript theme={null}
// Personalized metrics
{
  "name": "Sarah",
  "metric_value": "30%",
  "metric_name": "productivity increase",
  "time_saved": "10 hours per week",
  "roi": "$50,000 annually"
}
```

**Script:**

```
Hi {{name}}! Companies like yours see a {{metric_value}} {{metric_name}},
saving {{time_saved}} and generating {{roi}} in additional revenue.
```

### 3. Conditional Content

While Hooked doesn't support conditional logic in templates directly, you can prepare the script before sending:

```javascript theme={null}
function prepareScript(template, data) {
  let script = template;
  
  // Replace variables
  Object.entries(data).forEach(([key, value]) => {
    script = script.replace(new RegExp(`{{${key}}}`, 'g'), value);
  });
  
  return script;
}

// Different scripts based on user segment
const templates = {
  enterprise: "Hi {{name}}! As an enterprise customer, you get {{feature}}...",
  startup: "Hi {{name}}! Perfect for startups like {{company}}...",
  individual: "Hi {{name}}! Great for individuals looking to {{goal}}..."
};

const script = prepareScript(
  templates[user.segment],
  { name: user.name, company: user.company }
);
```

### 4. Industry-Specific

```javascript theme={null}
// SaaS Example
{
  "name": "Mike",
  "product_name": "Analytics Pro",
  "feature_1": "real-time dashboards",
  "feature_2": "custom reports",
  "feature_3": "API access",
  "trial_days": "14"
}

// E-commerce Example
{
  "name": "Emma",
  "product_name": "Wireless Headphones",
  "discount": "20%",
  "price": "$79",
  "shipping": "free",
  "delivery_date": "Friday"
}

// Real Estate Example
{
  "name": "David",
  "property_address": "123 Oak Street",
  "bedrooms": "3",
  "bathrooms": "2",
  "price": "$450,000",
  "square_feet": "2,100"
}
```

## Advanced Personalization Strategies

### Multi-Scene Personalization

Different variables for each scene:

```javascript theme={null}
{
  "type": "class",
  "templateId": "template_123",
  "scenes": [
    {
      "script": "Hi {{name}}, I'm {{agent_name}} from {{company}}.",
      "variables": [
        { "key": "name", "value": "Sarah" },
        { "key": "agent_name", "value": "Jennifer" },
        { "key": "company", "value": "RealtyPro" }
      ]
    },
    {
      "script": "I found {{property_count}} properties that match your criteria in {{location}}.",
      "variables": [
        { "key": "property_count", "value": "5" },
        { "key": "location", "value": "downtown" }
      ]
    },
    {
      "script": "The top property at {{address}} is {{price}} with {{beds}} bedrooms.",
      "variables": [
        { "key": "address", "value": "123 Main St" },
        { "key": "price", "value": "$550,000" },
        { "key": "beds", "value": "3" }
      ]
    }
  ]
}
```

### Dynamic Content Selection

```javascript theme={null}
// Prepare personalized content based on user data
function personalizeContent(user, products) {
  // Select relevant products
  const recommended = products
    .filter(p => p.category === user.interests[0])
    .slice(0, 3);
  
  // Build variables
  const variables = {
    name: user.name,
    interest: user.interests[0],
    product_1: recommended[0].name,
    price_1: recommended[0].price,
    product_2: recommended[1].name,
    price_2: recommended[1].price,
    product_3: recommended[2].name,
    price_3: recommended[2].price
  };
  
  return variables;
}

const content = personalizeContent(user, availableProducts);

// Generate video
await api.generateFromTemplate('product_showcase', content);
```

### Integration with CRM Data

```javascript theme={null}
import { CRMClient } from './crm';

async function generatePersonalizedVideo(contactId) {
  const crm = new CRMClient(process.env.CRM_API_KEY);
  
  // Fetch contact data
  const contact = await crm.getContact(contactId);
  const deals = await crm.getDeals(contactId);
  const activities = await crm.getActivities(contactId);
  
  // Calculate personalized metrics
  const totalValue = deals.reduce((sum, d) => sum + d.amount, 0);
  const lastInteraction = activities[0]?.date || 'never';
  const engagement = activities.length;
  
  // Prepare variables
  const variables = {
    name: contact.firstName,
    company: contact.company,
    total_value: formatCurrency(totalValue),
    open_deals: deals.filter(d => d.status === 'open').length,
    last_interaction: formatDate(lastInteraction),
    engagement_level: engagement > 10 ? 'high' : 'moderate'
  };
  
  // Generate video
  return await api.generateFromTemplate(
    'sales_followup_template',
    variables,
    {
      webhook: `https://mysite.com/webhook?contactId=${contactId}`
    }
  );
}
```

### A/B Testing with Personalization

```javascript theme={null}
// Test different personalization strategies
const variants = {
  A: {
    greeting: "Hi {{name}}",
    value_prop: "save {{time}} per week",
    cta: "Start your free trial"
  },
  B: {
    greeting: "Hey {{name}}",
    value_prop: "boost productivity by {{percentage}}",
    cta: "Get started now"
  }
};

async function generateWithVariant(recipient, variant) {
  const template = variant === 'A' ? variants.A : variants.B;
  
  const variables = {
    name: recipient.name,
    time: "5 hours",
    percentage: "30%"
  };
  
  const script = Object.entries(template)
    .reduce((s, [key, tpl]) => {
      return s.replace(`{{${key}}}`, tpl);
    }, originalScript);
  
  return await api.createVideo({
    script,
    ...variables,
    metadata: { variant, recipientId: recipient.id }
  });
}

// Split recipients into A/B groups
recipients.forEach((recipient, index) => {
  const variant = index % 2 === 0 ? 'A' : 'B';
  generateWithVariant(recipient, variant);
});
```

## Personalization Best Practices

### 1. Natural Language

<Tip>Make personalization feel natural, not robotic</Tip>

```javascript theme={null}
// ❌ Awkward
"Hi {{name}}, you live in {{city}}, {{state}}, {{country}} and work at {{company}}."

// ✅ Natural
"Hi {{name}}! I noticed you're based in {{city}}. Many {{company}} teams in your area have seen great results with our platform."
```

### 2. Balance Personalization

<Warning>Too much personalization can feel creepy</Warning>

```javascript theme={null}
// ❌ Too much (creepy)
{
  name: "John",
  linkedin_url: "linkedin.com/in/john",
  last_visited: "January 15 at 3:42 PM",
  pages_viewed: "pricing page 3 times",
  ip_address: "192.168.1.1"
}

// ✅ Just right
{
  name: "John",
  company: "TechCorp",
  role: "Engineering Manager",
  interest: "DevOps solutions"
}
```

### 3. Provide Defaults

```javascript theme={null}
function safePersonalize(template, data, defaults = {}) {
  const variables = { ...defaults, ...data };
  
  let result = template;
  Object.entries(variables).forEach(([key, value]) => {
    const placeholder = new RegExp(`{{${key}}}`, 'g');
    result = result.replace(placeholder, value || defaults[key] || '');
  });
  
  return result;
}

// Usage with defaults
const script = safePersonalize(
  "Hi {{name}} from {{company}}!",
  { name: "Sarah" }, // company is missing
  { company: "your company" } // default fallback
);
// Result: "Hi Sarah from your company!"
```

### 4. Validate Data Quality

```javascript theme={null}
function validatePersonalizationData(data, required) {
  const errors = [];
  
  // Check required fields
  required.forEach(field => {
    if (!data[field]) {
      errors.push(`Missing required field: ${field}`);
    }
  });
  
  // Check data quality
  if (data.name && data.name.length < 2) {
    errors.push('Name too short');
  }
  
  if (data.email && !data.email.includes('@')) {
    errors.push('Invalid email format');
  }
  
  // Check for placeholder text
  const placeholders = ['test', 'example', 'demo', 'lorem'];
  Object.values(data).forEach(value => {
    if (placeholders.some(p => String(value).toLowerCase().includes(p))) {
      errors.push(`Placeholder text detected: ${value}`);
    }
  });
  
  return { valid: errors.length === 0, errors };
}

// Before generating
const validation = validatePersonalizationData(recipientData, ['name', 'company']);
if (!validation.valid) {
  console.error('Invalid data:', validation.errors);
  // Handle error
}
```

## Real-World Examples

### Sales Outreach

```javascript theme={null}
const salesTemplate = {
  name: "{{prospect_name}}",
  company: "{{company}}",
  mutual_connection: "{{connection_name}}",
  pain_point: "{{specific_challenge}}",
  solution: "{{your_solution}}",
  case_study: "{{similar_company}}",
  result: "{{quantified_result}}",
  cta: "{{call_to_action}}"
};

// Example data
const prospectData = {
  prospect_name: "Jennifer",
  company: "DataCorp",
  connection_name: "Mike Chen",
  specific_challenge: "scaling their data pipeline",
  your_solution: "automated ETL workflows",
  similar_company: "TechStart Inc",
  quantified_result: "reduced processing time by 60%",
  call_to_action: "Let's schedule a 15-minute demo"
};
```

### Customer Onboarding

```javascript theme={null}
const onboardingTemplate = {
  name: "{{customer_name}}",
  plan: "{{subscription_plan}}",
  feature_1: "{{key_feature_1}}",
  feature_2: "{{key_feature_2}}",
  feature_3: "{{key_feature_3}}",
  support_person: "{{account_manager}}",
  next_step: "{{onboarding_step}}"
};
```

### Event Invitations

```javascript theme={null}
const eventTemplate = {
  name: "{{attendee_name}}",
  event: "{{event_name}}",
  date: "{{event_date}}",
  time: "{{event_time}}",
  location: "{{venue}}",
  speaker: "{{keynote_speaker}}",
  topic: "{{session_topic}}",
  discount: "{{early_bird_code}}"
};
```

## Personalization Checklist

Before launching your personalized video campaign:

<Check>**Data Quality**</Check>

* [ ] All required variables are present
* [ ] No placeholder or test data
* [ ] Names are properly capitalized
* [ ] Emails are valid
* [ ] Phone numbers are formatted correctly

<Check>**Content**</Check>

* [ ] Variables sound natural in sentences
* [ ] No obvious template text
* [ ] Proper grammar and punctuation
* [ ] Appropriate tone for audience
* [ ] Clear call-to-action

<Check>**Technical**</Check>

* [ ] Template tested with sample data
* [ ] Webhook configured correctly
* [ ] Error handling in place
* [ ] Logging for failed generations

## Next Steps

<CardGroup cols={2}>
  <Card title="Bulk Generation" icon="layer-group" href="/guides/bulk-generation">
    Scale personalization to hundreds of recipients
  </Card>

  <Card title="Best Practices" icon="star" href="/guides/best-practices">
    Production-ready tips and patterns
  </Card>
</CardGroup>
