Posts
A feed of updates from email pros across EmailVersed.

about 1 month ago
How to Use AMPscript in SFMC: A Developer’s Guide
Salesforce Marketing Cloud (SFMC) is a powerhouse for enterprise messaging, but its true potential is unlocked through AMPscript. As a proprietary server-side scripting language, AMPscript allows you to inject personalized content, execute conditional logic, perform data lookups, and manipulate data within your emails right before they hit the subscriber's inbox. Whether you are rendering dynamic first names or pulling real-time inventory from a Data Extension (DE), mastering AMPscript is essential for any senior email developer. Understanding the Basics of AMPscript Syntax AMPscript blocks are enclosed within specific delimiters: %%[ for multi-line script blocks and %% for inline variables and functions. HTML %%[ /* Declare variables and set values */ VAR @firstName, @loyaltyStatus Set @firstName = AttributeValue("First_Name") Set @loyaltyStatus = AttributeValue("Loyalty_Tier") ]%% <p>Hello %%=v(@firstName)=%%, thank you for being a valued member!</p> Key Rules to Remember: Variable Declaration: Always declare your variables at the top of your script block using the VAR keyword and prefix them with an @ symbol. AttributeValue Function: Always use AttributeValue() instead of directly calling profile attributes (e.g., _subscriberkey or custom fields). It prevents rendering errors if a field happens to be missing or null for a specific send. The Print Function (v()): Use %%=v(@variable)=%% to output the evaluated value of a variable into your HTML markup. Step-by-Step Implementation: Conditional Logic One of the most common use cases for AMPscript is changing the content of an email based on subscriber data. Let's look at how to display custom messaging depending on a subscriber's loyalty tier. HTML %%[ VAR @tier, @discountCode Set @tier = AttributeValue("Loyalty_Tier") If @tier == "Gold" THEN Set @discountCode = "GOLD20OFF" Elseif @tier == "Silver" THEN Set @discountCode = "SILVER10OFF" Else Set @discountCode = "WELCOME5" EndIf ]%% <div class="promo-box"> <h3>Your Exclusive Reward</h3> <p>Use code <strong>%%=v(@discountCode)=%%</strong> at checkout to redeem your member discount.</p> </div> Advanced Power: Performing a LookupRows() Instead of overloading your sending Data Extension with fields that change frequently, you can pull related data dynamically from a separate Data Extension using LookupRows. HTML %%[ VAR @email, @rows, @rowCount, @i, @productName, @orderDate Set @email = EmailAddress_ /* Lookup orders from a separate relational DE called "Recent_Orders" */ Set @rows = LookupRows("Recent_Orders", "Subscriber_Email", @email) Set @rowCount = rowcount(@rows) If @rowCount > 0 THEN Output(v("<p>Here are your most recent orders:</p><ul>")) FOR @i = 1 to @rowCount DO VAR @row, @pName Set @row = row(@rows, @i) Set @pName = field(@row, "Product_Name") Output(v(Concat("<li>", @pName, "</li>"))) NEXT @i Output(v("</ul>")) Else Output(v("<p>Check out our latest arrivals today!</p>")) EndIf ]%% Best Practices for SFMC Developers Fail Gracefully: Always wrap personalization logic in fallback handlers. If a data lookup fails or returns null, make sure your subscriber sees a clean default value rather than blank spaces or system error codes. Test Thoroughly with Preview & Test: Never rely solely on visual inspection. Use the Test Subscriber feature in SFMC to cycle through multiple subscriber profiles with different data conditions to ensure your conditional logic and loops evaluate correctly. Keep Processing Times in Mind: Heavy database lookups (LookupRows, BuildRowsetFromString) can impact overall send-speed performance during large enterprise batch deployments. Optimize your data extensions with proper indexing when executing complex queries at scale.
View post →about 1 month ago
The five checks that catch 80% of bugs
Link destinations with UTMs resolved. Alt text on every image. Preheader not accidentally pulling the first line of body copy. Merge tags rendered with a real profile and an empty one. Unsubscribe link actually unsubscribing. That's it. Five minutes. It catches nearly everything embarrassing.
View post →about 1 month ago
Accessible email is not a separate email
Semantic tables with role=presentation, real text instead of image text, 4.5:1 contrast, descriptive link copy instead of 'click here', and a logical reading order. None of that requires a different design. It requires deciding it matters before the design is signed off.
View post →about 1 month ago
Your lifecycle team needs a developer
Every retention team I've seen plateau was blocked on engineering. Not strategy, not creative — someone to instrument the events. One embedded developer changed our shipping velocity more than doubling the marketing headcount would have.
View post →about 1 month ago
Run a holdout or stop claiming credit
Last-click attribution will happily tell you your winback flow drives seven figures. A 5% holdout will tell you the truth, and the truth is usually smaller and still worth doing. The first time I ran holdouts properly, two of our flows had no measurable incremental effect at all. We killed them and reinvested the time. That's the win — not the flattering number.
View post →about 1 month ago
Liquid loops that don't break on empty carts
Half the abandoned cart emails I inherit render a blank grey box when the item data is missing. Wrap the loop, check for the property, and always ship a fallback block. Test with a deliberately broken profile. If it looks fine with no data, you're done.
View post →about 1 month ago
Product feeds beat hand-built grids
If you're manually pasting six products into every campaign, you're spending four hours a week on something a feed does in zero. Set up the feed once, filter by collection, sort by whatever you care about. Campaign build time drops to the copy.
View post →about 1 month ago
The calendar meeting that fixed our QA
We moved from 'email is done when it's built' to a Friday walkthrough where merchandising, copy, and email all look at next week's sends in a live inbox on a phone. Caught a broken loyalty balance token twice in the first month. Twenty minutes a week.
View post →about 1 month ago
How we cut our send volume 30% and grew revenue
We were emailing our full list four times a week because that's what the calendar said. Engagement was sliding and nobody wanted to be the person who suggested sending less. We built an engagement-tiered send plan: highly engaged got everything, mid tier got two per week, dormant got one relevance-based send monthly. Total volume dropped about 30%. Revenue per send went up enough that total revenue grew. The hard part was politics, not setup.
View post →about 1 month ago
Write the PS first
The PS is the second most-read line in any email after the subject. Most people treat it as an afterthought. I write it first now. If I can't put the whole point of the email into one casual sentence at the bottom, the email doesn't have a point yet.
View post →about 1 month ago
Nobody reads your nurture sequence in order
People skip emails, open number four before number two, and unsubscribe at odd moments. So every email has to stand alone. That means no 'as I mentioned last week', no cliffhangers that require the next send, and one complete idea per email. Sequences are a set of independent essays that happen to be scheduled.
View post →about 1 month ago
DMARC at p=none is not protection
Publishing a DMARC record and leaving it at p=none means you're collecting reports nobody reads. Move to quarantine within a quarter. Read the aggregate reports before you do, fix the legitimate sources that fail alignment, then tighten. It's a two-month project, not a two-minute DNS edit.
View post →about 1 month ago
'Our open rates dropped' is almost never a subject line problem
Nine times out of ten it's one of three things: you added a new IP or domain without warming it, you started mailing a segment that's been dormant for a year, or your Apple MPP numbers shifted and your baseline was never real. Check Google Postmaster first. If domain reputation moved, your creative is not the issue.
View post →about 1 month ago
A handoff file dev actually likes
Name your layers. Flatten nothing. Include hex values, font stacks with fallbacks, and the exact padding in pixels. Export images at 2x. Mark which blocks are repeatable. It takes fifteen extra minutes and saves three rounds of revisions.
View post →about 1 month ago
Design for the 320px case first
Over 70% of the emails I design get opened on a phone, usually in a hallway, usually one-handed. So I lay out mobile first and let desktop be the easy version. Practical rules: 16px body minimum, 44px tap targets, one column unless there's a real reason, and never put critical copy inside an image.
View post →about 1 month ago
Most migrations fail on the data, not the templates
Everyone budgets time for rebuilding emails. Almost nobody budgets time for reconciling the event schema. Before you touch a single template: list every event and attribute your current ESP receives, find out which ones are actually referenced in live messaging, and kill the rest. I have never done a migration where fewer than 40% of tracked attributes were dead weight.
View post →about 1 month ago
One canvas, not eleven
A client had 11 separate onboarding canvases split by country. Same logic, same copy, different translations. Collapsed to one canvas with Liquid-based localization and a single entry rule. Maintenance went from a half-day per change to twenty minutes.
View post →about 1 month ago
Modular templates beat bespoke builds
A client asked me to build 14 one-off emails last quarter. I built 9 modules instead and their team assembled all 14 themselves, plus 30 more since. The upfront cost is maybe 2x a single email. The payback is every email after that.
View post →about 1 month ago
The dark mode checklist I actually use
Dark mode isn't one problem, it's four. Logos that vanish, text that inverts halfway, buttons that lose their fill, and images with white backgrounds sitting on a dark canvas. Fixes in order of impact: use PNGs with a subtle stroke or padding on logos, never rely on pure #FFFFFF or #000000 for text, set background colors on the td and not just the table, and use the color-scheme meta plus prefers-color-scheme media query for Apple Mail and iOS. Outlook.com will still ignore most of it. Design for that, not around it.
View post →
about 1 month ago
Stop A/B testing subject lines
If your list is under 50k, subject line tests are mostly noise. You'll need thousands of opens per variant to detect anything below a 15% lift, and almost nothing you test moves the needle that much. Test the things with real variance instead: send timing, offer structure, whether the email has one CTA or five, plain text vs designed. Those produce differences you can actually see.
View post →
about 1 month ago
Your welcome flow is too short
Most welcome flows I audit are three emails long and stop the moment someone buys. That's leaving money on the table. The first 30 days is the only window where someone actually wants to hear from you. Use it. Teach them something, show them the product in context, introduce a person — then ask for the second purchase. My default structure is 6 emails over 21 days with a branch at email 3 based on purchase behavior. Non-buyers get social proof and objection handling. Buyers get education and cross-sell. Same flow, two very different conversations.
View post →