Syntax

Variable.GetValue(name)
Variable.SetValue(name, value)
1–2 arguments

Methods

Method Returns Description
Variable.GetValue(name) string, number, boolean, or null Gets the value of an AMPscript variable
Variable.SetValue(name, value) undefined Sets the value of an AMPscript variable
Show test script — return types vs official docs
<script runat="server">
/*
 * Chapter: Methods — Variable.GetValue / Variable.SetValue
 *
 * Proves:
 *   1. After Platform.Load("core", "1.1.5") Variable.GetValue and
 *      Variable.SetValue are callable.
 *   2. GetValue returns the stored scalar (string / number / boolean)
 *      or strict null when never set.
 *   3. SetValue returns undefined (void-like; Methods table: undefined).
 *   4. DEV: GetValue preserves number/boolean and returns null when never
 *      set (official docs: string).
 *   5. DEV vs Platform.Variable: Platform.Variable.SetValue returns null
 *      while bare Variable.SetValue returns undefined.
 *   6. SetValue accepts string, number, boolean, empty string, null,
 *      and undefined; null/undefined read back as null.
 *
 * NON-ASSERTABLE: personalization strings (_subscriberKey, emailaddr)
 * require send/subscriber context — not present on a plain CloudPage GET.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = "" + ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
function typeOfThunk(fn) {
    try { return "" + fn(); } catch (ex) { return "THREW:" + ("" + ex.message); }
}
function capture(fn) {
    try { return { threw: false, value: fn() }; } catch (ex) { return { threw: true, message: "" + ex.message }; }
}

Platform.Load("core", "1.1.5");
assert("typeof Variable is object after Core load", typeOfThunk(function () { return typeof Variable; }), "object");
assert("typeof Variable.GetValue is function", typeOfThunk(function () { return typeof Variable.GetValue; }), "function");
assert("typeof Variable.SetValue is function", typeOfThunk(function () { return typeof Variable.SetValue; }), "function");

var setRet = Variable.SetValue("@coreVarMethodsStr", "hello");
assert("SetValue returns undefined", setRet === undefined ? "undefined" : "other", "undefined");
assert("SetValue return typeof is undefined", "" + (typeof setRet), "undefined");
var platRet = Platform.Variable.SetValue("@coreVarMethodsStrPlat", "hello-plat");
assert("DEV Platform.Variable.SetValue returns null (bare returns undefined)", platRet === null ? "null" : "other", "null");
assert("GetValue returns the string that was set", Variable.GetValue("@coreVarMethodsStr"), "hello");
assert("GetValue string typeof is string", "" + (typeof Variable.GetValue("@coreVarMethodsStr")), "string");

Variable.SetValue("@coreVarMethodsNum", 42);
var numVal = Variable.GetValue("@coreVarMethodsNum");
assert("DEV GetValue preserves number (official docs: string)", numVal, 42);
assert("DEV GetValue number typeof is number (official docs: string)", "" + (typeof numVal), "number");

Variable.SetValue("@coreVarMethodsTrue", true);
assert("DEV GetValue preserves boolean true (official docs: string)", Variable.GetValue("@coreVarMethodsTrue"), true);

var missing = Variable.GetValue("@coreVarMethodsMissing20260803");
assert("DEV never-set GetValue is strict null (official docs: string)", missing === null ? "null" : "other", "null");
assert("DEV never-set GetValue typeof is object", "" + (typeof missing), "object");

Variable.SetValue("@coreVarMethodsEmpty", "");
assert("explicit empty string remains empty", Variable.GetValue("@coreVarMethodsEmpty"), "");

var setNull = capture(function () { return Variable.SetValue("@coreVarMethodsNull", null); });
var unset;
var setUndef = capture(function () { return Variable.SetValue("@coreVarMethodsUndef", unset); });
assert("SetValue null does not throw", setNull.threw ? "threw:" + setNull.message : "returned", "returned");
assert("null input reads back strict null", Variable.GetValue("@coreVarMethodsNull") === null ? "null" : "other", "null");
assert("SetValue undefined does not throw", setUndef.threw ? "threw:" + setUndef.message : "returned", "returned");
assert("undefined input reads back strict null", Variable.GetValue("@coreVarMethodsUndef") === null ? "null" : "other", "null");
</script>

Description

The global Variable object provides the bridge between AMPscript and SSJS. AMPscript variables are prefixed with @ and live in a shared scope accessible by both languages on the same page.

After Platform.Load("core", "1.1.5"), bare Variable.GetValue / Variable.SetValue share request-local state with Platform.Variable. GetValue behaviour matches the Platform form; SetValue returns undefined here, while Platform.Variable.SetValue returns null.

Show test script
<script runat="server">
/*
 * Chapter: Description — Variable is the Core alias of Platform.Variable
 *
 * Proves:
 *   1. Before Platform.Load the bare Variable is undefined; invoking
 *      GetValue throws. typeof is resolved inside a thunk.
 *   2. Platform.Variable is available without Platform.Load.
 *   3. After Platform.Load("core", "1.1.5") Variable is an object and
 *      shares request-local state with Platform.Variable.
 *   4. DEV: bare SetValue returns undefined; Platform.Variable.SetValue
 *      returns null — state is shared, return values are not identical.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}
function assertThrows(id, fn) {
    var threw = false, msg = "";
    try { fn(); } catch (ex) { threw = true; msg = "" + ex.message; }
    Platform.Response.Write((threw ? "PASS " : "FAIL ") + id + " -> " + (threw ? "threw: " + msg : "did NOT throw") + "\n");
}
function typeOfThunk(fn) {
    try { return "" + fn(); } catch (ex) { return "THREW:" + ("" + ex.message); }
}

assert("before load typeof Variable is undefined", typeOfThunk(function () { return typeof Variable; }), "undefined");
assertThrows("before load Variable.GetValue throws", function () { return Variable.GetValue("@x"); });
assert("Platform.Variable exists without load", typeOfThunk(function () { return typeof Platform.Variable; }), "clr");

Platform.Load("core", "1.1.5");
assert("after load typeof Variable is object", typeOfThunk(function () { return typeof Variable; }), "object");

Variable.SetValue("@coreVarDescAlias", "alias-roundtrip");
assert("bare Variable shares Platform.Variable state", Platform.Variable.GetValue("@coreVarDescAlias"), "alias-roundtrip");
Platform.Variable.SetValue("@coreVarDescFromPlatform", "from-platform");
assert("Platform.Variable writes are visible via bare Variable", Variable.GetValue("@coreVarDescFromPlatform"), "from-platform");
var bareSetRet = Variable.SetValue("@coreVarDescRet", "r");
var platSetRet = Platform.Variable.SetValue("@coreVarDescRetPlat", "r");
assert("DEV bare SetValue returns undefined (Platform returns null)", bareSetRet === undefined ? "undefined" : "other", "undefined");
assert("DEV Platform.Variable.SetValue returns null (bare returns undefined)", platSetRet === null ? "null" : "other", "null");
</script>

Examples

Read an AMPscript variable

%%[
  SET @subscriberKey = _subscriberKey
  SET @emailAddress  = emailaddr
]%%

<script runat="server">
// Read variables set by AMPscript
var sk    = Variable.GetValue("@subscriberKey");
var email = Variable.GetValue("@emailAddress");

Write("<p>Processing: " + email + "</p>");
</script>

Write an AMPscript variable

<script runat="server">
var data  = String(Platform.Function.Lookup("Preferences", "Theme", "SubscriberKey", sk));
// Never use `data || "light"` on a raw Lookup result — a NULL field throws
var theme = (data === "" || data === "null") ? "light" : data;
Variable.SetValue("@theme", theme);
</script>

<!-- Use the variable in AMPscript -->
<body class="theme-%%=v(@theme)=%%">

Bridge pattern for AMPscript functions

The most important use: safely pass values into AMPscript functions via Platform.Function.TreatAsContent:

// Safe: set value via Variable.SetValue, reference by name in AMPscript
Variable.SetValue("@inputStr", userValue);
Platform.Function.TreatAsContent("%%[Set @encoded = URLEncode(@inputStr, 1, 1)]%%");
var encoded = Variable.GetValue("@encoded");

This pattern avoids AMPscript injection vulnerabilities.

Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: Examples — read / write / TreatAsContent bridge
 *
 * Prerequisite: a preceding AMPscript block sets @coreVarExAmpSk and
 * @coreVarExAmpEmail (stand-ins for the page's @subscriberKey / @emailAddress).
 *
 * Proves:
 *   1. Variable.GetValue reads AMPscript-set values in the same request.
 *   2. Variable.SetValue writes a value readable by later SSJS (and by
 *      later AMPscript in a combined harness).
 *   3. The TreatAsContent bridge: SetValue -> TreatAsContent(URLEncode) ->
 *      GetValue returns the encoded result (injection-safe pattern).
 *   4. SetValue with the String()-first fallback stores the fallback when
 *      the lookup produced no usable value. The example deliberately does
 *      NOT use `data || "light"`: truthiness on a raw Lookup result throws
 *      when the matched row's field is NULL (see platform-functions/lookup).
 *      Asserted here on the same underlying facts, using the two values a
 *      Lookup can produce for "no usable value" — a genuine JavaScript null
 *      (no matching row) and an empty string (a blank field) — plus a real
 *      value to prove the guard does not fire on it.
 *
 * NOT ASSERTED: that the CLR null a never-populated DE field returns also
 * stringifies to "" and is caught by the same guard. That needs a data
 * extension fixture, which this chapter does not create; it is proven in the
 * empty-returns chapter of platform-functions--lookup.yml.
 *
 * NON-ASSERTABLE: Lookup("Preferences", ...) DE row; personalization
 * strings _subscriberKey / emailaddr on a plain CloudPage GET.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}

assert("read AMPscript @coreVarExAmpSk", Variable.GetValue("@coreVarExAmpSk"), "sk-example");
assert("read AMPscript @coreVarExAmpEmail", Variable.GetValue("@coreVarExAmpEmail"), "user@example.com");

/* The example's guard, on a no-match Lookup result (a genuine JS null). */
var noMatch = null;
var dataNoMatch = String(noMatch);
assert("String() of a no-match Lookup result is the string \"null\"", dataNoMatch, "null");
Variable.SetValue("@theme", (dataNoMatch === "" || dataNoMatch === "null") ? "light" : dataNoMatch);
assert("write fallback theme when the lookup found no row", Variable.GetValue("@theme"), "light");

/* The same guard, on a blank field (an ordinary empty string). */
var dataBlank = String("");
assert("String() of a blank field is the empty string", dataBlank, "");
Variable.SetValue("@themeBlank", (dataBlank === "" || dataBlank === "null") ? "light" : dataBlank);
assert("write fallback theme when the field is blank", Variable.GetValue("@themeBlank"), "light");

/* The guard must NOT fire on a real value. */
var dataReal = String("dark");
Variable.SetValue("@themeReal", (dataReal === "" || dataReal === "null") ? "light" : dataReal);
assert("a real lookup value is stored unchanged, the fallback does not fire", Variable.GetValue("@themeReal"), "dark");

Variable.SetValue("@inputStr", "hello world");
var pct = "%" + "%";
Platform.Function.TreatAsContent(pct + "[Set @encoded = URLEncode(@inputStr, 1, 1)]" + pct);
var encoded = Variable.GetValue("@encoded");
assert("bridge GetValue returns a string", "" + (typeof encoded), "string");
assert("bridge encoded differs from raw input", encoded === "hello world" ? "same" : "encoded", "encoded");
assert("bridge encoded is non-empty", encoded && ("" + encoded).length > 0 ? "true" : "false", "true");
assert("bridge encoded contains encoded space or plus", (("" + encoded).indexOf("%20") >= 0 || ("" + encoded).indexOf("+") >= 0) ? "true" : "false", "true");
</script>

Notes

Variable names must include the @ prefix:

Variable.SetValue("@name", "Jane");  // ✅ correct
Variable.SetValue("name", "Jane");   // ⚠️ may work but non-standard
Show test script
<script runat="server">
Platform.Load("core", "1.1.5");

/*
 * Chapter: Notes — @ prefix is correct; bare name may work
 *
 * Proves:
 *   1. Variable.SetValue("@name", ...) is the correct form and round-trips.
 *   2. Variable.SetValue("name", ...) without @ also addresses the same
 *      variable (page: may work but non-standard).
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

function assert(id, actual, expected) {
    Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n");
}

Variable.SetValue("@name", "Jane");
assert("SetValue with @ prefix round-trips", Variable.GetValue("@name"), "Jane");
assert("GetValue without @ finds the same @name", Variable.GetValue("name"), "Jane");

Variable.SetValue("name", "Jane-bare");
assert("DEV SetValue without @ may work (non-standard)", Variable.GetValue("@name"), "Jane-bare");
assert("bare SetValue is visible via @ GetValue", Variable.GetValue("name"), "Jane-bare");
</script>

See Also