JSS (React) Dynamic Layouts - Part 4: Disconnected mode and auto-generated layoutMap

Final part (I promise...)! We tie up all loose ends by adding layout data to the disconnected layout service mock, and by making the whole workflow as automatic as the OOB workflow for renderings.

Homestretch... There are just two elements missing that we need to fix in order to have full support for dynamic layouts in every mode and scenario:

  1. In the last part, we made sure the layout service included layout data. This only works in connected and integrated mode though, when there is a sitecore instance on the other end. What about disconnected mode? 
  2. In the first part, we created dynamic layout support by manually mapping layout IDs to layout react-components, which works fine with a sitecore-first workflow. All subsequent parts have been about building support for a code-first workflow, and in order to finish this we need to remove this manual step. But how?

1. Disconnected mode

The first thing we need to implement is a step in our code-first work process: Each time we define a new route file under data/routes, we add a layoutName property on the first level of the yml, like below:

route-example

Agreed? Good. When working code-first, we define these routes ourselves anyway, so it's just another property to add.

Now, on to how we fetch this data. I have leeched heavily on Corey Smith's post on extending the Layout Service rendering data, specifically the part about disconnected mode. I'm gonna give you the gist: When you run the jss start command (which starts the app in disconnected mode), a server-proxy script is invoked (scripts/disconnected-mode-proxy.js), which spins up an express server with mock APIs. We need to extend this to include layout data in the Layout Service API mock. The script calls a function createDefaultDisconnectedServer(proxyOptions). This proxyOptions object has some functions that we can extend, for instance a customizeContext function which we will use.

Simply add the below property to the proxyOptions object in scripts/disconnected-mode-proxy.js:

customizeContext

And we are done. Disconnected mode now supports specifying the layout in the route file.

2. Auto-generate the layout map

In part 1 we manually mapped layout Item ID to the correct layout react-component. Now, we want to automate this process. If you look under scripts/, you'll notice a generate-component-factory.js file. This script is invoked on build to autogenerate the component factory (i.e. "renderings") and we really just want the same thing for layouts. So again, copy-paste thief as I am, I copied this to a new script file that I called generate-layout-map.js (see, I don't even try to hide it) and modified it for the layout map (I didn't even remove the comments, just modified them. Somebody stop me). Now, I've done it a bit different than the componentFactory, which is responsible for both keeping the map record as well as serving the components to the RouteHandler. I still want the LayoutFactory we created in part 1 to take care of serving the layouts, I just want the layout map autogenerated. So I made the script as below:

generate-layout-map

Now, every time you build (or when hot-reload is active when you're developing) a layoutMap.js file will be generated under src/temp/.In order for this to work, the component file name for each layout needs to be index.js. It probably should have been from the start anyways, so let's go ahead and change that. First picture is before, second one is after. Adjust file names accordingly:

 Old layout file namesNew layout file names

We also update src/layoutFactory.js that we created in part 1 like below (using the new layoutMap):

layoutFactory

Now the last thing we need to do is simply include this auto-generate script in some other scripts, so that it will be invoked at appropriate times. For starters, add the code below to the end of scripts/bootstrap.js :

require-layout-map-bootstrap

Lastly, simply adjust the specified scripts under the scripts section of your package.json file as per below:

package-json-scripts

And that is it! And this time, I actually mean it. Full support for dynamic layouts including code-first workflow and disconnected mode.

Only took four posts....

 

22 Jan 2019, by Bonny Nilsson | 

JSS, Sitecore 9.1, Layouts, Disconnected mode, Code-first