Reading AMPscript Variables in SSJS

%%[
  SET @subscriberKey = _subscriberkey
  SET @emailAddr = emailaddr
  SET @firstName = FirstName
]%%

<script runat="server">
var subKey = Platform.Variable.GetValue("@subscriberKey");
var email = Platform.Variable.GetValue("@emailAddr");
var firstName = Platform.Variable.GetValue("@firstName");

// Now use these in SSJS logic
var score = Platform.Function.Lookup("LeadScores", "score", "email", email);
Platform.Variable.SetValue("@leadScore", score);
</script>

%%[ /* Render the SSJS-computed value in AMPscript */ ]%%
Lead score: %%=v(@leadScore)=%%

Show test script
<script runat="server">
/*
 * Chapter: Reading AMPscript Variables in SSJS
 * Proves:
 *   1. SetValue/GetValue round-trip (SSJS-side stand-in for AMPscript SET).
 * 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); }
}
Platform.Variable.SetValue("@subscriberKey", "sk-1");
Platform.Variable.SetValue("@leadScore", 42);
assert("GetValue sk", Platform.Variable.GetValue("@subscriberKey"), "sk-1");
assert("GetValue score number", Platform.Variable.GetValue("@leadScore"), 42);
</script>

Passing SSJS Results to AMPscript Rendering

// SSJS computes complex logic
var tier = "standard";
if (parseInt(score, 10) > 80) tier = "premium";
if (parseInt(score, 10) > 95) tier = "vip";

Platform.Variable.SetValue("@tier", tier);
Platform.Variable.SetValue("@discountCode", discountCodes[tier]);
%%[ IF @tier == "vip" THEN ]%%
  <div class="vip-banner">Welcome, VIP!</div>
  <p>Your exclusive code: %%=v(@discountCode)=%%</p>
%%[ ELSEIF @tier == "premium" THEN ]%%
  <p>Premium member discount: %%=v(@discountCode)=%%</p>
%%[ ELSE ]%%
  <p>Standard member</p>
%%[ ENDIF ]%%

Show test script
<script runat="server">
/*
 * Chapter: Passing SSJS Results to AMPscript Rendering
 * Proves:
 *   1. Tier computation + SetValue.
 * 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); }
}
var score = "90";
var tier = "standard";
if (parseInt(score, 10) > 80) tier = "premium";
if (parseInt(score, 10) > 95) tier = "vip";
Platform.Variable.SetValue("@tier", tier);
assert("tier premium", Platform.Variable.GetValue("@tier"), "premium");
</script>

Safe URL Encoding via AMPscript

AMPscript’s URLEncode has more encoding options than SSJS:

Variable.SetValue("@rawValue", userInput);
Platform.Function.TreatAsContent("%%[SET @encoded = URLEncode(@rawValue, 1, 1)]%%");
var encoded = Variable.GetValue("@encoded");

Show test script
<script runat="server">
/*
 * Chapter: Safe URL Encoding via AMPscript
 * Proves:
 *   1. Variable + TreatAsContent URLEncode path.
 * 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); }
}
Platform.Load("core", "1.1.5");
Variable.SetValue("@rawValue", "a b");
Platform.Function.TreatAsContent("%%[SET @encoded = URLEncode(@rawValue, 1, 1)]%%");
var encoded = Variable.GetValue("@encoded");
assert("encoded has percent-or-plus", ("" + encoded).indexOf("%") >= 0 || ("" + encoded).indexOf("+") >= 0 ? "true" : "false", "true");
</script>

Using Platform.Function.TreatAsContent Safely

// Output encoder — canonical copy lives in Security → Output Encoding
function htmlEncode(str) {
    return (str + "")
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#x27;");
}

// SAFE against AMPscript injection
Variable.SetValue("@name", userName);
Variable.SetValue("@code", promoCode);
var rendered = Platform.Function.TreatAsContent("Hello, %%=v(@name)=%%. Your code is %%=v(@code)=%%.");

// Still unsafe to write raw — the rendered string is not HTML-encoded.
Write(htmlEncode(rendered));

// DANGEROUS — never do this:
// Platform.Function.TreatAsContent(userInput); // AMPscript injection!

Show test script
<script runat="server">
/*
 * Chapter: Using TreatAsContent Safely
 * Proves:
 *   1. htmlEncode; TreatAsContent via Variable.
 * 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); }
}
Platform.Load("core", "1.1.5");
function htmlEncode(str) {
    return (str + "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
}
assert("htmlEncode", htmlEncode("<x>"), "&lt;x&gt;");
Variable.SetValue("@tac", "hi");
assert("TreatAsContent v()", Platform.Function.TreatAsContent("%%=v(@tac)=%%"), "hi");
</script>

Reading Subscriber Attributes in SSJS

%%[
  SET @city = AttributeValue("City")
  SET @language = AttributeValue("PreferredLanguage")
]%%

<script runat="server">
var city = Platform.Variable.GetValue("@city");
var language = Platform.Variable.GetValue("@language") || "en";

// Or use the global Attribute object directly
var city2 = Attribute.GetValue("City");
</script>

Show test script
<script runat="server">
/*
 * Chapter: Reading Subscriber Attributes in SSJS
 * Proves:
 *   1. Attribute.GetValue typeof after Core (CloudPage may return empty).
 *   NON-ASSERTABLE: real send-time personalization strings.
 * 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); }
}
Platform.Load("core", "1.1.5");
assert("Attribute typeof", typeOfThunk(function () { return typeof Attribute; }), "object");
assert("GetValue typeof", typeOfThunk(function () { return typeof Attribute.GetValue; }), "function");
</script>

JSON Data Bridge

Pass complex data from AMPscript to SSJS via JSON strings:

%%[
  SET @productJson = LookupRows("Products", "Category", "featured")
]%%

<script runat="server">
// Better: use SSJS to retrieve directly
var products = Platform.Function.LookupRows("Products", "Category", "featured");
// products is already an array in SSJS
</script>

For data computed in SSJS and consumed in AMPscript, use simple string variables since AMPscript doesn’t parse JSON natively:

// SSJS
Platform.Variable.SetValue("@productCount", products.length);
Platform.Variable.SetValue("@topProduct", products[0] ? products[0].Name : "");
%%[ /* AMPscript */ ]%%
We have %%=v(@productCount)=%% featured products.
Top pick: %%=v(@topProduct)=%%
Show test script
<script runat="server">
/*
 * Chapter: JSON Data Bridge
 * Proves:
 *   1. Stringify then SetValue then ParseJSON round-trip.
 * 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); }
}
var payload = { a: 1, b: "x" };
var json = Platform.Function.Stringify(payload);
Platform.Variable.SetValue("@jsonBridge", json);
var back = Platform.Function.ParseJSON(Platform.Variable.GetValue("@jsonBridge") + "");
assert("round-trip a", back.a, 1);
assert("round-trip b", back.b, "x");
</script>

See Also