Working with Server Side JavaScript
Introduction
You can execute server-side JavaScript (SSJS) in components and design parse files by including the runat="server"
attribute when using a <script>
tag.
For example:
<script runat="server">
print('<h1>%asset_name%</h1>');
</script>
You can also execute a JavaScript file by sourcing it using the src
attribute, for example:
<script runat="server" src="./?a=XXXX"></script>
This functionality is similar to that of the JavaScript processing field on the REST resource JavaScript asset.
When used in components, SSJS is not processed at the time of the processing of the component content. Instead, it is processed at the global level along with any global keyword replacements. |
Global variables
You can set global JavaScript variables which other components can access in the page processing.
For example, if you have a nested standard page at the top of my design parse file code that has the following SSJS code:
<script runat="server">
var userName = '%globals_user_attribute_username%';
</script>
You can then access the same global variable at any other point in the Matrix page generation, either in another component or in the design parse file code:
<script runat="server">
print(userName);
</script>
Attributes
You can pass additional attributes into the <script> tag for the server-side functionality, including:
- Runat="server"
-
Enables the JavaScript code within the tag to run server-side.
- Evalkeywords="post"
-
By default, keywords are evaluated before the JavaScript is processed. Adding this attribute will make the keywords evaluate after the JavaScript has been processed.
This only applies to global keywords. In-context asset-specific keywords such as %asset_name%
will always need to be evaluated in the context of where they are printed. - Log="log_prefix"
-
Adding this attribute will log any output from the JavaScript as an entry into the Matrix system log. The value of the log attribute will prefix the messages that are printed through the JavaScript
print()
function.
Performance mode
You can see metrics of the performance of the server-side JavaScript within performance mode. For example:
Three entries are shown under the asset the JavaScript block is executed under and includes:
- Process server-side JavaScript "pre" keywords
-
Time to process keyword replacements before the JavaScript has been processed.
- Process server-side JavaScript
-
Time to process the JavaScript code.
- Process server-side JavaScript "post" keywords
-
Time to process keyword replacements after the JavaScript has been processed.
Disabling SSJS
You can disable all JavaScript from running on the server using the runat="server" method by adding the following query string parameter to the URL:
?SQ_DISABLE_SERVER_JS
The JavaScript in the component will print within the HTML source and execute client-side as standard JavaScript. This allows debugging of the JavaScript within the source code of the page.
You need to have write access to the component for this query string to take effect. |
Viewing SSJS
If you have write access to an asset, you can append ?SQ_VIEW_SERVER_JS
to the URL when previewing it on the frontend to see a complete output of the JavaScript code that was sent to the JavaScript engine in Matrix.
This is useful if you are getting JavaScript errors on the frontend that relate to a specific line number in your code, as you will be able to track down exactly which line the error is referring to.
For example, if you received an error similar to the one in the example below. The error points to line 20 in the JavaScript code.
Viewing the frontend page with ?SQ_VIEW_SERVER_JS
appended to the URL, you can see to which line the error refers.
You can also use JavaScript comments to help indicate from which specific asset each JavaScript block is coming.
Processing order
It is essential to understand how Matrix will process keywords and SSJS and the order in which these get evaluated.
Essential rules to remember for keyword replacements:
-
Asset keywords always get replaced in context (that is,
%asset_name% in standard page and asset listing type format components and %frontend_asset%
keywords). -
Global keywords get replaced further up but before all SSJS by default.
-
Global keywords in SSJS with
evalkeywords="post"
attribute get replaced after all SSJS.
Matrix also replaces global keywords and processes SSJS in two separate places:
-
At the globals level
-
In the design parse file.
Therefore, the Matrix processing order of these are as follows:
-
Components - asset & frontend asset keywords.
-
All global keywords.
-
All SSJS.
-
All global keywords in SSJS with
evalkeywords="post"
. -
Parse file - Global keywords.
-
Parse file - SSJS.
-
Parse file - Global keywords in SSJS with
evalkeywords="post"
.
run_SSJS keyword modifier
Sometimes you might want to execute SSJS code within the contents of an asset earlier than at the global level. For example, when using the contents of an asset in a trigger action.
To do this, you can use the ^run_SSJS
keyword modifier to execute any SSJS code found within the contents of a keyword as a separate processing thread.
For example:
%globals_asset_contents_raw:1234^run_ssjs%
Examples
This section will show you some examples of how you can use SSJS and the different outcomes you will get depending on what keywords you use and how you print the code to the frontend.
Basic example
This example will conditionally print a <metadata> SEO-based section tag based on the value of the current frontend URL the user is viewing.
<script runat="server">
//Create a variable with the current frontend asset's URL
var frontendURL = '%frontend_asset_url%';
//Create a variable for the section string
var section = '';
//Set the section string based on the section where the current URL is located under
if(frontendURL.indexOf('/manuals') > 0){
section = 'Manuals';
}else if(frontendURL.indexOf('/tutorials') > 0){
section = 'Tutorials';
}else if(frontendURL.indexOf('/news') > 0){
section = 'News';
}
//Print a metadata tag for the current section if it is not empty
if(section != ''){
print('<meta property="article:section" content="' + section + '"/>');
}
</script>
This SSJS code could then be placed somewhere inside the <head> tag of the page design.
List assets from a metadata related asset field
This example takes a list of assets from a related asset metadata field and loops through each one to print information about each asset in an unordered list, similar to what you might use an asset listing for.
<script runat="server">
//Store array of assets from metadata field into a variable
var assets = %asset_metadata_related^json_decode^as_asset:asset_name_linked^empty:[]%;
//Only run if there are actually any assets in the array
if(assets.length > 0){
print('<ul>');
//For each asset, print the value
assets.forEach(function(asset){
print('<li>'+ asset +'</li>');
});
print('</ul>');
}
</script>
The critical thing to note is that the keyword will be replaced before the JavaScript is processed. So the JavaScript will see an array of data directly assigned to the assets variable, rather than a keyword string.