Platform.Variable bridges AMPscript and SSJS variables within the current page request. A value written by one language is available to server-side blocks that execute later in the document; values do not persist into a later request.

Platform.Variable does not require Platform.Load. The bare-name Variable alias is available after Platform.Load("core", "1.1.5") and shares the same variable state.

Methods

Method Returns Description
Platform.Variable.GetValue(name) string, number, boolean, or null Reads an AMPscript variable in the current request
Platform.Variable.SetValue(name, value) null Writes an AMPscript variable in the current request
Show test script
<script runat="server">
/*
 * Chapter: Methods
 * Proves:
 *   1. Platform.Variable is available without Platform.Load.
 *   2. The bare Variable alias is absent before Core 1.1.5 and usable after it.
 *   3. The alias and Platform.Variable share the same request-local state.
 * EXPECTED OUTPUT: every assertion line starts with PASS.
 */
function assert(id, actual, expected) { Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n"); }
function typeOf(fn) { try { return fn(); } catch (ex) { return "threw:" + String(ex.message); } }
function capture(fn) { try { return { threw: false, value: fn() }; } catch (ex) { return { threw: true, message: String(ex.message) }; } }
assert("Platform.Variable is available without Platform.Load", typeOf(function () { return typeof Platform.Variable; }), "clr");
assert("bare Variable is undefined before Platform.Load", typeOf(function () { return typeof Variable; }), "undefined");
var aliasType = typeOf(function () { Platform.Load("core", "1.1.5"); return typeof Variable; });
assert("bare Variable is available after Core 1.1.5", aliasType, "object");
var aliasSet = capture(function () { return Variable.SetValue("@platformVariableAlias", "alias-roundtrip"); });
assert("bare Variable.SetValue is callable", aliasSet.threw ? "threw:" + aliasSet.message : "returned", "returned");
assert("bare alias shares Platform.Variable state", Platform.Variable.GetValue("@platformVariableAlias"), "alias-roundtrip");
</script>


GetValue

Syntax

Platform.Variable.GetValue(variableName)

Parameters

Name Type Required Description
variableName string Yes AMPscript variable name; the leading @ is optional

Variable names are case-insensitive. When both @name and @NAME are assigned, the later assignment is the value returned through either spelling.

Return Value

Returns the value in its current SSJS scalar type. AMPscript numeric values are numbers, SSJS booleans remain booleans in later SSJS blocks, and strings remain strings. A variable that was never set returns JavaScript null (typeof "object"); a variable explicitly set to "" returns an empty string.

Examples

var email = Platform.Variable.GetValue("@email");
var firstName = Platform.Variable.GetValue("firstName");
Show test script
<script runat="server">
/*
 * Chapter: GetValue
 * Prerequisite: an earlier AMPscript block sets @ampBefore, @ampEmpty,
 * @ampNumber, @ampCase, and @AMPCASE.
 * Proves:
 *   1. AMPscript-set values are visible to later SSJS in the same request.
 *   2. The leading @ is optional and names are case-insensitive.
 *   3. Strings, numbers, and empty strings retain their runtime value/type.
 *   4. A never-set variable is strict JavaScript null with typeof object.
 * EXPECTED OUTPUT: every assertion line starts with PASS.
 */
function assert(id, actual, expected) { Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n"); }
var ampNumber = Platform.Variable.GetValue("@ampNumber");
assert("AMPscript value is visible with at-name", Platform.Variable.GetValue("@ampBefore"), "amp-to-ssjs");
assert("AMPscript value is visible without at-name", Platform.Variable.GetValue("ampBefore"), "amp-to-ssjs");
assert("explicit empty string remains empty", Platform.Variable.GetValue("@ampEmpty"), "");
assert("AMPscript number value is 42", ampNumber, 42);
assert("AMPscript number typeof is number", typeof ampNumber, "number");
assert("variable names are case-insensitive", Platform.Variable.GetValue("@ampCase"), "amp-case-second");
var missing = Platform.Variable.GetValue("platformVariableMissing20260801");
assert("DEV missing variable is strict null (official docs: string)", missing === null ? "null" : "not-null", "null");
assert("DEV missing variable typeof is object (official docs: string)", typeof missing, "object");
</script>


SetValue

Syntax

Platform.Variable.SetValue(variableName, value)

Parameters

Name Type Required Description
variableName string Yes AMPscript variable name; the leading @ is optional
value string, number, boolean, null, or undefined Yes Scalar value to assign

Return Value

Returns JavaScript null. Strings, numbers, booleans, and empty strings retain their SSJS scalar type when read by a later SSJS block. Values assigned as null or undefined read back as null. A later AMPscript block sees numbers and booleans through AMPscript’s display representation and sees null-like values as empty.

Examples

Platform.Variable.SetValue("@result", "processed");
Platform.Variable.SetValue("count", rows.length);
Platform.Variable.SetValue("@jsonPayload", Stringify(data));

After SetValue, a later AMPscript block on the same page can read the variable:

%%[ /* AMPscript reading the value set above */ ]%%
Your result: %%=v(@result)=%%
Show test script
<script runat="server">
/*
 * Chapter: SetValue
 * Proves:
 *   1. Names with and without @ address the same variable.
 *   2. DEV: SetValue returns strict JavaScript null (official docs: void).
 *   3. Strings, numbers, booleans, empty strings, null, and undefined are accepted.
 *   4. Scalar values retain their SSJS type; null and undefined read back as null.
 *   5. A later AMPscript block can read the values in the same request.
 * EXPECTED OUTPUT: every assertion line starts with PASS; the later AMPscript
 * markers must show the corresponding values.
 */
function assert(id, actual, expected) { Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n"); }
function capture(fn) { try { return { threw: false, value: fn() }; } catch (ex) { return { threw: true, message: String(ex.message) }; } }
var setAt = Platform.Variable.SetValue("@ssjsToAmp", "ssjs-to-amp");
assert("DEV SetValue with at-name returns strict null (official docs: void)", setAt === null ? "null" : "not-null", "null");
var setBare = Platform.Variable.SetValue("ssjsBareName", "bare-name-value");
assert("DEV SetValue without at-name returns strict null (official docs: void)", setBare === null ? "null" : "not-null", "null");
assert("at-name and bare-name address the same variable", Platform.Variable.GetValue("@ssjsBareName"), "bare-name-value");
Platform.Variable.SetValue("@ssjsString", "text");
Platform.Variable.SetValue("@ssjsNumber", 42.5);
Platform.Variable.SetValue("@ssjsTrue", true);
Platform.Variable.SetValue("@ssjsFalse", false);
Platform.Variable.SetValue("@ssjsEmpty", "");
var setNull = capture(function () { return Platform.Variable.SetValue("@ssjsNull", null); });
var unset;
var setUndefined = capture(function () { return Platform.Variable.SetValue("@ssjsUndefined", unset); });
assert("string round-trips", Platform.Variable.GetValue("@ssjsString"), "text");
assert("number round-trips as number", Platform.Variable.GetValue("@ssjsNumber"), 42.5);
assert("number typeof remains number", typeof Platform.Variable.GetValue("@ssjsNumber"), "number");
assert("true round-trips as boolean", Platform.Variable.GetValue("@ssjsTrue"), true);
assert("true typeof remains boolean", typeof Platform.Variable.GetValue("@ssjsTrue"), "boolean");
assert("false round-trips as boolean", Platform.Variable.GetValue("@ssjsFalse"), false);
assert("false typeof remains boolean", typeof Platform.Variable.GetValue("@ssjsFalse"), "boolean");
assert("explicit empty string round-trips", Platform.Variable.GetValue("@ssjsEmpty"), "");
assert("SetValue null does not throw", setNull.threw ? "threw:" + setNull.message : "returned", "returned");
assert("SetValue null returns strict null", !setNull.threw && setNull.value === null ? "null" : "other", "null");
assert("null input reads back strict null", Platform.Variable.GetValue("@ssjsNull") === null ? "null" : "other", "null");
assert("SetValue undefined does not throw", setUndefined.threw ? "threw:" + setUndefined.message : "returned", "returned");
assert("SetValue undefined returns strict null", !setUndefined.threw && setUndefined.value === null ? "null" : "other", "null");
assert("undefined input reads back strict null", Platform.Variable.GetValue("@ssjsUndefined") === null ? "null" : "other", "null");
</script>


Common Patterns

Pass SSJS computation to later AMPscript rendering

var score = computeLeadScore(subscriberKey);
Platform.Variable.SetValue("@leadScore", score);
%%[ IF @leadScore > 80 THEN ]%%
  <strong>High priority lead</strong>
%%[ ENDIF ]%%

Read an earlier AMPscript value in SSJS

%%[
  SET @subKey = _subscriberkey
  SET @email = emailaddr
]%%
<script runat="server">
  var subKey = Platform.Variable.GetValue("@subKey");
  var email = Platform.Variable.GetValue("@email");
</script>

Personalization strings such as _subscriberkey and emailaddr depend on send or subscriber context. Platform.Variable only transfers whatever value the earlier AMPscript block produced; it does not create that context on a plain CloudPage GET.

Cross multiple server-side blocks

<script runat="server">
  Platform.Variable.SetValue("@rawInput", userInput);
</script>
%%[ SET @encoded = URLEncode(@rawInput, 1, 1) ]%%
<script runat="server">
  var encoded = Platform.Variable.GetValue("@encoded");
</script>
Show test script
<script runat="server">
/*
 * Chapter: Common Patterns
 * Prerequisite: a preceding AMPscript block has set @ampAfter.
 * Proves:
 *   1. Values can cross SSJS -> AMPscript -> SSJS in execution order.
 *   2. The bridge is limited to the current page request.
 *   3. Personalization values require their real send/subscriber context and are
 *      not created by the bridge itself.
 * EXPECTED OUTPUT: every assertion line starts with PASS. Run the request-local
 * assertion in a second request after the first request set the named value.
 */
function assert(id, actual, expected) { Platform.Response.Write((actual === expected ? "PASS " : "FAIL ") + id + " -> [" + actual + "]\n"); }
var mode = Platform.Request.GetQueryStringParameter("mode");
if (mode === "scope") {
    var prior = Platform.Variable.GetValue("platformVariableCrossRequest20260801");
    assert("request-local value is absent in a later request", prior === null ? "null" : String(prior), "null");
} else {
    Platform.Variable.SetValue("@platformVariableCrossRequest20260801", "request-one");
    assert("value is visible within the same request", Platform.Variable.GetValue("@platformVariableCrossRequest20260801"), "request-one");
    assert("later AMPscript value is visible to following SSJS", Platform.Variable.GetValue("@ampAfter"), "amp-after-ssjs");
}
</script>

See Also