Snippets
Minimal copy-paste blocks for flags, configs, kill switches, experiments and i18n.
Minimal copy-paste blocks, grouped by the registry taxonomy. These are the same leaves the docs get op returns.
release
release / flags
Evaluate the feature gate {{FLAG_KEY}} on a user-bound Client. Assumes
Shipeasy.configure ran at startup — see Installation.
Basic check
# construct once per callsite (cheap; binds the user + runs the attributes transform)
flags = Shipeasy::Client.new(current_user)
# get_flag(name, default: false)
# name — the gate key (required)
# default — returned ONLY when the value can't be resolved (client not ready /
# gate absent); a gate that evaluates to false returns false
if flags.get_flag("{{FLAG_KEY}}", default: false)
# ship it
endWhy it resolved that way — get_flag_detail
flags = Shipeasy::Client.new(current_user)
# returns a FlagDetail (.value, .reason); reason ∈ RULE_MATCH / DEFAULT / OFF /
# OVERRIDE / FLAG_NOT_FOUND / CLIENT_NOT_READY
detail = flags.get_flag_detail("{{FLAG_KEY}}")
logger.info("flag={{FLAG_KEY}} value=#{detail.value} reason=#{detail.reason}")React to flag changes (long-running server)
# requires configure(poll: true); fires after a poll fetches NEW data (200, not 304)
unsubscribe = Shipeasy.on_change { reload_local_cache! }
# ... later: unsubscribe.callrelease / configs
Read the dynamic config {{CONFIG_KEY}} with a fallback default.
Assumes
Shipeasy.configureran at startup — see Installation.
# construct once per callsite (cheap; binds the user)
flags = Shipeasy::Client.new(current_user)
# get_config(name, decode = nil, default: nil)
# name — the config key
# decode — optional proc run on a present value, e.g. ->(v) { v["max"] }
# default — returned only when the config key is absent
value = flags.get_config("{{CONFIG_KEY}}", default: "blue")release / killswitches
Read the kill switch {{KILLSWITCH_KEY}} (true = killed). Assumes
Shipeasy.configure ran at startup — see Installation.
Whole switch
# construct once per callsite (cheap; binds the user)
flags = Shipeasy::Client.new(current_user)
# get_killswitch(name, switch_key = nil)
# name — the kill switch key (required)
# switch_key — optional named per-key switch to read
if flags.get_killswitch("{{KILLSWITCH_KEY}}")
# killed → take the safe path
endA named per-key switch
flags = Shipeasy::Client.new(current_user)
provider = "stripe" # pass the thing you're about to do as the switch key
# A configured switch returns its own boolean; an unconfigured key falls back to
# the kill switch's top-level value.
if flags.get_killswitch("{{KILLSWITCH_KEY}}", provider)
use_backup_processor
endrelease / experiments
Get the assignment for {{EXPERIMENT_KEY}}, log exposure, and track the
{{SUCCESS_EVENT}} conversion — all on the bound Client. Assumes
Shipeasy.configure ran at startup — see Installation.
Read the assignment
# construct once per callsite (cheap; binds the user)
flags = Shipeasy::Client.new(current_user)
# get_experiment(name, default_params, decode = nil)
# name — the experiment key (required)
# default_params — params returned when NOT enrolled (the control shape)
# decode — optional proc run on the resolved params
result = flags.get_experiment("{{EXPERIMENT_KEY}}", { label: "Buy now" })
if result.in_experiment && result.group == "treatment"
render_cta(result.params[:label])
endLog exposure + track the conversion
flags = Shipeasy::Client.new(current_user)
# call when you actually present the treatment (no user arg — bound)
flags.log_exposure("{{EXPERIMENT_KEY}}")
# track the conversion on the same bound Client (unit derived from the bound user)
# track(event_name, props = {})
flags.track("{{SUCCESS_EVENT}}", { revenue: 49.99 })metrics
metrics / track
Track a metric/conversion event from the bound Client. Metrics in the dashboard
are computed from these events. Assumes Shipeasy.configure ran at startup —
see Installation.
Track an event
# construct once per callsite (cheap; binds the user)
flags = Shipeasy::Client.new(current_user)
# track(event_name, props = {})
# event_name — the event your metric is built on (required)
# props — optional payload; numeric/string fields you can sum/filter on
# in a metric (private attributes are stripped before egress)
flags.track("{{EVENT_NAME}}", { amount: 49, currency: "usd" })Fire-and-forget (never blocks your response) and a no-op under
configure_for_testing / configure_for_offline. The unit is the bound user
(user_id, else anonymous_id); with no unit the call is a no-op.
Track without properties
flags = Shipeasy::Client.new(current_user)
flags.track("{{EVENT_NAME}}") # props are optionali18n
i18n / setup
Emit the i18n loader + head tags for profile {{PROFILE}} so the browser
hydrates translations on first paint (Rails view helpers auto-mount).
Assumes
Shipeasy.configureran at startup withc.public_key+c.profileset — see Installation.
<%# i18n_head_tags(profile: nil, chunk: nil) — emits the inline data + loader tag.
profile/chunk default to the configured values; pass them to override. %>
<%= i18n_head_tags(profile: "{{PROFILE}}") %>Outside Rails, build the loader tag from the engine with the public client key (never the server key):
# i18n_script_tag(client_key, profile: "en:prod", base_url: nil)
# client_key — the PUBLIC client key
# profile — locale profile to load
# base_url — CDN override (defaults to https://cdn.shipeasy.ai)
tag = Shipeasy.i18n_script_tag(ENV.fetch("SHIPEASY_CLIENT_KEY"), profile: "{{PROFILE}}")i18n / render
Render a translated label in a Rails view with the i18n_t helper.
Assumes
Shipeasy.configureran at startup — see Installation.
<%= i18n_head_tags %>
<%# i18n_t(key, variables = {}, profile: nil, chunk: nil)
key — the translation key
variables — interpolation values for the string
profile — locale profile override (defaults to the configured profile)
chunk — optional key namespace/chunk override %>
<h1><%= i18n_t("hero.title", name: current_user.name) %></h1>ops
ops / see
Report a caught, handled error (or a non-exception "violation") to Shipeasy with
see() — fire-and-forget, never re-raises. Package-level, so it reports against
the engine from Shipeasy.configure. Assumes Shipeasy.configure ran at
startup — see Installation.
Report a handled exception
begin
charge(order)
rescue => e
# .causes_the(subject) what the error affects (e.g. "checkout")
# .to(outcome) the terminal — what you do about it; builds + fires once
Shipeasy.see(e).causes_the("checkout").to("use the backup processor")
fallback_charge(order)
endAttach context with .extras(...)
begin
charge(order)
rescue => e
# .extras(hash) structured fields attached to the report
Shipeasy.see(e).causes_the("checkout").extras({ order_id: oid }).to("use cached prices")
endReport a non-exception violation
# a bad state that isn't an exception — the name is a STABLE fingerprint; put
# variable data in .extras, never the name. .to() is the terminal.
Shipeasy.see_violation("missing_invoice").causes_the("billing").to("skip the dunning email")Mark an expected exception — report NOTHING
begin
parse(token)
rescue StopIteration => e
# transmits nothing; .because(...) / .extras() are local-debug only
Shipeasy.control_flow_exception(e).because("end of stream is expected")
endAdmin API client (optional) — `Shipeasy::Admin`
The base SDK evaluates flags, configs, and experiments (Shipeasy.configure + Shipeasy::Client.new(user)). The Admin API client is a separate, optional…
Agent skill
Installable LLM skill for the Ruby SDK (configure() + Client(user), evaluate, experiment + track, testing).