Developer guides

Build email marketing campaigns with Sanity and Klaviyo

Learn how to use Functions to stage and send email campaigns from Sanity through Klaviyo.

This guide explains how two Sanity Functions working together create and send marketing campaigns through Klaviyo, integrated with Sanity Connect for Shopify setup. This is the setup we use for the Sanity Swag store.

E-Commerce Not Required

With this guide you will:

  • Build a flow using Klaviyo Campaigns directly in the Sanity Studio.
  • Update Klaviyo HTML templates directly without opening Klaviyo.
  • Send Campaigns to your Klaviyo customers directly from the Sanity Studio with your own editorial workflows.

Prerequisites

Overview

The marketing campaign system consists of two main Sanity Functions that work in tandem:

  • marketing-campaign-create: Creates and updates marketing campaigns and email templates
  • marketing-campaign-send: Sends campaigns to subscribers

These functions automatically process content changes and integrate with Klaviyo's API for email marketing automation.

How to set up Klaviyo

Before using these functions, you need to set up your Klaviyo account:

  • Create a Klaviyo Account: Sign up at klaviyo.com and complete account verification
  • Create a List
    • Navigate to Audience → Lists & Segments in your Klaviyo dashboard
    • Create a new list (e.g., "Newsletter Subscribers")
    • Take note the List ID from the URL or in list settings (you'll need this later)
  • Generate an API Key: Go to Account → Settings → API Keys- Create a new Private API key with the following scopes:
    • campaigns:read
    • campaigns:write
    • templates:read
    • templates:write
  • Copy the API key for environment configuration

Sanity Connect for Shopify (optional)

These functions work with content synced from Shopify via Sanity Connect for Shopify. The system expects:

  • Products synced from Shopify as shopify.product documents
  • Emails created in Sanity that reference these products
  • Marketing campaigns that can be created from email content

Implementation

Extend your Sanity Studio

We'll be creating 2 new content types for our studio, post and marketingCampaign. The post content type resembles something like a typical post and you could easily repurpose existing content types to suit your needs. Our two functions below use these two content types and could be tweaked as needed.

Blueprints configuration

We're assuming you've gong through the setup above to create a blueprint file, we're using configuration code below but reconfigure as needed; the only quirk here is making sure you are setup for env variables with dotenv and we have to pass them into our functions with the env:key below.

You should also scaffold the function so that each are created running the following command:

Navigate to the root of the create function and use your prefered package manager to install:

And likewise navigate to the send function an ensure the @sanity/client is installed.

Set up the marketing campaign create function

File: functions/marketing-campaign-create/index.ts
Trigger: Document changes on post documents
Purpose: Automatically creates and updates Klaviyo campaigns and email templates when posts are created or modified.

Key features

  • Automatic Template Generation: Converts Sanity Portable Text content into an HTML email templates
  • Product Integration: Renders Shopify products within email templates
  • Campaign Management: Creates Klaviyo campaigns with proper audience targeting
  • Status Tracking: Updates post status throughout the process
  • Error Handling: Comprehensive error handling with console logs

Process flow

Document Event Trigger: Listens for changes to post documents- Determines operation type (create/update) based on document state

Template Generation:

  • Fetches post content including Portable Text body
  • Converts content to HTML using @portabletext/to-html
  • Renders Shopify products with pricing and images, generates both HTML and text versions

Klaviyo Integration:

  • Creates email template in Klaviyo, creates marketing campaign with audience targeting, links template to campaign message, and handles template updates for existing campaigns

Sanity Document Management

  • Creates marketingCampaign document
  • Links post to marketing campaign
  • Updates email status to ready-for-review

Environment variables required

Find the following information for your Klaviyo account and email list, and paste it into the environment file:

Add code to the create campaign function file

Replace the boilerplate code in the index.ts function file that you scaffolded with the following code:

Set up the campaign send function

File: functions/marketing-campaign-send/index.ts
Trigger: Document changes on marketingCampaign documents specifically toggling the status to ready to send
Purpose: Sends approved marketing campaigns to subscribers via Klaviyo.

Key Features

  • Campaign Validation: Ensures campaign is ready for sending
  • Status Management: Updates campaign and email status after sending
  • Error Handling: Handles Klaviyo API errors gracefully
  • Rate Limiting: Respects Klaviyo's API rate limits

Process Flow

Document Event Trigger

  • Listens for changes to marketingCampaign documents
  • Validates that campaign has the required Klaviyo campaign ID

Campaign Sending

  • Calls Klaviyo's send job API
  • Handles various error scenarios (rate limits, permissions, etc.)
  • Updates campaign status to sent

Status Updates

  • Updates marketing campaign document with send timestamp
  • Updates post status to sent
  • Creates success/error notifications

Add environment variables

Find the API key for your Klaviyo account and email list, and paste it into the environment file:

Add code to the send campaign function file

Test and deploy the functions

You should test if the functions run locally, and deploy them to production when you have validated that everything is correctly set up.

Usage guide

Once the functions are deployed, you test out the flow in the Studio.

Creating a Marketing Campaign

  • Create an Post in Sanity Studio - build an initial post/email in the Sanity studio, include copy/products/etc
  • Function Automatically Triggers
    - Creates Klaviyo template with rendered content
    - Creates Klaviyo campaign with audience targeting
    - Links post to marketing campaign
    - Updates post status to ready-for-review

Sending a Campaign

  • Update Marketing Campaign Status - When you're ready to send the campaign, go into the campaign that's ready and change the status to ready-to-send
  • Function Automatically Triggers
    - Sends campaign via Klaviyo API
    - Updates campaign status to `sent`
    - Updates post status to `sent`
    - Creates success notification

Why 2 Different Functions?

Troubleshooting

Common Issues

  • API Key Issues- Verify API key has correct permissions, check API key is not expired, ensure API key is properly set in environment variables
  • List ID Issues- Verify list exists in Klaviyo, check list ID is correct, ensure list has subscribers
  • Template Generation Issues- Check Portable Text content structure, verify product references are valid, test template rendering in Klaviyo preview
  • Campaign Sending Issues- Verify campaign is in correct status, check Klaviyo campaign settings, review rate limit status

Debugging Steps

  • Check Function Logs- Review console output for errors, look for specific error messages, check API response status codes
  • Verify Environment Variables- Ensure all required variables are set, check variable values are correct, test API key with Klaviyo directly
  • Test API Calls- Use Klaviyo's API documentation, test API calls manually, verify request/response format

Was this page helpful?