Syntax

ContentArea(id[, regionName, errorMsg, fallbackContent])
1–4 arguments

Parameters

Name Type Required Description
id string | number Yes ID of the Content Area. A numeric string for the same id works too.
regionName string No Impression region for content tracking. ⚠️ Supplying it makes the call throw a resolved-value error — see below.
errorMsg string No Error message returned as a string on retrieval failure. ⚠️ Unreachable — the call already throws on regionName.
fallbackContent string No Content to display when the area cannot be retrieved. ⚠️ Unreachable — never emitted at runtime.
Show test script
<script runat="server">

/*
 * Chapter: Parameters — ContentArea(id[, regionName, errorMsg, fallbackContent])
 *
 * Proves:
 *   1. The bare-name global requires Platform.Load: before the load it does
 *      not resolve at all (typeof is "undefined", resolved lazily inside a
 *      thunk so an unbound name cannot abort the page).
 *   2. After Platform.Load("core", "1.1.5") it is a genuine JS function
 *      (typeof "function"), not the "clrmethodinfo" marker the qualified
 *      Platform.Function form reports.
 *   3. The required `id` parameter alone — the minimal documented call —
 *      returns the content area's markup, for an ID that exists.
 *   4. Number↔string type-acceptance for `id`: the documented number form
 *      AND its numeric-string counterpart both return the same content, so
 *      the Parameters table widens the type to `string | number`.
 *   5. DEV the documented optional `regionName` (parameter 2) does not
 *      work: it is rejected as a resolved-value parameter. A string
 *      literal, the empty string and null all throw.
 *   6. DEV because parameter 2 is rejected, the documented string `errorMsg`
 *      (parameter 3) and `fallbackContent` (parameter 4) are UNREACHABLE:
 *      arity 3 and arity 4 throw, so neither the error message nor the
 *      fallback string is ever returned.
 *   7. Arities outside the documented 1..4 range (0 and 5) throw as well.
 *      Since arity 1 succeeds in this same request, those throws settle
 *      ARITY and say nothing about whether the member exists.
 *
 * NOT ASSERTED: the exact text of the thrown messages beyond a stable
 * fragment check on arity 2. Each message is printed verbatim next to its
 * assertion for the reader.
 *
 * EXPECTED OUTPUT: every line starts with PASS. A FAIL means the runtime no
 * longer matches the documented claim and the page must be revised.
 */

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 typeOf(fn) {
    try { return "" + fn(); } catch (ex) { return "THREW: " + ("" + ex.message); }
}

/* 1. Before the Core load the bare name does not resolve. */
assert("before Platform.Load the bare name is undefined", typeOf(function () { return typeof ContentArea; }), "undefined");

Platform.Load("core", "1.1.5");

/* 2. After the load it is a real function, not a CLR method proxy. */
assert("after Platform.Load typeof ContentArea is function", typeOf(function () { return typeof ContentArea; }), "function");
assert("typeof Platform.Function.ContentArea is clrmethodinfo", typeOf(function () { return typeof Platform.Function.ContentArea; }), "clrmethodinfo");

/* Fixture: create a Content Area and keep the ID the platform assigned. */
var prox = new Script.Util.WSProxy();
var caName = "ssjsg-ca-" + Platform.Function.GUID().substring(0, 8);
var caBody = "BODY-" + caName;
var created = prox.createItem("ContentArea", { Name: caName, CustomerKey: caName, Content: caBody, IsDynamicContent: false });
var caId = created.Results[0].NewObjectID;
assert("the fixture Content Area was created", "" + created.Status, "OK");

/* 3. The minimal documented call (id only) returns the content. */
assert("arity 1 with the fixture id returns the content", "" + ContentArea(caId), caBody);

/* 4. Number↔string type-acceptance for id — both return the same content. */
assert("type-accept: the numeric-string id returns the same content", "" + ContentArea("" + caId), caBody);

/* 5. DEV the documented optional regionName is rejected as a resolved value. */
assertThrows("DEV arity 2 regionName string literal throws (docs: optional impression region)", function () {
    return ContentArea(caId, "impressionRegion");
});
assertThrows("DEV arity 2 empty-string regionName throws as well", function () {
    return ContentArea(caId, "");
});
assertThrows("DEV arity 2 null regionName throws as well", function () {
    return ContentArea(caId, null);
});

/* 6. DEV errorMsg and fallbackContent are unreachable behind that rejection. */
assertThrows("DEV arity 3 string errorMsg throws (docs: that message is returned)", function () {
    return ContentArea(caId, "impressionRegion", "Could not load content area");
});
assertThrows("DEV arity 4 fallbackContent never emitted, call throws (docs: fallback is displayed)", function () {
    return ContentArea(caId, "impressionRegion", "Could not load content area", "Fallback text here");
});

/* 7. Off-signature arities throw as well. */
assertThrows("arity 0 throws", function () {
    return ContentArea();
});
assertThrows("arity 5 throws", function () {
    return ContentArea(caId, "r", "e", "f", "extra");
});

/* The rejected parameter is named in the arity-2 message. */
var msg2 = "";
try { ContentArea(caId, "impressionRegion"); } catch (e2) { msg2 = "" + e2.message; }
assert("DEV arity 2 message names ImpressionRegionName as the rejected parameter", msg2.indexOf("ImpressionRegionName") >= 0 ? "true" : "false", "true");
assert("DEV arity 2 rejects it as a ResolvedValueParameter", msg2.indexOf("ResolvedValueParameter") >= 0 ? "true" : "false", "true");

/* Cleanup. */
prox.deleteItem("ContentArea", { ID: caId });
</script>

Description

ContentArea() retrieves and renders content from a classic (legacy) SFMC Content Area identified by its ID.

Requires Platform.Load: This global form requires Platform.Load("core", "1.1.5") before use. The qualified Platform.Function.ContentArea() form does not.

Runtime note: after the load the global is a genuine function (typeof ContentArea === "function") and the single-argument call returns the content of a Content Area that exists — the same id passed as a numeric string works too. An id that does not resolve throws an evaluation error. Every arity above 1 throws, so regionName, errorMsg and fallbackContent are unusable.

Show test script — only the 1-argument form works
<script runat="server">

/*
 * Differs-from-docs claim: the official Salesforce documentation presents
 * the global ContentArea(id, regionName, errorMsg, fallbackContent) as a
 * four-parameter callable, with errorMsg returned on failure and
 * fallbackContent displayed when nothing is returned. At runtime ONLY the
 * single-argument form works.
 *
 * Official docs: ContentArea(123456,"impressionRegion","err","fallback")
 *                returns the content the area produced.
 * SFMC runtime:  arity 1     -> returns the content area's markup
 *                arity 2     -> "A ContentArea function call includes an
 *                                invalid parameter value. … must be a
 *                                literal (constant) values."
 *                                Parameter Name: ImpressionRegionName
 *                                Parameter Ordinal: 2
 *                                Parameter Type: ResolvedValueParameter
 *                arity 0/3/4/5 -> "Unable to retrieve security descriptor
 *                                for this frame." (arity 0 with an
 *                                undefined message)
 *
 * Proves every part of the claim:
 *   1. Arity 1 returns the content for the fixture created in this request.
 *   2. DEV arity 2 throws the resolved-value error for every regionName
 *      shape: string literal, concatenation, variable, empty string and
 *      null. So the failure is not "literal vs variable" — the parameter
 *      cannot be supplied at all.
 *   3. DEV arity 3 and arity 4 throw as well, which is what makes errorMsg
 *      and fallbackContent unreachable: neither string is ever returned.
 *   4. Arity 0 and arity 5 throw too. Existence is independently
 *      established by the successful arity-1 call in this same request, so
 *      those messages settle ARITY only.
 *   5. The qualified Platform.Function form behaves identically, so the
 *      deviation is not specific to the bare-name Core namespace.
 *
 * EXPECTED OUTPUT: every line starts with PASS.
 */

Platform.Load("core", "1.1.5");

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");
}

/* Fixture: create a Content Area and keep the ID the platform assigned. */
var prox = new Script.Util.WSProxy();
var caName = "ssjsg-ca-" + Platform.Function.GUID().substring(0, 8);
var caBody = "BODY-" + caName;
var created = prox.createItem("ContentArea", { Name: caName, CustomerKey: caName, Content: caBody, IsDynamicContent: false });
var caId = created.Results[0].NewObjectID;
assert("the fixture Content Area was created", "" + created.Status, "OK");

/* 1. Arity 1 works. */
assert("arity 1 returns the content", "" + ContentArea(caId), caBody);

/* 2. DEV every regionName shape is rejected as a resolved value. */
assertThrows("DEV arity 2 string literal regionName throws", function () {
    return ContentArea(caId, "impressionRegion");
});
assertThrows("DEV arity 2 concatenated regionName throws", function () {
    return ContentArea(caId, "impression" + "Region");
});
var dynRegion = "impressionRegion";
assertThrows("DEV arity 2 variable regionName throws", function () {
    return ContentArea(caId, dynRegion);
});
assertThrows("DEV arity 2 empty-string regionName throws", function () {
    return ContentArea(caId, "");
});
assertThrows("DEV arity 2 null regionName throws", function () {
    return ContentArea(caId, null);
});

/* 3. DEV errorMsg and fallbackContent never take effect. */
assertThrows("DEV arity 3 errorMsg throws (docs: the message is returned)", function () {
    return ContentArea(caId, "impressionRegion", "Could not load content area");
});
assertThrows("DEV arity 4 throws so fallbackContent is never emitted (docs: fallback shown)", function () {
    return ContentArea(caId, "impressionRegion", "Could not load content area", "FALLBACK");
});
assertThrows("DEV arity 4 with a null regionName throws as well", function () {
    return ContentArea(caId, null, "err", "FALLBACK");
});

/* 4. Off-signature arities throw too. */
assertThrows("arity 0 throws", function () {
    return ContentArea();
});
assertThrows("arity 5 throws", function () {
    return ContentArea(caId, "r", "e", "f", "extra");
});

/* 5. The qualified Platform.Function form behaves identically. */
assert("qualified arity 1 returns the same content", "" + Platform.Function.ContentArea(caId), caBody);
assertThrows("DEV qualified arity 2 throws as well", function () {
    return Platform.Function.ContentArea(caId, "impressionRegion");
});

/* Cleanup. */
prox.deleteItem("ContentArea", { ID: caId });
</script>

Difference from Platform.Function.ContentArea()

  ContentArea() (global) Platform.Function.ContentArea()
3rd parameter errorMsg: string stopOnError: boolean
Requires Platform.Load Yes — Platform.Load("core", "1.1.5") No

See Platform.Function.ContentArea for the qualified variant.

Show test script
<script runat="server">

/*
 * Chapter: Description — requires Platform.Load, is a genuine function,
 * behaves like the qualified form, and how the two differ in their 3rd
 * parameter.
 *
 * Proves:
 *   1. The documented Platform.Load requirement: the bare name is undefined
 *      before Platform.Load("core", "1.1.5") and a function afterwards,
 *      while the qualified Platform.Function form resolves without any load.
 *   2. A Content Area created in this request is returned by
 *      ContentArea(id), for the numeric ID and its numeric-string form.
 *   3. A throw at arity 1 means the ID did not resolve, nothing more: an
 *      unknown id, 0 and a negative id throw while the fixture id keeps
 *      succeeding in the same request.
 *   4. DEV the documented 3rd-parameter difference (string errorMsg here vs
 *      boolean stopOnError on the qualified form) cannot be exercised:
 *      arity 3 throws for the string form exactly as the qualified form
 *      throws for the boolean one.
 *   5. The recommended replacement path is real: Platform.Function resolves
 *      ContentBlockByID as a host method (the documented modern substitute
 *      for classic Content Areas).
 *
 * NOT ASSERTED: the frontmatter availability claims for email and triggered
 * send. Those hold only in a send context; a CloudPage GET cannot observe
 * them, so they are recorded as blocked in the verification DB instead.
 * NOT ASSERTED: any runtime effect of the Salesforce deprecation notice.
 * Deprecation is a documentation fact; nothing observable in this request
 * distinguishes a deprecated member from a supported one.
 *
 * 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 typeOf(fn) {
    try { return "" + fn(); } catch (ex) { return "THREW: " + ("" + ex.message); }
}

/* 1. The Platform.Load requirement, both before and after. */
assert("bare name is undefined before Platform.Load", typeOf(function () { return typeof ContentArea; }), "undefined");
assert("qualified form resolves WITHOUT Platform.Load", typeOf(function () { return typeof Platform.Function.ContentArea; }), "clrmethodinfo");

Platform.Load("core", "1.1.5");

assert("bare name is a genuine function after Platform.Load", typeOf(function () { return typeof ContentArea; }), "function");

/* Fixture: create a Content Area and keep the ID the platform assigned. */
var prox = new Script.Util.WSProxy();
var caName = "ssjsg-ca-" + Platform.Function.GUID().substring(0, 8);
var caBody = "BODY-" + caName;
var created = prox.createItem("ContentArea", { Name: caName, CustomerKey: caName, Content: caBody, IsDynamicContent: false });
var caId = created.Results[0].NewObjectID;
assert("the fixture Content Area was created", "" + created.Status, "OK");

/* 2. The fixture id resolves, as a number and as a numeric string. */
assert("the fixture id returns the content", "" + ContentArea(caId), caBody);
assert("the numeric-string id returns the same content", "" + ContentArea("" + caId), caBody);

/* 3. Ids that do not resolve throw. */
assertThrows("an unknown id throws", function () {
    return ContentArea(123456);
});
assertThrows("id 0 throws", function () {
    return ContentArea(0);
});
assertThrows("a negative id throws", function () {
    return ContentArea(-1);
});

/* 4. DEV the documented string errorMsg (3rd parameter) is unusable. */
assertThrows("DEV arity 3 with the string errorMsg throws (docs: returns that message)", function () {
    return ContentArea(caId, "impressionRegion", "Could not load content area");
});
assertThrows("the qualified form's boolean stopOnError throws at arity 3 too", function () {
    return Platform.Function.ContentArea(caId, "impressionRegion", false);
});

/* 5. The documented modern replacement resolves as a host method. */
assert("typeof Platform.Function.ContentBlockByID is clrmethodinfo", typeOf(function () { return typeof Platform.Function.ContentBlockByID; }), "clrmethodinfo");

/* Cleanup. */
prox.deleteItem("ContentArea", { ID: caId });
</script>

Examples

The single-argument form works when the id resolves to an existing Content Area:

Platform.Load("core", "1.1.5");
// returns the content area's rendered markup
var content = ContentArea(935116);
Platform.Response.Write(content);

The documented 4-argument form does not — it is shown as the documented shape, not as working code:

Platform.Load("core", "1.1.5");
// throws before the error message or fallback content can be used
var content = ContentArea(935116, "impressionRegion", "Could not load content area", "Fallback text here");
Platform.Response.Write(content);

For new content, use Platform.Function.ContentBlockByID() instead.

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

/*
 * Chapter: Examples — the working single-argument form, the documented
 * 4-argument form, and the replacement.
 *
 * Proves:
 *   1. Example 1, the plain 1-argument call, returns the content area's
 *      markup exactly as the docs show — provided the ID resolves.
 *   2. DEV example 2, the full 4-argument call with errorMsg and a
 *      fallback, throws: it fails before the documented errorMsg or
 *      fallbackContent can be used.
 *   3. Because that call throws, Platform.Response.Write() never receives a
 *      value: the variable it assigns to stays undefined, and neither the
 *      errorMsg nor the fallback string is the result.
 *   4. The page's recommended replacement, Platform.Function.ContentBlockByID,
 *      resolves as a host CLR method.
 *
 * NOT ASSERTED: whether an impression is recorded for the region. Parameter
 * 2 cannot be supplied at all, and impression counts only surface in
 * Marketing Cloud tracking reports after a send is processed, which is not
 * observable from within this request.
 *
 * 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 typeOf(fn) {
    try { return "" + fn(); } catch (ex) { return "THREW: " + ("" + ex.message); }
}

/* Fixture: create a Content Area and keep the ID the platform assigned. */
var prox = new Script.Util.WSProxy();
var caName = "ssjsg-ca-" + Platform.Function.GUID().substring(0, 8);
var caBody = "BODY-" + caName;
var created = prox.createItem("ContentArea", { Name: caName, CustomerKey: caName, Content: caBody, IsDynamicContent: false });
var caId = created.Results[0].NewObjectID;
assert("the fixture Content Area was created", "" + created.Status, "OK");

/* 1. Example 1 — the plain 1-argument call. */
assert("example 1: ContentArea(id) returns the content", "" + ContentArea(caId), caBody);

/* 2. DEV example 2 — the full 4-argument call with errorMsg and fallback. */
assertThrows("DEV example 2: the 4-argument call throws (docs: shows the fallback)", function () {
    return ContentArea(caId, "impressionRegion", "Could not load content area", "Fallback text here");
});

/* 3. Neither the errorMsg nor the fallback is ever returned. */
var content2;
try { content2 = ContentArea(caId, "impressionRegion", "Could not load content area", "Fallback text here"); } catch (ex2) { /* documented throw */ }
assert("example 2: the fallback is never assigned", typeOf(function () { return typeof content2; }), "undefined");
assert("example 2: the fallback string is NOT the result", content2 === "Fallback text here" ? "true" : "false", "false");
assert("example 2: the errorMsg string is NOT the result", content2 === "Could not load content area" ? "true" : "false", "false");

/* 4. The recommended replacement resolves as a host method. */
assert("typeof Platform.Function.ContentBlockByID is clrmethodinfo", typeOf(function () { return typeof Platform.Function.ContentBlockByID; }), "clrmethodinfo");

/* Cleanup. */
prox.deleteItem("ContentArea", { ID: caId });
</script>

See Also