What You’ll Learn in This Module
Snippets are one of Cast’s most powerful features — reusable blocks of Liquid saved in your project and referenced by name in any narration. This module explains how snippets work, the critical rule that snippets always return strings, the best practices for designing snippet output, and the patterns for consuming snippet results safely in your narrations.
What Is a Snippet?
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.
Why snippets matter in Cast
- Reusability. Write once, use everywhere. A “CustomerSince” snippet can be referenced in welcome slides, QBR decks, and renewal reminders.
- Maintainability. Update the logic in one place and every narration that uses it gets the update automatically.
- Separation of concerns. Complex logic lives in snippets; narrations stay clean and readable.
- Generate Conditions. Snippets can be used in Cast’s Generate Conditions to control which contacts receive a Cast presentation at all.
How Snippets Work
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:
Thank you for being a customer for {{ CustomerSince }}.
When Cast generates the presentation, it:
- Runs the Liquid code inside the
CustomerSincesnippet - Takes whatever the snippet outputs (its rendered text)
- Inserts that text wherever
{{ CustomerSince }}appears
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:
{% if health_score > 80 %}true{% else %}false{% endif %}
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
❌ Will not work reliably:
{% if IsEMEA == true %}
{% if IsEMEA %} ← always truthy because any non-empty string is truthy
✅ Correct — compare string to string:
{% if IsEMEA == "true" %}
✅ Best practice — design snippets with “yes” / “no”:
Inside the snippet:
{% comment %} Snippet Name: IsEMEA {% endcomment %}
{% if EMEA_Countries contains country %}yes{% else %}no{% endif %}
In the narration:
{% if IsEMEA == "yes" %}
EMEA-specific content.
{% endif %}
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
If a snippet calculates a number and outputs it, the result is still a string:
{% comment %} Snippet: DaysUntilRenewal — outputs a number like "45" {% endcomment %}
{%- assign days = DaysUntilRenewal | strip | plus: 0 -%}
{% if days <= 30 %}
Your renewal is approaching — only {{ days }} days away.
{% endif %}
Without | plus: 0, comparing the string "45" with the number 30 using <= would be unreliable.
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:
{%- assign region = IsEMEA | strip -%}
{% if region == "yes" %}
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
1. Use “yes” / “no” for boolean snippets
{% comment %} Snippet: IsHighValue {% endcomment %}
{%- assign revenue = arr | default: 0 | plus: 0 -%}
{%- if revenue > 100000 -%}yes{%- else -%}no{%- endif -%}
Note the whitespace control ({%- -%}) — this prevents extra spaces in the output.
2. Use whitespace control throughout
Every tag inside a snippet should use {%- -%} to prevent stray whitespace from creeping into the output:
{% comment %} Snippet: GetTier {% endcomment %}
{%- assign score = health_score | default: 0 | plus: 0 -%}
{%- if score >= 80 -%}top{%- elsif score >= 60 -%}mid{%- else -%}low{%- endif -%}
3. Handle missing data inside the snippet
Don’t leave it to the narration to handle missing data for a snippet’s inputs. Use default inside the snippet itself:
{% comment %} Snippet: HealthTier {% endcomment %}
{%- assign score = health_score | default: 0 | plus: 0 -%}
{%- if score >= 80 -%}excellent
{%- elsif score >= 60 -%}solid
{%- else -%}needs attention
{%- endif -%}
4. Document inputs and outputs
Use a comment block at the top of every snippet:
{% 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 %}
Using Snippets in Narrations — Complete Pattern
Here’s the full safe pattern for consuming a snippet result:
For display:
Thank you for being a customer for {{ CustomerSince }}.
For yes/no logic:
{%- assign region = IsEMEA | strip -%}
{% if region == "yes" %}
EMEA-specific content.
{% endif %}
For text value logic:
{%- 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 %}
For numeric logic:
{%- assign days = DaysUntilRenewal | strip | plus: 0 -%}
{% if days <= 30 %}
Your renewal is in {{ days }} days — let's make sure everything is in order.
{% endif %}
Snippets in Generate Conditions
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:
{% if IsEligibleForQBR == "yes" %}
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.
Debugging Snippet Output
If a snippet isn’t behaving as expected, temporarily display its raw output to see exactly what it returns:
DEBUG: [{{ IsEMEA }}]
DEBUG: [{{ IsEMEA | strip }}]
DEBUG: length={{ IsEMEA | size }}
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.
Common Mistakes
❌ Testing a snippet as a bare condition:
{% if IsEMEA %}
EMEA content
{% endif %}
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:
{%- assign region = IsEMEA | strip -%}
{% if region == "yes" %}
EMEA content
{% endif %}
❌ Forgetting to strip before comparing:
{% if IsEMEA == "yes" %} ← might fail if snippet returns " yes "
✅ Assign and strip first:
{%- assign region = IsEMEA | strip -%}
{% if region == "yes" %}
❌ Assuming a snippet returns an empty string on error:
{% if MySnippet == "" %}
No result.
{% endif %}
A snippet might return nil, empty string, whitespace, or an error message depending on the situation.
✅ Use a defensive check:
{%- assign result = MySnippet | default: "" | strip -%}
{% if result == "" %}
No result.
{% endif %}
Try It Yourself
Exercise: Design a snippet called AccountRisk that:
- Takes
health_scoreanddays_since_loginas 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:** ```liquid {% 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 -%} ``` **The narration:** ```liquid {%- 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 %} ``` Key details: - Snippet uses `{%- -%}` everywhere to prevent whitespace - 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 valuesWhat’s Next
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:
- Snippet Library: https://school.cast.app/liquid/liquid-library.html
- Contact Variables: https://school.cast.app/fields-snippets-data-validation/contact-variables.html