Module 16: Snippets in Cast
What Is a Snippet?
Section titled “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
Section titled “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
Section titled “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:
{% raw %}Thank you for being a customer for {{ CustomerSince }}.{% endraw %}When Cast generates the presentation, it:
- Runs the Liquid code inside the
CustomerSincesnippet - 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 ({%- -%}) — this prevents extra spaces in the output.{% endraw %}
2. Use whitespace control throughout
Section titled “2. Use whitespace control throughout”{% raw %}Every tag inside a snippet should use {%- -%} 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 %}3. Handle missing data inside the snippet
Section titled “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:
{% 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 %}4. Document inputs and outputs
Section titled “4. Document inputs and outputs”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 in Generate Conditions
Section titled “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:
{% 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.
Debugging Snippet Output
Section titled “Debugging Snippet Output”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.
Common Mistakes
Section titled “Common Mistakes”❌ 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 %}Try It Yourself
Section titled “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:
{% 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 {%- -%} everywhere to prevent whitespace{% endraw %}
- Both inputs have
default: 0and| plus: 0for safe conversion - Output values are simple, unambiguous strings
- Narration uses
| stripbeforecase/when elsebranch catches unexpected values
What’s Next
Section titled “What’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