ContentArea
→ stringRetrieves rendered content from a classic Content Area by ID. Salesforce documents Content Areas as deprecated in favour of Content Builder blocks.
Syntax
ContentArea(id[, regionName, errorMsg, fallbackContent])
Deprecated. Salesforce documents classic Content Areas as superseded by Content Builder. For new content, use Platform.Function.ContentBlockByID() instead.
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.
The official docs present all four parameters as usable. At runtime only the first one is: supplying the impression-region parameter fails with a resolved-value error before errorMsg or fallbackContent can be used. See Platform.Function.ContentArea for the runnable proof.
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>