A New Approach to Single-Page Applications (SPA) at Bloomreach Connect 2017
Robbert Kauffman
2018-02-26
If you're interested in integrating your React app or any single page application for that matter with a CMS then this presentation is for you.
At Amsterdam's Bloomreach Connect 2017, Rik van de Ven (ING) and Robbert Kauffman (Bloomreach) discussed a new approach to integrating Single-Page Applications with a CMS.
Have a look at the video below.
Can't watch a video right now? You can also find the abstract of the video below.
Abstract:
🧔 Robbert Kauffman:
Today I want to talk about single page applications (SPA) and how we can integrate these with web content management to provide an alternative to content as a service. There we are. The big market trend I'm seeing today is the move to a headless and microservices architecture.
And with that, the rise of single page applications. Single page applications are not just used for web applications, but also increasingly for just regular websites.
Who here uses SPAs today or is planning to use them? Let's see some hands. Alright, a good amount. For those that do not know what an SPA is, perhaps some of the business folks sneak into this room today. Mr. T is upset with you. Now, in all seriousness, let me just read you from Wikipedia. I think this describes this very well.
The single page application is a web application or website that interacts with the user by dynamically rewriting the current page, rather than loading entire new pages from the server. This approach voids interruption of the user experience between successive pages, making the application behave more like a desktop application.
SPAs basically, because of how they work, a lot of the logic is moved from the back end to the SPA. They provide a clear separation of front end and back end and where typically the SPA handles things like the UI, the interactions, the state. The back end handles things like data, querying, processing and exposes that via APIs.
Why would you use an SPA? There are multiple reasons and first and foremost a big reason I see is to separate release and deploy cycles of the front end and the CMS. It's a lot easier to just deploy some updates to Javascript in HTML to your web server or to your content delivery network than it is to do a release and deploy of the average CMS.
Another reason is because a lot of logic is moved from the CMS, the delivery to the CMS to your SPA and that the front end developers no longer or less so, need to work and learn the proprietary framework of the CMS.
Another reason is again, because the logic is moved, there's reduced lock in, and more reasons are like a broader initiative to move to like a microservices architecture. Do you have any additional reasons you'd like to add?
👨 Rik van de Ven:
I think you missed one, which we find is important at least, and I think for a lot of other companies from a business perspective I think in general the experience is better in a single page app.
If you look at traditional websites, it's fine if you're only consuming content, but we are so focused on experience these days, and a single page app is what gives you a great experience.
If you look at it from a technical perspective, I think we are all working in an omnichannel way, if you want to use the same data in a mobile app as in your website. You need to have an API anyway. What's a way to build something on top of an API? It's a single page app.
🧔 Robbert Kauffman:
Couldn't agree more.
👨 Rik van de Ven:
Add those two to the story.
🧔 Robbert Kauffman:
Thanks for that. Those are all very good reasons. Now, what we've seen or what I've seen mostly in the field, the kind of integration approach because of how SPAs work, how they work with the APIs, the logical, straightforward approach is coming to the surface. However, coming to the surface comes with some challenges.
Typically, to use a single page application, typically that's an IT driven decision and often these teams are not aware the kind of limitation this brings to the business, such as having no audited box CMS preview.
The reason behind this is because the CMS is no longer powering the end delivery of the pages, the SPA is doing this, it has no knowledge of how the page should look like and how it can generate that preview. Sure, there are some workarounds, but it's definitely not something you would get out of the box.
Also, drag and drop control with their presentation, those kind of functionality is typically broad or powered by the delivery of the CMS. Once it's no longer in control of that, you lose out on that functionality.
Finally, no control over where content is displayed and appears on the front end. A way to resolve this is to associate metadata with the content, but then you end up garbling the content with metadata, which is not ideal.
It's important to stress that these are all architectural limitations, so it's not necessarily something that limited experience struggles with. You'll see this with other systems as well, because these are essentially architectural limitations.
Fortunately, we found a better solution. Thanks to I'm not sure if they're in the room. I didn't see them yet, but thanks to in part our friends over at Authentic, we came up with a few solutions. Where do I need to point this? Oh, that's better. There are basically four scenarios and solutions and they range in complexity from on the left, low in complexity, to more complex on the right, and the same for the kind of control and the business value they provide to the business. On the left, low and control in control in business value to more on the right.
Let me just quickly take you through them one by one. First, content as a service that is basically taking the raw content over to APIs and consuming that by the SPA. You can do that with the Content REST API that Bloomreach Experience offers.
I'm going too fast. Another one is hybrid. What you're basically doing there is some pages are powered by the SPA and other pages or parts of the pages are powered by the CMS. Now, this has some obvious disadvantages such as that for the pages that are powered by the SPA, you still do not have that control and for the pages that are powered by the CMS, you still have to develop those in the CMS, and you can't do that in the front end framework of your choice.
Now, the other two, those are the ones the last two purchases that today we're going to spend more time on. I'm going to talk a little bit about experience as a service. Before I do that, Rik is going to dive deeper into component level integration, and also before he does that, give some background on which SPA they are using, which framework and why. Take it away Rik.
👨Rik van de Ven:
Thanks. Component level integration, before I can start I need to bore you with some background of my company, ING, because I think there is no silver bullet in technology. What I'm presenting here is what works for us, and I'm going to try to give you a kind of an understanding why this works for us, because this wouldn't work for every company.
I think for those of you who don't know, ING is a bank which operates in a lot of countries, but what people are usually not aware of because when you are a consumer of ING, you know ING as a customer in one country. You might think it's a global bank. In reality, if you look at how we operate, there's a lot of freedom in all the countries.
This is an example of six websites of six different countries, and well it's a bit small but you can see that they are all different. This has grown historically and there is a big disadvantage with coming with this. That's the technology choices. If you look at our landscape, almost every web framework ever invented is being used in one of our countries. From a strategy perspective as a company, we want to move away from this. We want to start to become more one bank, and we want to start to share as much as we can.
That's kind of hard with this technology. We needed a technology to fix that. We looked at how can we fix this. Okay, maybe we just take one technology. Let's move to React. As a challenge with that as well, because this slide is actually from last year, and if I would write this slide this year, it would probably I wouldn't say React anymore but pre act maybe.
If you look at the change speed of all those countries, it's different per country, but it will not be months. If we decide to move to React with all the countries, so that we can share, by the time we are at that technology in all the countries, I think we are five years from now. No one knows what React is anymore.
For us there is only one way of starting to share, and that's based on standards. This clicker is, there we go. For us there was a very interesting standard to solve this, and it's called Web Components. Web Components kind of works well with Hippo CMS but I will get to that.
First, I want to give you a little background on what it is, Web Components. It's a standard which basically gives you four elements, and if you combine these we tend to call it Web Components. The first and most important one is custom elements. What custom elements allow you to do, it allows you to create your own element in the browser, and as soon as you declare it like this, it's available. You can put, in this example, you can put a my element anywhere in the DOM, and as a user and a browser, you will see a big hello and small I am a custom element, which is the HTML I put in attached to this element. This allows me to start to work with my own components.
I want to do more. I want to take the HTML out, and I want to do some templating, because in reality, I don't only want to put HTML in there. I often want to put some data in that HTML. Some things might be conditional, so I need a templating engine. That's there in the standards as well. It's called HTML template. HTML template allows you to design your templates and do all the stuff you would do in any templating engine, but again it's a standard build in through the browser.
If you want to make real components with this, they need to look good. We need to be able to style them. They need to have behavior in Javascript. We have that goal of using one component, building it, centrally within ING maybe and putting it in six websites with six different looks and feels, six different style sheets, six different Javascript framework.
We need some way to do that. Well, there's another thing in the standards, which is called the shadow DOM. What the shadow DOM does, it will allow you to have to add something to the DOM, which will not be part of the DOM. It's similar to virtual DOM in React, but again in the browser. Your browser will make sure that whatever you do with the shadow DOM, it's contained in that part.
In this example, I make a paragraph red. The result of this will not be that all paragraphs in the page will be red, only those paragraphs, which are inside this component. This is very important to do styling in a proper way. Last but not least, is HTML import and what HTML import allows you to do is take all that code you're writing your component, put it in an HTML file, and import that in any application or page wherever you need it.
These 4 combine our Web Components. An example for the page would look like this if you see the page at the right. This could be a simple mortgage page we create. The HTML markup is to the left. I will zoom in to some bits of it. If you look at this, it could be the entire page, all the code we need. Because it's doing a lot of imports, so if you look at the half, we first import Web Components. That's because normal browsers haven’t implemented the standard yet. We need to implement something to fix that. Then, we implement the 4 components which we use on this page. Let's zoom in to that one.
One is page digital. In this example that's the Web Component, which contains all other components. What this Web Component does, it creates the entire markup of the page. It might put a menu on top. It will put a header on top. It could put a footer at the bottom. It just kind of gives you your framework for your page.
Then the last thing remaining is that we actually have the Web Component for instance, the product card, and as you can see this Web Component is also it has no mark up or nothing. It just has the content, which you see on the page as properties. The Web Component, which we import will do the rest.
If you look at this HTML, it's quite simple. I would like to demo how this works with Hippo, because I think they kind of work together very nice. What I did, ooh this is the page I just showed now, with that simple HTML. It's managed in Hippo. I can go into the CMS. What I like about this approach is, for Hippo, this is just HTML. All the functionality I normally have available in Hippo is still available. I can drag these components around. It's no problem. Just works. I can do inline editing of the content and that should also work. Let's see. If I change some text and so as you can see, there's not much of a difference between the experience you normally would have with Hippo, or the experience with Web Components.
What I'm going to do now, and this is what I like, because all the actual markup is in the Web Components, I can replace the Web Components easily. I will check out another brand of my Web Component. Wait, let's just connect this. It is a brand I created for today. If I now go to another page in the general manager, it will get a different definition of my Web Components, and suddenly, I have a completely different website.
I could have a different menu. I have a different filter. The same goes for the site, which is running. It's just a completely different website. Content editing still works. I can still drag around these components. I can still do inline editing if I want.
🧔 Robbert Kauffman:
To clarify, this doesn't touch any of the code in Hippo CMS, right, when you check out?
👨 Rik van de Ven:
No. The check out I did is only static files of Javascript, HTML, and CSS, which are completely outside of Hippo CMS. I think I may have a slide on that actually, which probably is the next slide. This is the set up which I just demoed. What I did I put Engin Ex in front.
I have a normal Hippo installation, but the Hippo installation only is one component, the one I can show as well, if you look in the CMS. That's where it's a bit limited. If you look at the components I have available here, it's only the Web Component component. It's the only component we give to the content editors. With this component, you can select any Web Component we have, and it will just render the content of a document attached to it into that Web Component. That's the trick.
That's how we work. What this gives us next to this flexibility is that we, if you look at most of our changes, our changes are more often in styling and in look and feel than actually in our document types. With this, we have experience with deploying front end code and testing front end code automatically from our apps, which allows us to put this kind of code in production as many times a day as we want. For instance, we have days where we go live with the entire front end 14 times a day. It's not a problem.
In this setup, we can do the same for all the components we use with our CMS, which for us, gives us a lot of agility of changing everything. Important thing there is that I kind of connected everything by convention. There is no real code saying these are the Web Components you can use with this document. It's all very loose.
I can use any document type. I can connect it to any Web Component. Depending on the Web Component, it will either look good or not, but you will see that in the channel manager. It's total freedom. If we introduce a new document type, fine we can use it with the existing Web Components. If I want to change the Web Component, it's all fine.
That's how we think we can do public website and how we are doing it now. That page digital quite often can be a single page app. For that scenario, this would kind of work, but if page digital is a smart single page app, and it understands deep linking, it might still work, but I think we are kind of missing something. For that, I'm going to have Robbert continue.
🧔Robbert Kauffman:
We have another solution. It's a nice segway into Experience-as-a-Service (EaaS). It's like the last approach of the four approaches I laid out earlier. Experience as a service, what is it? It basically offers a native-like, seamless CMS experience while using an SPA. With native-like, I mean the same kind of authoring experience you have when the CMS is also doing the delivery, when the CMS owns the glass or like Mike earlier this morning said, when experience led.
You have all the functionality out of the box, like an integrated CMS preview. You have drag and drop control over the presentation. You can create pages in the CMS and it might seem like a very small marginal point, but I’ve actually seen situations where they're reusing content as a service.
To create a landing page, they would have to create a route in the single page application. That task involved a front end developer, while it should be just an editorial task. Finally, you can also use all the great enterprise grade features such as personalization, AB testing, and so on.
Now, the use case for experience as a service is when you have a more complex SPA, when component level integration might be more challenging to use, and also when you're using frameworks such as Angular 4, that need to be in control of the DOM and don't even work with the earlier approach.
Let's move into the demo. I've got another demo set up right here. I'll dive into the architecture afterwards to give you an understanding of how it actually works.
Alright. I got my React application right here. It's a very simple website but the idea here is it's more like a tech demo. It's not a full fledged website and to prove that it's actually a React application, let me view the source. As we can see here it's just some static HTML for the header and the footer, and then I have like one development where the application it's pushed up to that contains all the banners and the content, and so on. I have a bundle.js, which is actually the React application.
Now, so far that's nothing too crazy. Where it gets exciting is, as soon as I go into the CMS. I have one to one preview so this is my React application that you're seeing. The React application is powering this preview. It's one to one. You don't have to maintain the HTML in multiple places. It's entirely accurate preview.
Now the exciting stuff is that you still have the CMS functionality here. If you click on edit content button, I can change any of the titles. I can save it. I immediately see my changes. I have drag and drop that I can use. I can add new pages. If I go to page and say new and click on create, then I can create new pages and just drag and drop any of my components onto that page and create my page that way. It will immediately be available as soon as I publish it on my single page application.
You also can use things like personalization. If I go back to the home page, I've got a banner right here. Over on the left side is my personalized variance. I have one for the Wednesday special, which you can see. You can preview those if I switch to the alter ego. What you'll see is that you can also have the preview here and it also works on the live site.
At the same time you also have the notion of preview so while I've updated my title of that banner, if I go to the live website, it will not be there yet. Let me try to open that page that I just created. I think this is my awesome new page. It will not be there yet. As soon as I publish my changes, that page should be visible. You still have that same notion of live versus preview. Pretty much the same experience you would have when you are using the CMS, natively.
Alright. Let's go back to my presentation and so how does it work.
👨 Rik van de Ven:
Do you want me to support it?
🧔 Robbert Kauffman:
So, how does it work? It exposes pages or the experience through the experienced API and has then consumed by the single page application. Now, that's for the live site. For the preview, there are two additional things, the SPA powers the CMS preview, so you have that accurate preview in the CMS.
To provide all that CMS functionality, like the in context editing and the drag and drop, the API returns also some metadata that the SPA then inserts in the HTML for rendering all that CMS functionality.
Now, all of this is powered by the Experience API and it's basically a framework agnostic REST API and exposes the aggregated page structure. It can be used with any SPA framework, whether that's angular or React or viewed. There's so many nowadays. It also includes any of the associated content on that page, and all the containers and the components within those containers and any variants for personalization or AB testing. Finally, also the CMS metadata that's important for the CMS functionality.
For the live sites, the architecture is as followed. Over here I have a page with some HTML. It's rendered by the single page application. There's a header, a footer, a main section with a banner, a product grid, and a news list. Now, those are all SPA components. Those are defined in the SPA. Once the SPA initializes, it does a call through the Experience API and that gets the page structure, any content, from the Experience API. Basically, it's just some JSON that it gets back and it tells the SPA I want you to render a main section, with these components and a column with apparently no components.
It tells the SPA what to render on that page. It can be for every page it can be different depending on what the author has put on that page. Now, it's a little different so these can be managed in the CMS as you saw on the demo. It's a little different once you go into preview. Over here, I have a CMS user who previews the page in Bloomreach Experience, and that SPA is loaded via the base layout at FDL.
That's the only free market template you would have to set up. It's basically just loads the SPA using the Javascript like the bundle JS or however you want to load the SPA. Alternatively, you could even run it on your note server, and reverse proxy it into the CMS, but it introduces some security risk so I would stick to this approach.
Now, it then serves back to the HTML to the user and then the browser starts loading the SPA, starts initializing. Then, as the SPA initializes, again this is the same thing, calls the experienced API and gets the content, the CMS but now because it's preview mode, it also gets the metadata from the Experience API. It doesn't do that on the live site, to not put any unnecessary mark up in your HTML.
Now the SPA then renders that page and additionally it takes the metadata and turns that into HTML comments that it puts into the HTML. Those are some HTML comments at the start of the container, at the end of the container, the start of the component, the end of the component, that's actually what we also do in free marker in Hippo. I lends itself very well to the SPAs.
To kind of recap briefly, we have four scenarios and solutions. They range in complexity but also in the kind of control and value they provide to the business so with content as a service, you're very limited. You're basically go back to a form based way of managing your website. Fortunately, with two of the approaches we discussed today, you can still half that control and manage your website in a very intuitive way, while you manage the templates, in the front end framework of your choice.
That's really what I wanted to share with you today. If you want to learn more, if you want to look at some code, feel free to drop me an email or the general email, [email protected] works too. I'll be around for the rest of the conference and I'll just be walking around too, so feel free to tap my shoulder and ask more. I'm happy to talk more on the topic and I think now we should have some time for questions.
🎤 Moderator:
Any questions?
👥 Audience Member:
I was wondering how the last approach would work with the site map that is exposed from the CMS?
🧔 Robbert Kauffman:
That's a good question, so that's basically a choice you can make. One thing how we did it with the React application I showed is that for any URL that you request or say I go to slash news, it would try to do that same request to Hippo to get basically that page back through the Experience API.
Basically, it takes that path, the path of your URL, and puts that path in the query to Bloomreach for the Experience API. Then you get the news page back or whichever other page your visiting. That's a way and then you're still maintaining the site map in Bloomreach.
Another way is you could also expose all the sitemap items, whether those are content driven or whether those are clearly defined and expose those over in API to basically insert those as dynamic rods between the applications. They could also work. I choose the former approach because it was free and easier to set up.
👥 Audience Member:
Have you managed to make the experience as a service approach working angular using ahead of time compilation because it seems like JSON is going to dictate conditionally what's rendered, but when you're using ahead of time, there's no render engine in the browser. Does this approach work there?
🧔 Robbert Kauffman:
Yeah. It's basically it would serve your site rendering, yeah, because it's the same if you use server side in React. The challenge there or the approach we took there staples is also taking this approach. We ran into there where they use I believe it's electrode for server side rendering. Basically if it's service site rendering, yeah. Then you run into some challenges. What we do there is we have some not really server side rendering another way of rendering it for the preview.
Then, for the live site, it uses that server side rendering and that is basically a cached version of the API it gets back. You can still take that approach. The only area where we run into some challenges is in the preview is when you try to make these changes, because ahead of time will just be a static version of that, which you cannot change. You would have to apply that work around, that you have also a client side version of that application, for preview mode.
🎤 Moderator:
Thank you. Any other questions? I don't know if everyone heard but the question is for the audience, whether anyone has seen something like this with other platforms out there?
🧔 Robbert Kauffman:
It's a good point. It's something we developed. It's relatively new. I haven't seen it with other products. I think how the channel manager works lends itself very well for this approach. It's something that I haven't seen anywhere else in the field. We think it is something differentiating. Yeah, if it's not, then I'd love to know.
🎤 Moderator:
Okay. Thank you both. That's then the end of the presentation I guess. It's a bit earlier than expected, but I think nobody would mind having lunch a bit earlier than expected. After lunch, there's going to be an amazing presentation here, so I would advise you to come back, but I'm not going to say much more about that yet. Okay. Enjoy.