Using Adobe IO to Support Server-Side Rendering
Many web applications are written using client-side single-page application (SPA) frameworks, like ReactJS and Angular. Doing so has many advantages, however, it does prevent a slight challenge for search engines like Google to effectively index content on pages and make them available to a Google search. There is a common solution to this called Server-side rendering. “Server-side rendering (SSR) is a popular technique for rendering client-side SPAs on the server and then sending a fully rendered page to the client. This allows for dynamic components to be served as static HTML markup.”
It is common to execute directly against a NodeJS server to accomplish SSR, each with its own respective costs associated with them. With all requests coming through the AEM runtime, teams need a direction on where to send client-side requests to be rendered server-side. Adobe’s recommendation is to route these requests to Adobe’s IO Runtime. This blog post will outline the technical design for executing SSR within your AEM Environment.
First, Adobe IO Runtime (What is it?)
“The Adobe I/O Runtime is a serverless platform that allows you to quickly deploy custom code to respond to events and execute functions right in the cloud, all with no server set-up required. Developers can run code on top of our Cloud solutions, bringing Adobe services together with APIs.”
To execute against this serverless environment, you are required to register a new project with the IO console. This operation is within the console: https://console.adobe.io/
For this project, you will need to enable IO Runtime and request namespaces for each of our workspaces for us to execute against. When creating the project, you must make sure you select the Project Firefly template.
The following screenshot illustrates the SSR Project that we set up:
Namespaces (Project Firefly)
There is a namespace for each workspace.
These namespaces are required to deploy your applications. Each application will deploy to these single namespaces. You don’t want to have multiple namespaces per environment.
Deploying your App to IO
Scripts: AEM Processor
Once your app is ready, you will need to create a ui.serverside module in your codebase. Once the module is created (please see the reference example as part of SSR-Adobe-COE codebase), you will need to update your ui.frontend module to build your app to execute serverside. Luckily, Adobe provides us with a utility to create the app by using a script called AEM Processor:
The aem-processor.js is responsible for compiling your ui.frontend into a ui.serverside application that we can deploy to Adobe IO Runtime. This is nothing more than your frontend library consolidated into a single-entry point or action called SSR.
In the package.json of your ui.serverside module, you must name your serverside application and supply it with a version.
Please NOTE: you must maintain the version number of your serverside application that you are deploying. This is done manually as part of the package.json file in your ReactJS app.
In order for Adobe Runtime to know where to deploy, you are required to update the .env file in your ui.serverside module:
Adobe IO Environment Configurations:
When deploying from your local machine, run the following commands:
When complete, it will look like this:
Where… • https://24244-ssrapp-stage.adobeioruntime.net = namespace • RJS-react-package-1.0.0-SNAPSHOT = application-name-version from package.json • ssr = action
Deploying via TDP (CI/CD) Pipeline
You have a couple choices when considering how this impacts the CI/CD pipeline. You can perform the deployment during the compilation process, or you can perform it post compilation.
Compilation Process (Using Jenkins):
Customize the pipeline’s maven command execution to add additional steps to perform “aio app deploy” from the ui.serverside module. This gives the possibility to not commit the app.js into the codebase but just use the generated file during the compilation to deploy to AIO Runtime.
Post Compilation Process (Using XL Release):
Customize the XL Release workflows to add an additional custom step to execute the “aio app deploy” command by checking out the repo and diving into the ui.serverside module. The dependency for this approach is to have the app.js file committed into the repository.
Note: It is also a good practice to remove older versions of your apps by purging your app.js file.
Routing your request to SSR
AEM Factory Configuration Settings
To route your SSR request to Adobe IO, you will first need to create a runtime configuration to store the Root Path, React Server Path, and whether you want to send the code to be processed server-side. Please see the below screenshot.
To test the performance of the SSR, you do this in the context of the pages that are being rendered as part of SSR. You will want to also write load test scripts (we used Flood IO scripts) to test the execution of pages from a browser through the CDN, through the dispatcher, through the publisher, to Adobe IO.
For this test to be considered successful, the flood IO script must clear the CDN cache and the dispatcher cache every 5 requests in order to ensure the proper load is tested on Adobe IO.
Server-side rendering is required to support Search Engine Optimization. Adobe recommends the use of Adobe IO Runtime to execute ServerSide Rendering (SSR).