CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sendgrid--mail

Twilio SendGrid NodeJS mail service for sending transactional and marketing emails with templates, attachments, and advanced delivery features.

Pending
Overview
Eval results
Files

templates-personalization.mddocs/

Templates and Personalization

Templates and personalization enable dynamic, customized email content for individual recipients. SendGrid supports both modern dynamic templates and legacy templates, with comprehensive personalization capabilities for per-recipient customization.

Capabilities

Dynamic Templates

Modern template system with handlebars-style syntax and rich data binding capabilities.

// Dynamic template message structure
const msg = {
  to: recipients,
  from: 'sender@example.com',
  templateId: 'd-1234567890abcdef', // Dynamic templates start with 'd-'
  dynamicTemplateData: templateData  // Object with template variables
};

// Template data can include any JSON-serializable data
interface DynamicTemplateData {
  [key: string]: any; // Strings, numbers, objects, arrays, booleans
}

Usage Examples:

// Basic dynamic template
const msg = {
  to: 'user@example.com',
  from: 'noreply@example.com',  
  templateId: 'd-abc123def456',
  dynamicTemplateData: {
    firstName: 'John',
    lastName: 'Doe',
    accountBalance: 1250.75,
    isVip: true,
    orders: [
      { id: '12345', total: 99.99, date: '2024-03-15' },
      { id: '67890', total: 149.50, date: '2024-03-10' }
    ]
  }
};

sgMail.send(msg);

// Complex template data with nested objects
const welcomeEmail = {
  to: 'newuser@example.com',
  from: 'welcome@example.com',
  templateId: 'd-welcome-series-1',
  dynamicTemplateData: {
    user: {
      firstName: 'Alice',
      lastName: 'Johnson',
      email: 'newuser@example.com',
      signupDate: '2024-03-15',
      preferences: {
        newsletter: true,
        notifications: false
      }
    },
    company: {
      name: 'Example Corp',
      supportUrl: 'https://example.com/support',
      unsubscribeUrl: 'https://example.com/unsubscribe'
    },
    features: [
      { name: 'Dashboard', available: true },
      { name: 'Analytics', available: false },
      { name: 'API Access', available: true }
    ]
  }
};

Legacy Templates

Traditional template system using substitution tags for simple variable replacement.

// Legacy template message structure
const msg = {
  to: recipients,
  from: 'sender@example.com',
  templateId: 'legacy-template-id', // Legacy templates don't start with 'd-'
  substitutions: substitutionData,  // Object mapping tags to values
  substitutionWrappers: ['::', '::'] // Optional custom wrappers
};

// Substitution format
interface Substitutions {
  [key: string]: string; // All values must be strings
}

Usage Examples:

// Basic legacy template
const msg = {
  to: 'user@example.com',
  from: 'noreply@example.com',
  templateId: 'password-reset-template',
  subject: 'Password Reset for ::firstName::',
  substitutions: {
    '::firstName::': 'John',
    '::resetUrl::': 'https://app.example.com/reset?token=abc123',
    '::expiryTime::': '24 hours'
  }
};

// Custom substitution wrappers
const customMsg = {
  to: 'user@example.com',
  from: 'noreply@example.com',
  templateId: 'custom-template',
  substitutions: {
    '[[username]]': 'johndoe',
    '[[activationCode]]': '123456'
  },
  substitutionWrappers: ['[[', ']]']
};

// Template sections for reusable content blocks
const sectionMsg = {
  to: 'user@example.com',
  from: 'noreply@example.com',
  templateId: 'newsletter-template',
  sections: {
    '::header::': '<h1>Monthly Newsletter</h1>',
    '::footer::': '<p>© 2024 Example Corp</p>',
    '::promotions::': '<div>Special offers this month!</div>'
  },
  substitutions: {
    '::firstName::': 'John',
    '::month::': 'March'
  }
};

Personalization Objects

Per-recipient customization allowing different template data, subjects, and recipients for each personalization.

// Personalization data structure
interface PersonalizationData {
  to: EmailData | EmailData[];                    // Required recipients
  from?: EmailData;                               // Override sender
  cc?: EmailData | EmailData[];                   // CC recipients
  bcc?: EmailData | EmailData[];                  // BCC recipients
  subject?: string;                               // Override subject
  headers?: { [key: string]: string };            // Custom headers
  substitutions?: { [key: string]: string };      // Legacy template data
  dynamicTemplateData?: { [key: string]: any };   // Dynamic template data
  customArgs?: { [key: string]: string };         // Custom tracking args
  sendAt?: number;                                // Scheduled send time
}

// Use personalizations in mail data
const msg = {
  from: 'sender@example.com',
  templateId: 'd-personalized-template',
  personalizations: [personalizationData]
};

Usage Examples:

// Multiple personalizations for different recipients
const msg = {
  from: 'newsletter@example.com',
  templateId: 'd-monthly-newsletter',
  personalizations: [
    {
      to: [{ email: 'premium@example.com', name: 'Premium User' }],
      subject: 'Premium Newsletter - Exclusive Content',
      dynamicTemplateData: {
        firstName: 'John',
        subscriptionType: 'Premium',
        exclusiveContent: true,
        featuredArticles: [
          { title: 'Advanced Features Guide', url: 'https://example.com/premium1' },
          { title: 'Investment Strategies', url: 'https://example.com/premium2' }
        ]
      }
    },
    {
      to: [{ email: 'basic@example.com', name: 'Basic User' }],
      subject: 'Monthly Newsletter - Latest Updates',
      dynamicTemplateData: {
        firstName: 'Jane',
        subscriptionType: 'Basic',
        exclusiveContent: false,
        featuredArticles: [
          { title: 'Getting Started Guide', url: 'https://example.com/basic1' },
          { title: 'Tips and Tricks', url: 'https://example.com/basic2' }
        ]
      }
    }
  ]
};

// Personalization with different send times
const scheduledMsg = {
  from: 'reminders@example.com',
  templateId: 'd-appointment-reminder',
  personalizations: [
    {
      to: ['patient1@example.com'],
      subject: 'Appointment Reminder - Tomorrow at 10 AM',
      sendAt: Math.floor(Date.now() / 1000) + 86400, // 24 hours from now
      dynamicTemplateData: {
        patientName: 'John Smith',
        appointmentDate: '2024-03-16',
        appointmentTime: '10:00 AM',
        doctorName: 'Dr. Johnson'
      }
    },
    {
      to: ['patient2@example.com'],
      subject: 'Appointment Reminder - Tomorrow at 2 PM', 
      sendAt: Math.floor(Date.now() / 1000) + 86400, // 24 hours from now
      dynamicTemplateData: {
        patientName: 'Jane Doe',
        appointmentDate: '2024-03-16',
        appointmentTime: '2:00 PM',
        doctorName: 'Dr. Williams'
      }
    }
  ]
};

Personalization Class

Use the Personalization class for programmatic construction of personalization objects.

const { Personalization } = require('@sendgrid/helpers').classes;

/**
 * Create a new personalization instance
 * @param data - Optional initial personalization data
 */
const personalization = new Personalization(data);

// Recipient management
personalization.setTo(to);
personalization.addTo(to);
personalization.setCc(cc);
personalization.addCc(cc);
personalization.setBcc(bcc);
personalization.addBcc(bcc);

// Content customization
personalization.setSubject(subject);
personalization.setSendAt(sendAt);
personalization.setDynamicTemplateData(data);
personalization.setSubstitutions(substitutions);

// Headers and tracking
personalization.setHeaders(headers);
personalization.addHeader(key, value);
personalization.setCustomArgs(customArgs);
personalization.addCustomArg(key, value);

// Substitution management
personalization.addSubstitution(key, value);
personalization.reverseMergeSubstitutions(substitutions);
personalization.setSubstitutionWrappers(wrappers);

// Convert to JSON
const jsonData = personalization.toJSON();

Usage Examples:

const { Personalization } = require('@sendgrid/helpers').classes;

// Build personalization programmatically
const personalization = new Personalization();

// Set recipients
personalization.setTo([
  { email: 'user1@example.com', name: 'User One' },
  { email: 'user2@example.com', name: 'User Two' }
]);
personalization.addCc('manager@example.com');

// Set custom subject
personalization.setSubject('Personal Message for Your Team');

// Add dynamic template data
personalization.setDynamicTemplateData({
  teamName: 'Development Team',
  projectStatus: 'On Track',
  deadline: '2024-04-01',
  completionPercentage: 75
});

// Add custom tracking
personalization.setCustomArgs({
  teamId: 'dev-team-1',
  projectId: 'proj-2024-q1'
});

// Add custom headers
personalization.addHeader('X-Team-Priority', 'High');

// Use in email
const msg = {
  from: 'pm@example.com',
  templateId: 'd-team-update-template',
  personalizations: [personalization]
};

Template Data Helpers

Utility functions for working with template data and substitutions.

// Global template data application (Mail class methods)
const mail = new Mail();

/**
 * Apply global substitutions to a personalization
 * @param personalization - Personalization instance to modify
 */
mail.applySubstitutions(personalization);

/**
 * Apply global dynamic template data to a personalization  
 * @param personalization - Personalization instance to modify
 */
mail.applyDynamicTemplateData(personalization);

// Substitution merging (Personalization class method)
/**
 * Merge substitutions while preserving existing ones
 * @param substitutions - New substitutions to merge
 */
personalization.reverseMergeSubstitutions(substitutions);

Usage Examples:

const { Mail, Personalization } = require('@sendgrid/helpers').classes;

// Global template data
const mail = new Mail();
mail.setDynamicTemplateData({
  companyName: 'Example Corp',
  supportEmail: 'support@example.com',
  unsubscribeUrl: 'https://example.com/unsubscribe'
});

// Individual personalization
const personalization = new Personalization();
personalization.setTo('user@example.com');
personalization.setDynamicTemplateData({
  firstName: 'John',
  accountBalance: 1500.00
});

// Apply global data to personalization
mail.applyDynamicTemplateData(personalization);
// Now personalization has both global and individual data

// Merge substitutions safely
personalization.setSubstitutions({
  '::firstName::': 'John',
  '::accountType::': 'Premium'
});

personalization.reverseMergeSubstitutions({
  '::firstName::': 'Johnny', // Won't override existing
  '::lastName::': 'Doe'      // Will be added
});
// Result: firstName stays 'John', lastName becomes 'Doe'

Template Best Practices

Dynamic Template Guidelines

  1. Use descriptive variable names: {{user.firstName}} instead of {{n}}
  2. Structure data logically: Group related data in objects
  3. Provide fallbacks: Use handlebars helpers for missing data
  4. Validate data types: Ensure template expects the right data types

Legacy Template Guidelines

  1. Consistent wrapper syntax: Stick to one wrapper style throughout
  2. Escape special characters: Be careful with HTML in substitutions
  3. String values only: All substitution values must be strings
  4. Use sections for reusable content: Define common blocks in sections

Personalization Strategy

  1. Segment recipients appropriately: Group similar recipients together
  2. Optimize for deliverability: Don't over-personalize to avoid spam filters
  3. Test with real data: Validate templates with actual production data
  4. Monitor performance: Track open and click rates by personalization type

Error Handling

// Handle template errors
sgMail.send(templateMsg)
  .catch(error => {
    if (error.response && error.response.body) {
      const { errors } = error.response.body;
      
      errors.forEach(err => {
        if (err.field === 'template_id') {
          console.error('Template not found or invalid:', err.message);
        } else if (err.field === 'personalizations') {
          console.error('Personalization error:', err.message);
        }
      });
    }
  });

Install with Tessl CLI

npx tessl i tessl/npm-sendgrid--mail

docs

advanced-delivery.md

attachments-content.md

email-service.md

index.md

message-construction.md

templates-personalization.md

tracking-analytics.md

tile.json