Rolf//Thomas

ist ein Internetentwickler bei idee[x] digitale dienste

How to send static configuration from Typo3 to React

Send config data to an embeded React app inside a Typo3 page

All configuration should take place on the Typo3 side of things so editors and maintainers can change the React app’s settings. If the displayed data is also static and not to big in size, you could even include it directly and save an api call. There is a huge performance benefit: everything is cached by Typo3 and rendered instantly on page load. No spinners or “Loading…”-screens. Nobody will miss them.

How to approach this?

My first implementation was inserting an object on the global javascript namespace and reading this object on mount time of the React app. But lately I think polluting the global namespace is not very nice – it might be ok on a small project but with bigger team size and distributed teams it’s more of a pain to maintain than worth it. So the best solution in my view is to include the configuration in the root html element of the actual app. This seems more contained to me. To avoid encoding problems with single or double quotes via the html data element, better encode the resulting data with something like base64 – not the winner of efficency (~30% increase in size), but for configuration data it doesn’t matter. As an added bonus it ofuscates the config data quite a bit.

Typo3

In the Extbase Controller gather all configuration data and insert it as Base64 encoded JSON data attribute via the Fluid Template.

Controller

/**
  * action show
  *
  * @return void
  */
public function showAction()
{
  // …
  // build app configuration, transform to json and encode using base64
  $appConfig = base64_encode(json_encode([
    'debug' => $this->settings['debug'],
    'version' => $this->version,
    'exampleProperty' => $examplePropertyValue,
    // …
  ]));
  // pass encoded configuration to template variable
  $this->view->assign('appConfig', $appConfig);
}

Fluid Template

<div class="tx-exampleextension-modulename-app">
    <noscript>Please activate javascript to use the app.</noscript>
    <!-- insert base64 encoded json configuration to data-attribute, resulting in data-config="eyJkZWJ1ZyI6ZmFsc2UsInZlcnNpb24iOiIxLjAuNC…" -->
    <div 
      id="tx-exampleextension-modulename-app__root"
      data-config="{appConfig -> f:format.raw()}"
    >
    </div>
    <!-- include styles and app code -->
    <link href="{f:uri.resource(path:'css/app.css')}" rel="stylesheet">
    <script src="{f:uri.resource(path:'javascript/app.js')}"></script>
</div>

React app

In the React app make sure to decode the configuration and pass it down as prop so it can be used.

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

// get root element of app
const element = document.getElementById('tx-exampleextension-modulename-app__root')
// get encoded configuration from 'data-config' attribute, decode base64 and parse json
const configuration = JSON.parse(window.atob(element.getAttribute('data-config'))) // <- this…

ReactDOM.render(
  <React.StrictMode>
    <App configuration={configuration} />
  </React.StrictMode>,
  element
)

Configuration done. Happy coding 🎉

Anything to add or correct?

Just reply on twitter.

How to send static configuration from #Typo3 to #React?
@rolfthomas