The Greenland Project - A server-side rendered story

The aim of the project was to try and make a server-side rendering (SSR) application in Laravel.

My motivation for starting this project was simply to learn and form my own opinion about SSR and the advantages/disadvantages of using this approach.

To make my journey a little bit more interesting, I decided to make something more than just a "Hello World" example project.

Therefore, I started the The Greenland Project and the original intent was to make an interactive SVG map of Greenland (yes, the country that Trump wants to buy, see BBC). In the end, I didn't quite reach my goal, but more on that later.

The project

The SVG map was written as a VueJS component, that utilized D3 to parse and render a GeoJSON object to the DOM.

On the server the component would be parsed and rendered by Laravel / Node and served as part of the initial DOM.

VueJS Component

The component is built using the recommendations on ssr.vuejs.org. The outline of the project is the following:

# This is the actual component. That renders the map and 
# fetches the context.
Greenland.vue

# This is a small helper function, that ensures stateful 
# singletons. 
# See 
# https://ssr.vuejs.org/guide/structure.html#avoid-stateful-singletons 
# for more information.
app.js

# This is used to render the component on the client.
entry-client.js

# This is used to render the component on the server.
entry-server.js

Laravel/Node

On the server side, I choose to use the package spatie/laravel-server-side-rendering. This package is a Laravel bridge for the spatie/server-side-rendering library.

In general spatie/laravel-server-side-rendering is a pretty neat package and when you follow the howto section it should be pretty strait-forward. One should imagine.

My stupid mistake

However, there was one annoying thing that keept me busy longer then I care to admit; The default configuration of the package enables it per default in production only.

/*
 * Enable or disable the server renderer. Enabled in production by default.
 */
'enabled' => env('APP_ENV') === 'production'

You can imagine, what would happen if you missed this subtle point in development.

My implementation

Aside from the stupid mistake, the implementation is pretty strait forward.

In the controller, I built the context object:

'context' => [ 
    'getJson' => $this->geography->getGreenland(),
    ...
]

and injected that in the component in the view blade.

{!! ssr('js/entry-server.js')
    ->context('context', $context)
    ->fallback('<div id="greenland"></div>')
    ->render() !!}

Missing interactivity

As mentioned in the introduction, I intended to make an interactive map. Unfortunately, there was a mismatch between my SSR DOM and the client-side DOM, which caused the map to render when the client-side code spun up. So I have for the time being disabled the JS render function until I figure out, where the mismatch is located.

So, what do I think?

SSR is a very interesting technique and particularly, when you consider that you are using 2 different technology stacks.

I don't think SSR gives much benefit as a general approach, the overhead and tinkering required to render a single component, like the SVG map, will always be a hard sell for any contractor.

On the flipside: a client side application dose have an argument, when it comes to improving SEO, but in that case why just build everything with Node and avoid the complexity of a mixed tech stack.

Last remarks

Here are the links to the Library, that I used and to the issue that helped my resolve my stupid mistake.