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
Read {{FLAG_KEY}} off a user-bound Client. Assumes configure() ran at
startup — see Installation.
import ai.shipeasy.Client;
import java.util.Map;
// construct once per callsite (cheap; binds the user)
Client client = new Client(Map.of("user_id", "u_123"));
boolean enabled = client.getFlag("{{FLAG_KEY}}"); // gate name
// optional default overload — returned ONLY when unresolvable (engine not
// ready / flag absent), never when the flag legitimately evaluates to false:
// boolean enabled = client.getFlag("{{FLAG_KEY}}", true /* default */);release / configs
Read the dynamic config {{CONFIG_KEY}} (with a fallback when absent).
Assumes configure() ran at startup — see Installation.
import ai.shipeasy.Client;
import java.util.Map;
// construct once per callsite (cheap; binds the user)
Client client = new Client(Map.of("user_id", "u_123"));
Object cfg = client.getConfig(
"{{CONFIG_KEY}}", // config name
Map.of("title", "Default")); // fallback returned when the config is absent
// one-arg overload returns null when absent: client.getConfig("{{CONFIG_KEY}}")release / killswitches
Check whether the kill switch {{KILLSWITCH_KEY}} is killed. Assumes
configure() ran at startup — see Installation.
import ai.shipeasy.Client;
import java.util.Map;
// construct once per callsite (cheap; binds the user)
Client client = new Client(Map.of("user_id", "u_123"));
boolean killed = client.getKillswitch("{{KILLSWITCH_KEY}}"); // killswitch name
// optional second arg reads one named per-key switch (null = whole killswitch):
// boolean off = client.getKillswitch("{{KILLSWITCH_KEY}}", "eu_region" /* switchKey */);
if (killed) {
// disable the protected path
}release / experiments
Bucket a user into {{EXPERIMENT_KEY}}, then track the {{SUCCESS_EVENT}}
conversion. Assumes configure() ran at startup — see Installation.
import ai.shipeasy.Client;
import ai.shipeasy.ExperimentResult;
import java.util.Map;
// construct once per callsite (cheap; binds the user)
Client client = new Client(Map.of("user_id", "u_123"));
ExperimentResult r = client.getExperiment(
"{{EXPERIMENT_KEY}}", // experiment name
Map.of("color", "blue")); // defaultParams — filled in when not enrolled
if (r.inExperiment && "treatment".equals(r.group)) {
// render the treatment variant; r.params carries the assigned parameters
}
// later, on conversion — track() lives on the bound Client (NOT the Engine);
// the unit id is derived from the bound user (user_id, else anonymous_id):
client.track(
"{{SUCCESS_EVENT}}", // event name
Map.of("amount", 49)); // optional properties bag (track(name) omits it)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
import ai.shipeasy.Client;
import java.util.Map;
Client client = new Client(Map.of("user_id", "u_123")); // construct once per callsite
// track(eventName, props)
// eventName — 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)
client.track("{{EVENT_NAME}}", Map.of("amount", 49, "currency", "usd"));Fire-and-forget (never blocks your response) and a no-op under
Shipeasy.configureForTesting / configureForOffline. The unit is the bound user
(user_id, else anonymous_id); with no unit the call is a no-op.
Track without properties
Client client = new Client(Map.of("user_id", "u_123")); // construct once per callsite
client.track("{{EVENT_NAME}}", Map.of()); // props are optional (pass an empty map)i18n
i18n / setup
The Java server SDK has no t() — emit the i18n loader <script> tag (with the
public client key) so the browser SDK loads the {{PROFILE}} profile.
Assumes configure() ran at startup — see Installation.
import ai.shipeasy.Engine;
import ai.shipeasy.Shipeasy;
// grab the already-configured global Engine (the SSR/script-tag helpers live on
// the Engine, not the bound Client)
Engine engine = Shipeasy.engine();
String clientKey = System.getenv("SHIPEASY_CLIENT_KEY"); // PUBLIC key (never the server key)
String head = engine.i18nScriptTag(
clientKey, // public client key embedded in the loader tag
"{{PROFILE}}"); // locale profile, e.g. en:prod
// → render `head` inside the document <head>
// 3-arg overload also takes a CDN baseUrl (defaults to https://cdn.shipeasy.ai).i18n / render
Rendering a translated label is client-side only — the Java server SDK does
not expose t(). Once the loader tag (see setup) has hydrated the browser, the
client SDK renders keys:
// browser, @shipeasy/sdk client
import { t } from "@shipeasy/sdk/client";
t("checkout.cta"); // → translated string for the active {{PROFILE}} profileops
ops / see
Report a caught, handled error (or a non-exception "violation") to Shipeasy with
see() — fire-and-forget, never re-throws. The static form reports against the
engine from Shipeasy.configure(...). Assumes Shipeasy.configure(...) ran at
startup — see Installation.
Report a handled exception
import static ai.shipeasy.See.see;
import java.util.Map;
try {
charge(order);
} catch (Exception e) {
// .causesThe(subject) what the error affects (e.g. "checkout")
// .to(outcome) the terminal — what you do about it; builds + fires once
see(e).causesThe("checkout").to("use the backup processor");
fallbackCharge(order);
}Attach context with .extras(...)
import static ai.shipeasy.See.see;
try {
charge(order);
} catch (Exception e) {
// .extras(map) structured fields attached to the report
see(e).causesThe("checkout").extras(Map.of("order_id", oid)).to("use cached prices");
}Report a non-exception violation
import static ai.shipeasy.See.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.
violation("missing_invoice").causesThe("billing").to("skip the dunning email");Mark an expected exception — report NOTHING
import static ai.shipeasy.See.controlFlowException;
try {
parse(token);
} catch (NoSuchElementException e) {
// transmits nothing; .because(...) is local-debug only
controlFlowException(e).because("end of stream is expected");
}