SmashGL Reference

~8 min read

SmashGL (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

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:

  1. Either a SOURCE or DATA clause is present
  2. A SMASH clause is present
  3. A time phrase is resolvable — in GOAL or in a standalone WINDOW clause
  4. Every metric referenced in GOAL is available in the data binding
  5. <viz> in SMASH is one of metric, sparkline, chart, bar, table, gauge, badge
  6. Compound goals use either all AND or all OR — mixing is rejected

Warnings (query still runs):

Next Steps

Still need help?