Skip to content

Module 16: Snippets in Cast

A snippet is a named, reusable block of Liquid logic saved in Cast. Instead of copying the same 20 lines of Liquid into every narration that needs them, you write the logic once as a snippet and then reference it by name.

Excel analogy: Snippets are like named formulas or custom functions in Excel. Instead of re-typing a complex calculation in every cell that needs it, you define it once and call it by name. In Excel you might create a named range or a LAMBDA function; in Cast, you create a snippet.

  1. Reusability. Write once, use everywhere. A “CustomerSince” snippet can be referenced in welcome slides, QBR decks, and renewal reminders.
  2. Maintainability. Update the logic in one place and every narration that uses it gets the update automatically.
  3. Separation of concerns. Complex logic lives in snippets; narrations stay clean and readable.
  4. Generate Conditions. Snippets can be used in Cast’s Generate Conditions to control which contacts receive a Cast presentation at all.

You create a snippet in Cast with a name (like CustomerSince or IsEMEA) and Liquid code inside it. In your narration, you reference the snippet by name — it looks just like a variable:

{% raw %}
Thank you for being a customer for {{ CustomerSince }}.
{% endraw %}

When Cast generates the presentation, it:

  1. Runs the Liquid code inside the CustomerSince snippet
  2. Takes whatever the snippet outputs (its rendered text) {% raw %}3. Inserts that text wherever {{ CustomerSince }} appears{% endraw %}

The Critical Rule — Snippets Always Return Strings

Section titled “The Critical Rule — Snippets Always Return Strings”

No matter what logic is inside a snippet — math, conditions, date calculations — what comes out is always a text string. This is the most important thing to understand about snippets.

A snippet that contains:

{% raw %}
true{% else %}false
{% endraw %}

Does not return the boolean true or false. It returns the string "true" or "false" — text characters, not logical values.

Analogy: Think of a snippet as a tiny document generator. Whatever text appears in the final output of that document is what you get back — as text. Even if that text happens to spell out a number or the word “true,” it’s still text.

This has three important consequences for how you use snippet output:


Consequence 1 — Boolean Comparisons Must Use Strings

Section titled “Consequence 1 — Boolean Comparisons Must Use Strings”

Will not work reliably:

{% raw %}
← always truthy because any non-empty string is truthy
{% endraw %}

Correct — compare string to string:

{% raw %}
{% endraw %}

Best practice — design snippets with “yes” / “no”:

Inside the snippet:

{% raw %}
{% comment %} Snippet Name: IsEMEA {% endcomment %}
yes{% else %}no
{% endraw %}

In the narration:

{% raw %}
EMEA-specific content.
{% endraw %}

The "yes"/"no" pattern is unambiguous. Nobody will confuse the string "yes" with a boolean keyword, because yes has no special meaning in Liquid.


Consequence 2 — Numeric Snippet Output Must Be Converted

Section titled “Consequence 2 — Numeric Snippet Output Must Be Converted”

If a snippet calculates a number and outputs it, the result is still a string:

{% raw %}
{% comment %} Snippet: DaysUntilRenewal — outputs a number like "45" {% endcomment %}
{% endraw %}
{% raw %}
{%- assign days = DaysUntilRenewal | strip | plus: 0 -%}
Your renewal is approaching — only {{ days }} days away.
{% endraw %}

Without | plus: 0, comparing the string "45" with the number 30 using <= would be unreliable.


Consequence 3 — Snippet Output May Contain Whitespace

Section titled “Consequence 3 — Snippet Output May Contain Whitespace”

Depending on how a snippet is written, it may return leading or trailing spaces, newlines, or blank lines. Always strip before comparing:

{% raw %}
{%- assign region = IsEMEA | strip -%}
{% endraw %}

Without strip, if the snippet returns " yes " (with spaces), the comparison fails.

💡 Make it a habit: Every time you assign a snippet result to a variable for comparison, add | strip.


Designing Good Snippets — Best Practices

Section titled “Designing Good Snippets — Best Practices”

1. Use “yes” / “no” for boolean snippets

Section titled “1. Use “yes” / “no” for boolean snippets”
{% raw %}
{% comment %} Snippet: IsHighValue {% endcomment %}
{%- assign revenue = arr | default: 0 | plus: 0 -%}
{%- if revenue > 100000 -%}yes{%- else -%}no{%- endif -%}
{% endraw %}

{% raw %}Note the whitespace control (&#123;%- -%&#125;) — this prevents extra spaces in the output.{% endraw %}

{% raw %}Every tag inside a snippet should use &#123;%- -%&#125; to prevent stray whitespace from creeping into the output:{% endraw %}

{% raw %}
{% comment %} Snippet: GetTier {% endcomment %}
{%- assign score = health_score | default: 0 | plus: 0 -%}
{%- if score >= 80 -%}top{%- elsif score >= 60 -%}mid{%- else -%}low{%- endif -%}
{% endraw %}

Don’t leave it to the narration to handle missing data for a snippet’s inputs. Use default inside the snippet itself:

{% raw %}
{% comment %} Snippet: HealthTier {% endcomment %}
{%- assign score = health_score | default: 0 | plus: 0 -%}
{%- if score >= 80 -%}excellent
{%- elsif score >= 60 -%}solid
{%- else -%}needs attention
{%- endif -%}
{% endraw %}

Use a comment block at the top of every snippet:

{% raw %}
{% comment %}
Snippet Name: CustomerSince
Input: contract_start_date (ISO 8601 date string)
Output: e.g. "1 year and 6 days" or "Invalid Date Value"
{% endcomment %}
{% endraw %}

Using Snippets in Narrations — Complete Pattern

Section titled “Using Snippets in Narrations — Complete Pattern”

Here’s the full safe pattern for consuming a snippet result:

For display:

{% raw %}
Thank you for being a customer for {{ CustomerSince }}.
{% endraw %}

For yes/no logic:

{% raw %}
{%- assign region = IsEMEA | strip -%}
EMEA-specific content.
{% endraw %}

For text value logic:

{% raw %}
{%- assign health_tier = HealthTier | strip -%}
{% case health_tier %}
{% when "excellent" %}
Your account is thriving!
{% when "solid" %}
Your account shows great potential.
{% else %}
Let's discuss how to improve your account health.
{% endcase %}
{% endraw %}

For numeric logic:

{% raw %}
{%- assign days = DaysUntilRenewal | strip | plus: 0 -%}
Your renewal is in {{ days }} days — let's make sure everything is in order.
{% endraw %}

Snippets can also be used in Cast’s Generate Conditions to control which contacts receive a Cast presentation at all. For example, a snippet IsEligibleForQBR could return "yes" or "no", and the generate condition would check:

{% raw %}
{% endraw %}

Only contacts whose snippet returns "yes" would have a Cast presentation generated for them. This is a powerful way to segment your audience without maintaining separate campaigns.


If a snippet isn’t behaving as expected, temporarily display its raw output to see exactly what it returns:

{% raw %}
DEBUG: [{{ IsEMEA }}]
DEBUG: [{{ IsEMEA | strip }}]
DEBUG: length={{ IsEMEA | size }}
{% endraw %}

The square brackets make leading/trailing whitespace visible. The size filter tells you exactly how many characters the snippet returned. Remove these debug lines before publishing.


Testing a snippet as a bare condition:

{% raw %}
EMEA content
{% endraw %}

This is always true — even when the snippet returns "no" or "false". Any non-empty string is truthy in Liquid.

Always compare to a specific string value:

{% raw %}
{%- assign region = IsEMEA | strip -%}
EMEA content
{% endraw %}

Forgetting to strip before comparing:

{% raw %}
← might fail if snippet returns " yes "
{% endraw %}

Assign and strip first:

{% raw %}
{%- assign region = IsEMEA | strip -%}
{% endraw %}

Assuming a snippet returns an empty string on error:

{% raw %}
No result.
{% endraw %}

A snippet might return nil, empty string, whitespace, or an error message depending on the situation.

Use a defensive check:

{% raw %}
{%- assign result = MySnippet | default: "" | strip -%}
No result.
{% endraw %}

Exercise: Design a snippet called AccountRisk that:

  • Takes health_score and days_since_login as inputs (both may arrive as strings, both may be nil)
  • Returns "high" if health score is below 50 OR last login was more than 90 days ago
  • Returns "medium" if health score is between 50–79
  • Returns "low" for health scores 80+
  • Has proper defaults, conversion, and whitespace control

Then write the narration code that uses this snippet.

Click to reveal the answer

The snippet:

{% raw %}
{% comment %}
Snippet Name: AccountRisk
Inputs: health_score (string), days_since_login (string)
Output: "high", "medium", or "low"
{% endcomment %}
{%- assign score = health_score | default: 0 | plus: 0 -%}
{%- assign login_days = days_since_login | default: 0 | plus: 0 -%}
{%- if score < 50 or login_days > 90 -%}high
{%- elsif score < 80 -%}medium
{%- else -%}low
{%- endif -%}
{% endraw %}

The narration:

{% raw %}
{%- assign risk = AccountRisk | strip -%}
{% case risk %}
{% when "high" %}
We've identified some areas that need immediate attention.
Let's schedule a call this week.
{% when "medium" %}
Your account is performing steadily, with some opportunities
for improvement we'd like to discuss.
{% when "low" %}
Your account is in excellent shape. Let's focus on
growth and expansion opportunities.
{% else %}
Let's review your account status together.
{% endcase %}
{% endraw %}

Key details: {% raw %}- Snippet uses &#123;%- -%&#125; everywhere to prevent whitespace{% endraw %}

  • Both inputs have default: 0 and | plus: 0 for safe conversion
  • Output values are simple, unambiguous strings
  • Narration uses | strip before case/when
  • else branch catches unexpected values

In Module 17, you’ll see a complete real-world snippet in action — the CustomerSince pattern that calculates how long a customer has been with your company and expresses it in natural language.


📖 Official documentation: