SmashGL Reference
~8 min readSmashGL (Smash Goal Language) is a portable, goal-first query language for configuring analytics dashboard cards. A SmashGL query declares what success looks like (the goal), where the data lives (the source), and how to display it (the presentation).
The Simple tab in the card editor writes SmashGL automatically. This reference is for users editing in the Code tab directly.
Quick Reference
GOAL <verb> <metric> [to|by] [<op>] <value>[<unit>] <time-phrase> [SOFT|HARD]
[AND|OR <verb> <metric> ...]
[COMPARE <mode>]
[TYPE cumulative | ratio | level]
[DIRECTION higher | lower]
[FORMAT percent | currency | number]
[SMOOTH rolling7 | rolling14 | rolling30 | ema7 | ema14]
[WINDOW <time-phrase>]
SOURCE <shopify.table.column> [AS <alias>] [, ...]
[WHERE <field> <op> <value> [AND ...]]
[GROUP BY <dimension>]
[ORDER BY <field> [ASC|DESC]]
[LIMIT <n>]
— OR —
DATA <alias> = <json-value>
[PREVIOUS <json-value>]
SMASH <viz> [WITH <flag>, <flag>, ...] [TITLED "<title>"]
Verbs: grow, reduce, hold, hit, cap (with synonyms) Time phrases: this week|month|quarter|year, last N days|weeks, over last N days|weeks, from <date> to <date>, since <date> Vizes: metric, sparkline, chart, bar, table, gauge, badge Flags: trend, forecast, alert, risk, gap
GOAL — What Success Looks Like
The GOAL clause says what you are trying to achieve.
GOAL <verb> <metric> [to|by] [<op>] <value>[<unit>] <time-phrase>
Examples:
GOAL hit revenue >= $50,000 this month
GOAL grow orders by +15% over last 30 days
GOAL reduce refund_rate to <= 2% this month
GOAL hold uptime >= 99.98% this month
GOAL cap ad_spend <= $5,000 this week
Verbs
| Verb | Direction | Typical use |
|---|---|---|
grow |
higher-is-better | Revenue, sessions, orders |
reduce |
lower-is-better | Refund rate, churn |
hold |
maintain | Pass/fail thresholds (uptime SLA, conversion floor) |
hit |
reach an absolute | Point-in-time targets (revenue ≥ $50K) |
cap |
enforce a ceiling | Budget caps (ad spend ≤ $5K) |
Each verb accepts synonyms: grow → increase, raise, boost, lift; reduce → decrease, lower, cut, minimize; hold → maintain, sustain, keep, ensure; hit → reach, achieve, target; cap → ceiling.
Values and units
| Token | Interpreted as |
|---|---|
50000 |
Plain number |
$50,000 |
Currency (store currency) |
99.98% |
Percent (0–100 scale) |
+15% |
Relative target: +15% vs comparison period |
-5% |
Relative target, negative direction |
Time phrases
| Phrase | Meaning |
|---|---|
this week |
Current calendar week |
this month |
First of current month → today |
this quarter |
Start of current quarter → today |
this year |
January 1 → today |
over last N days |
Rolling N-day window ending today |
last N days |
Same as above |
from <ISO-date> to <ISO-date> |
Fixed date range |
since <ISO-date> |
From the given date to today |
Commitment (SOFT / HARD)
GOAL grow revenue by +20% this month SOFT
HARD(default) — strict STATUS bandsSOFT— lenient bands; progress bar renders with a dashed border for aspirational/stretch goals
Compound goals
GOAL hit revenue >= $15,000 AND hit orders >= 300 this month
GOAL grow revenue by +20% OR hit gross_profit >= $20,000 this month
AND requires all conditions; OR requires any one. They cannot be mixed. The card shows a rollup badge (“1 of 2 goals met”).
SOURCE — Live Data Binding
SOURCE shopify.<table>.<column> [AS <alias>] [, ...]
The path is shopify.<table>.<column> — e.g. shopify.sales.net_sales. The alias after AS is used by the GOAL clause.
Multiple columns
The first column is the primary KPI (the hero number). Additional columns become secondary stats:
SOURCE shopify.sales.net_sales AS revenue,
shopify.sales.gross_sales,
shopify.sales.orders
Continuation clauses
SOURCE shopify.sales.gross_sales AS products
WHERE channel = "online_store"
GROUP BY product_title
ORDER BY gross_sales DESC
LIMIT 10
| Clause | Purpose |
|---|---|
WHERE <field> <op> <value> |
Filter rows |
GROUP BY <dimension> |
Categorical grouping — used by bar, table |
GROUP BY day (or week, month) |
Time-series grouping — required by sparkline and chart |
ORDER BY <field> [ASC\|DESC] |
Sort results |
LIMIT <n> |
Cap row count |
Available data
| Namespace | Columns |
|---|---|
shopify.sales |
net_sales, gross_sales, gross_profit, orders, net_items_sold, refund_rate |
shopify.sessions |
online_store_visitors, uptime_pct |
AOV — derived metric
When net_sales and orders are both in SOURCE, Average Order Value is automatically computed as net_sales / orders. Reference it as the alias aov:
SOURCE shopify.sales.net_sales AS aov, shopify.sales.orders
GOAL grow aov by +3% this month
DATA — Inline Static Data
DATA revenue = {"net_sales": 47300, "gross_sales": 50600, "orders": 847}
PREVIOUS {"net_sales": 41800, "gross_sales": 44200, "orders": 723}
Useful for demo cards, fixture cards, or one-off displays. PREVIOUS provides the comparison-period values.
Multi-row (bar charts):
DATA returns_total = [
{"period": "Week 1", "returns_total": 2650},
{"period": "Week 2", "returns_total": 2300},
{"period": "Week 3", "returns_total": 3100},
{"period": "Week 4", "returns_total": 1890}
]
SMASH — Presentation
SMASH <viz> [WITH <flag>[, <flag>]...] [TITLED "<title>"]
SHOW AS is accepted as a synonym: SHOW AS metric WITH alert TITLED "Revenue".
Visualization types
| Type | Description |
|---|---|
metric |
Large hero number with OKR goal block and vs-prior pill |
sparkline |
Hero number + delta pill + small trend line |
chart |
Full-width chart (alias for sparkline) |
bar |
Horizontal bar chart with optional goal line |
table |
Ranked rows |
gauge |
Arc / dial showing progress toward a goal |
badge |
Simple large-number display |
Flags
Without a WITH clause, all applicable flags are active by default. WITH enables explicit mode — only listed flags are active.
| Flag | Description | Requires |
|---|---|---|
trend |
vs-prior pill on metric/badge; trend line on sparkline/chart | day-level GROUP BY for trend line |
forecast |
Forward projection + dashed sparkline | GOAL + non-rolling window |
alert |
RAG pulse on card border keyed to goal status | GOAL |
risk |
At risk / On pace / Ahead indicator | GOAL + non-rolling window |
gap |
Gap to goal — value and time remnant | GOAL |
Custom ALERT colors:
SMASH metric WITH alert(#dc2626, #d97706, #16a34a) TITLED "Revenue vs Last Year"
WINDOW — Standalone Time Phrase
When no GOAL is present, the time phrase moves to a standalone WINDOW clause:
WINDOW last 90 days
SOURCE shopify.sales.gross_sales AS products
GROUP BY product_title
ORDER BY gross_sales DESC
LIMIT 10
SMASH table TITLED "Top Products"
COMPARE — Comparison Period
| Mode | Comparison period |
|---|---|
previousPeriod |
Equal-length window immediately before the current (default) |
previousYear |
Same calendar dates, 12 months earlier |
sameDayLastWeek |
Same dates, shifted back 7 days |
samePeriodLastYear |
Same named period last year (named windows only) |
samePeriodLastMonth |
Same named period last month (named windows only) |
For in-progress periods, the comparison is auto-truncated to match elapsed time — “this month vs last year” on the 13th compares the 1st–13th only.
TYPE / DIRECTION / FORMAT
TYPE cumulative | ratio | level
DIRECTION higher | lower
FORMAT percent | currency | number
| TYPE | Meaning |
|---|---|
cumulative |
Period total that grows over time (revenue, orders) |
ratio |
Running rate — already a finished value (uptime, conversion rate) |
level |
Snapshot at a point in time (inventory count) |
DIRECTION lower inverts attainment and flips the trend pill colour — green means the metric decreased (good). Inferred automatically for column names containing refund, return, churn, cost, bounce.
FORMAT percent shows 1.80%; currency prefixes the store currency symbol; number shows a plain count.
SMOOTH — Sparkline Smoothing
SMOOTH rolling7 | rolling14 | rolling30 | ema7 | ema14
Applies smoothing to the sparkline trend line only. Does not affect the headline KPI.
Complete Examples
Revenue — monthly target, vs. last year:
GOAL hit revenue >= $50,000 this month
COMPARE previousYear
SOURCE shopify.sales.net_sales AS revenue, shopify.sales.gross_sales
SMASH metric WITH alert TITLED "March Revenue"
Orders — rolling 30 days, grow 15%:
GOAL grow orders by +15% over last 30 days
SOURCE shopify.sales.orders AS orders
SMASH metric WITH trend, alert TITLED "Orders"
Top Products — last 90 days:
WINDOW last 90 days
SOURCE shopify.sales.gross_sales AS products
GROUP BY product_title
ORDER BY gross_sales DESC
LIMIT 10
SMASH table TITLED "Top Products (90d)"
Refund Rate — percent, lower is better:
GOAL reduce refund_rate to <= 2% this month
TYPE ratio
FORMAT percent
DIRECTION lower
SOURCE shopify.sales.refund_rate AS refund_rate
SMASH metric WITH trend, alert TITLED "Refund Rate"
Compound Goal — Revenue AND Orders:
GOAL hit revenue >= $15,000 AND hit orders >= 300 this month
SOURCE shopify.sales.net_sales AS revenue,
shopify.sales.orders AS orders
SMASH metric WITH alert, forecast TITLED "Monthly OKR"
BFCM — fixed date range:
GOAL hit revenue >= $25,000 from 2026-11-27 to 2026-11-30
SOURCE shopify.sales.net_sales AS revenue, shopify.sales.orders
SMASH metric WITH alert, forecast, gap TITLED "BFCM Revenue"
Sparkline with smoothing:
WINDOW over last 30 days
SMOOTH rolling7
SOURCE shopify.sales.net_sales AS revenue
GROUP BY day
ORDER BY day ASC
SMASH sparkline WITH trend TITLED "Revenue Trend"
Soft goal — aspirational sessions target:
GOAL grow sessions to >= 50000 this month SOFT
SOURCE shopify.sessions.online_store_visitors AS sessions
SMASH metric WITH alert TITLED "Sessions (Stretch)"
Validation Rules
A SmashGL document is valid when:
- Either a
SOURCEorDATAclause is present - A
SMASHclause is present - A time phrase is resolvable — in
GOALor in a standaloneWINDOWclause - Every metric referenced in
GOALis available in the data binding <viz>inSMASHis one ofmetric,sparkline,chart,bar,table,gauge,badge- Compound goals use either all
ANDor allOR— mixing is rejected
Warnings (query still runs):
forecast/riskwith a rolling window → ignoredtrendflag onsparkline/chartwithoutGROUP BY day→ trend line omittedTYPE ratio+forecast→ forecast renders as current value
Next Steps
Still need help?