June 06, 2019
We recently started sending production traffic to a new JSS instance after about 4 months of dev work. The aim of this post is to explore a few of challenges we hit - specifically around how to build out the application. It's a follow on from the intro to going live with jss.
Feature ###, oh that just comes out the box
I'm sure we've all been there, the sales pitch paints an all singing all dancing solution - you estimate a story and weeks later it's still in development. To be fair to the JSS team their sell was very measured, that JSS provided the bridge to Sitecore and then it's down to you to build out your Vue/React/Angular app.
JSS all the things
It's still early days for JSS so the industry examples and 'best practices' are still emerging.
If you have an established Sitecore solution, migrating over to JSS won't be an overnight thing. We had a 4-month-old Razor project, added JSS to the mix for just some new pages and it took us about 4-5 months to get live.
A few upfront requirements
Our deployment isn't the simplest setup for various reasons. A few of the items listed later were done specifically to work around these challenges - I'll flag them up when we get to them.
Our setup has the following quirks:
- We sit behind an external proxy and WAF
- The url structure contains sites on a range of urls and language parameters:
- www.url-name.co.uk for en-GB content
- www.urlname.it for it-IT content
- www.url-name.ca for en-CA content
- www.url-name.ca/fr for fr-CA content
In the traditional Sitecore application this is all managed with the <sites> configuration.
What did we find out along the way?
Here are a few of the things we missed in the 'memo' when we started out. Each added noticeable time, dev effort or bugs to the progress of the project - I'm hoping you won't hit the same issues! :)
SSR vs CSR modes
If using the SSR proxy you need to be careful you don't rely on accessing properties which are only available at the client. Examples being things like window.location. If you do, when you run the site in SSR mode these will error as window doesn't exist.
Package managers - changing the core libraries
If you are using the proxy, chances are you'll be consuming @sitecore-jss/sitecore-jss-proxy. But, what if you need to edit the core behaviour of the package? Either you could store a copy of the code in your local solution and edit directly or apply a patch to it.
We extended how the proxy worked to play nicely with site resolution, so patched in the changes via the npm package: patch-package. You store a transform in source control which the package helps create and then gets applied during npm install. This was favourable to storing a copy of the Sitecore code as any changes they make wouldn't be reflected in our codebase.
Let's assume you are performing blue/green deployments and you host your site out of more than one region in the cloud. Chances are users could route through either region and/or colour.
For debugging purposes, we include http headers to provide all this information - sharing information from the Sitecore application and the JSS proxy.
Site resolution and language resolution
Most of the complexity we encountered here was related to the URL structure we needed to adhere to, so this item might not be applicable to everyone. In summary, the current version of JSS doesn't have the concept of site resolution hence you need to roll this yourself.
We built a basic implementation of the <sites> logic you get in Sitecore which provides the ability to hot-swap the behaviour of the proxy and append on the sc_site=... querystring to any layout service call. One thing to note here if using the proxy, you will want this logic available in SSR and CSR mode.
This was patched into the core implementation of the proxy with the patch-package library. We also disabled the use of the sc_lang querystring when calling the layout service as we relied on sites for language instead.
The final change was to update dynamically the url that JSS calls for the layoutService. This was done in config.js in proxyOptions. We added the router property to adjust the core url to call.
The JSS team provide an OTB transition graphic that's visible when making a routing change. It's trivial to change, but don't forget to unless you want the JSS gif flashing every time a user changes page.
To GraphQL or not to GraphQL
We won't use GraphQL in the foreseeable. Now I appreciate this could be quite a contentious suggestion but let's explore why:
- We have well established and highly performant tools for working with Sitecore content
- The team are very skilled in this sort of thing
- Content Resolvers (and Context Extensions) provide a strongly typed, and unit testable way of injecting content into the layout service output
Harnessing the power of webpack
You can achieve some very powerful results with webpack, in particular around what the local developer experience is like. I'd recommend for anyone getting going with JSS, invest some time in finding out what webpack can offer.
We've customised our version to provide things like: custom dns and ssl in dev, aliased asset and module resolution (import ### from @services/urlService in favour of import ### from ../../../services/urlService) and some improvements around SCSS resolution.
Out of all the items here, this was by far the biggest time runaway. You get basic error handling OTB so in its most basic form would just need to re-skin that page.
In reality the logic to handle the different types of errors (400s vs 500s), and the fact these need handling in CSR and SSR modes really increases complexity. You then need to work out where to get the (multi-lingual?) content from these pages - from Sitecore? But what if Sitecore is broken?
One example of a simple requirement that took a lot of work was telling on which page the error was thrown. In one of the cases we had to rework how we use the Vue router as errors could be thrown before the page was updated. We definitely missed that one in the memo!
There are quite a few items here but don't let that put you off! The experience of working with JSS has been a very positive one.
Moving forwards the whole team are eager to really exploit the benefits we can now reap from a SPA and over time add more and more features into the application.