I am building an email in SFMC where I have some code executing (see below) in the preheader that decides what version of the email this contact should get. This is done using the contentblockbykey trick as explained here: AMPscript Variables in Preheader

From what I understand from documentation and the AMPscript Guide is that the preheader is executed first in the order of operations. So this would mean all variables that are set here should be available in the body and the subject as these are executed afterwards. However, when I try to reference the @contentblock and @onderwerp variables in the body they are empty and I get an error for having an empty value in a contentblockbykey function.

Does this mean all preheader AMPscript is "forgotten" after it has executed? (btw I know I can solve this by adding the code to the top of the template but this is problematic as there are many emails dependent on this, I don't want to touch that for several reasons.)

code in preheader

error message

Code that gets executed (in code snippet block)


SET @Emailadres = Email 
SET @ContractRows = LookupRows('Test_bron_indexering','Email',@Emailadres)
SET @RowCountContracten = RowCount(@ContractRows)
SET @GeenIndex = FALSE
SET @WelIndex = FALSE

IF @RowCountContracten  > 0 THEN 
    FOR @i = 1 to @RowCountContracten DO 
        SET @ContractRow = Row(@ContractRows,@i) 
        SET @Geindexeerd =  Field(@ContractRow,'Geindexeerd')

        IF (@Geindexeerd == FALSE) THEN 
             SET @GeenIndex = TRUE
        ELSEIF (@Geindexeerd == TRUE) THEN 
             SET @WelIndex = TRUE
    NEXT @i 

IF (@GeenIndex AND @WelIndex) THEN
    SET @onderwerp = "Subject for scenario 1"
    SET @preheader = "Preheader for scenario 1"
    SET @contentblock = "scenario1"

ELSEIF (@WelIndex AND NOT @GeenIndex) THEN
    SET @onderwerp = "Subject for scenario 2"
    SET @preheader = "Preheader for scenario 2"
    SET @contentblock = "scenario2"

ELSEIF (NOT @WelIndex AND @GeenIndex) THEN
    SET @onderwerp = "Subject for scenario 3"
    SET @preheader = "Preheader for scenario 3"
    SET @contentblock = "scenario3"

    RaiseError("No scenario match", TRUE)
  • Where's the output in your content block? You can't use it inline like that if it has no output. Commented Apr 14, 2022 at 13:24
  • The output is there in the production code, I edited a few things to make it more clear but forgot to include the output function. Edited the code now. Commented Apr 15, 2022 at 14:34

2 Answers 2


The issue you are facing is that, similar to the subjectline, preheader is set to process/render in a different environment. This environment will ingest from your 'email code' but will not egress anything that happened inside of it.

Basically, its like a cascade of waterfalls. The top 'feed' to it is your main variables from the template. This feeds the preheader waterfall, the subjectline waterfall, the email waterfall and the text email waterfall.

The feed starts in your template and goes until it hits the body tag. At this point, it then splits in two with one being the preheader waterfall and the other being the email waterfall. The preheader waterfall goes all the way to the bottom directly after the split, but the email hits a plateau that then forms the text email waterfall, which then hits a plateau that goes to the subjectline waterfall. This way, the stuff created in the template, the html email and the text email can all be sent forward to the subjectline, but the preheader stuff is completely separate.

Something like:

Beautiful Art

So although not exactly accurate, yes the values set in the preheader slot will 'disappear' in the sense they exist outside of the rest of the cascade. This is easily solved by either just using that slot to output or by just pushing all the preheader logic and display in the template above the body tag.

I do not know what your hesitance is to put the content in the template, but what you are asking for is not possible due to the way SFMC is set up to render/process your code.


First, don't do this:

SET @Emailadres = Email

Do this instead:

SET @Emailadres = AttributeValue("Email")
if not empty(@EmailAdres) then
  /* other code */
  RaiseError("Emailadres has no value",1)  

In the email body, preferably before the <html> tag, execute the content block:


(This template illustrates the content slots that I like to use. What I'm suggesting would go in the init block.)

Then in the preheader input box:

  • Thanks for your reply Adam. We ensure data hygiene in queries and with required fields so no need to check for empty email addresses. As I mention in my question, I know I can solve this in the template and go above the <html> but I don't want to touch the template for several reasons. Since the preheader executes first I'm wondering why this work around doesn't work. Commented Apr 15, 2022 at 14:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .