NoA Ignite logo

A closer look at Episerver’s (currently Optimizely's) SPA framework

March 17, 2021 / 5 min read

Generalised and simplified application layers

In May 2020, a team of Episerver’s (currently Optimizely's) developers released a project called “Foundation Spa React”. The exemplary Foundation SPA React project consists of two parts: Back-end and front-end. You can think of it as an exemplary or boilerplate project of a SPA website. It features a SPA JS library, also created by Optimizely's team. Spa-core is basically a framework that aims to streamline the Optimizely SPA website creation.

Book your on-the-house consultation

Let's talk

We decided to analyse this whole project more thoroughly in this blog post. Here, we are going to focus on technicalities – the project’s structure and configuration. Let’s dive in!

The foundation SPA React project

The exemplary Foundation SPA React project consists of two parts: Back-end and front-end. The front-end part of the project is built mainly on React, Redux and the foundation-lib-spa-core library. The foundation-lib-spa-core is a library (or even a framework) also created by the authors of the Foundation SPA React, and it also uses React and Redux. This library takes care of a lot of standard SPA problems (e.g., routing and dynamically content loading). It also includes the React components for the Optimizely CMS properties (e.g., content area, XHTML, etc.). Those components also ensure that the WYSWYG (on-site editing) experience works correctly.

The back-end part is an Optimizely application. One interesting fact is that the standard Razor-view engine has been replaced with a custom implementation that uses the V8 JavaScript engine. However, it shouldn’t be difficult to change the JS engine to something else. This approach enables what is called Server-Side Rendering (SSR), which can potentially increase page loading performance and enables better SEO properties for the SPA project.

When the browser opens the page, a prerendered version will be fetched from the server and displayed to the user. The rest of the data will be loaded dynamically via XRH requests made to the CDA. It is worth mentioning that the Optimizely's project implements some custom controllers that extend the CDA functionality and execute custom actions.

Developers can customise a page by defining proper models, views, custom service and states. The framework will then render proper views depending on the content that needs to be displayed. A nice feature provided by the Optimizely developers is the possibility of synchronising back-end Optimizely content models with the front-end application code. At this point, we have to note that the front-end content models should exactly match the ones on the server, as the foundation-lib-spa-core framework expects them to be identical.

The Episever’s (currently Optimizely's) SPA project structure

In fact, the Foundation SPA React page solution consists of several projects. Almost all of them are back-end-related. Only one of them is strictly front-end-related (Spa.Frontend). However, we reckon it shouldn’t be too hard to extract it to a different solution and keep it separated from the back-end code.

The front-end part of the foundation project relies heavily on the lib-spa-webpack:

the lib-spa-webpack

the lib-spa-webpack2

The second one (foundation-lib-spa-core) implements a lot of features that aim to help with SPA development.

Now, let’s take a closer look at the structure:

the spa structure

  • Foundation: It’s a Web Application project. It contains configurations, startup routines, static assets and the construction of the SPA page.
  • Foundation.Cms: Includes elements like page and block types, view models, descriptors, attributes etc.
  • Foundation.ContentDelivery: Adds and enhances the content delivery API with extra controllers and models.
  • Foundation.Find.Cms: This element is code-related to episerver.find.
  • Foundation.SpaViewEngine: It’s an implementation of a JS view engine that is capable of server side rendering (SSR).
  • Spa.Frontend: Typescript project, SPA implementation.

Episerver’s (currently Optimizely's) SPA model synchronisation

A welcomed feature provided by the developers is the possibility (or, in this case, rather a need) of synchronising the back-end Optimizely content models with the front-end application code. This synchronisation comprises elements like pages, blocks, media, categories etc.

The foundation-lib-spa-core element contains a script that makes an HTTP call to the Optimizely content delivery API, to pull the models’ definition. Then it generates typescript models based on the response. Mind you; the generated models should not be altered manually. The reason is twofold:

  1. The spa-core library assumes that those models are identical as those in the back-end.
  2. The next epi_sync_models.js script execution will overwrite all manual changes.

Optimizely SPA: Creating page type and view

Extending the project with a new page type and the view is relatively straightforward. You need to do two things:

  1. Add a new page definition that inherits from FoundationPageData. The Foundation FoundationPageData contains a lot of common properties used by the exemplary site.

FoundationPageData

  1. Add a view definition on the front-end part. Before you add a new view to the application, you have to sync the models first (prior solution build required).

spa example

Your page type should be present in the Models folder:

the Models folder

The next step is to create the page view class:

the page view class

In this straightforward example, we used the Property component (which is just one of many things provided by the spa-core library). This component is responsible for: 3. Rendering a particular property (it will handle various property types, e.g., strings, numbers, XHTML, references and content areas differently). 4. Adding proper attributes that enable the on-page editing experience.

the spa proper attributes

In these few steps, we’ve created a new page type and a corresponding view. As you can see, the framework deals with many things for you. For instance:

  • On-page editing
  • View routing,
  • SSR (Server Side Rendering, crucial from the SEO point of view)

As you can also see in the picture above, a global layout is applied to your page. You can easily change it by modifying the MoseyLayout.tsx file or, even better, replacing it in the Config.tsx file (the next section).

Overview of the application configuration

The Config.tsx file in the SPA.Fronted project contains the page configuration. The AppConfig has some amazing properties, like, for instance:

  • Optimizely URL
  • Global layout
  • Spinner component
  • Preloaded components list, and many more

It also allows you to define custom modules that should be implemented in the IInitializableModule module interface.

the IInitializableModule

  • ConfigureContainer: Enables injecting services. These services will be available whenever you have access to the context object.
  • GetStateReducer: The whole thing is running on React and Redux. This solution allows you to add our own state reducers to the application.
  • StartModule: Gives an opportunity to execute some code during application initialisation.

Of course, these are just some of the basic things about the SPA foundation project. There is a lot more you can do with it.

People discussing. The photo focuses on the laptops and a cup of coffee.

Book expert consultation!

If you want to talk to our experts about this article or related question – just reach out!

Author

Daniel Domurad a .NET Developer in NoA Ignite Poland

Daniel Domurad

Daniel is a developer at Noa Ignite with a background in backend, fronted and devops technologies. Currently he's working mostly with Optimizely, Umbraco, React and Azure. After work Daniel spends most of his time being a parent, playing boardgames, painting miniatures and running D&D sessions.

post.ukxyz@noaignite.com

Related articles

Back to all articles