# [JS/Invenio CONFIG](https://indico.cern.ch/event/774510/)
#### Invenio Developers Forum
#### 26 Nov 2018
---
'If I need to create a client *SPA**, how do I get Invenio config?'
***
###### *SPA*: Invenio REST APIs are not fully-featured yet, the SPA is still loaded from a Jinja template
---
### CURRENT SITUATION
* Invenio configuration is injected in Jinja templates
* The Jinja templates loads the AngularJS application
* AngularJS gets the config through attrs
* It is like having "Multiple SPA" (one per module?)
----
*[Invenio-Search-UI](https://github.com/inveniosoftware/invenio-search-ui/blob/master/invenio_search_ui/templates/invenio_search_ui/search.html#L24)*
```html
{%- block body_inner %}
<div id="invenio-search">
<invenio-search
search-endpoint="{{ config.SEARCH_UI_SEARCH_API }}"
search-extra-params='{% if search_extra_params %}{{search_extra_params|tojson}}{% endif %}'
search-hidden-params='{% if search_hidden_params %}{{search_hidden_params|tojson}}{% endif %}'
search-headers='{"Accept": "{{ config.SEARCH_UI_SEARCH_MIMETYPE|default('application/json')}}"}'
>
{{super()}}
</invenio-search>
</div>
{%- endblock body_inner %}
```
---
### A SINGLE SINGLE PAGE APP
I am building my Invenio overlay
I am creating a SPA (REACT app :innocent:?) and:
* I don't want to hardcode a duplicated config
* I want to get the config of the Invenio application
---
### 3 SOLUTIONS
* inject config (as with AngularJS)
* expose config through REST
* expose config at build time
---
### INJECT CONFIG
----
```html
<div id="config" data-config="{'DEBUG': '1', }" />
```
* **Advantages:**
* simple
* **Drawbacks:**
* ugly
* needs a Jinja template
* inject entire config or need to know in advance what to inject
---
### EXPOSE CONFIG THROUGH REST
* Perform an extra call to load config first
* Render your app based on the config
----
```bash
$ curl -k https://videos.cern.ch/api/records/_options | jq
{
"default_media_type": "application/json",
"item_media_types": [
"application/json",
"application/smil",
"application/x-datacite+xml",
"text/vtt",
"x-application/drupal"
],
"max_result_window": 10000,
"search_media_types": [
"application/json"
],
"sort_fields": [
{
"bestmatch": {
"default_order": "asc",
"title": "Best match"
}
},
]
}
```
----
* **Advantages:**
* it is REST
* easy to use, explicit
* low maintenance
* supports runtime config changes
* **Drawbacks:**
* extra API call potentially blocking (show loader?)
* adds assumptions and complexity
* source of bugs
* needs development on both Invenio and JS apps
---
### EXPOSE CONFIG AT BUILD TIME
----
### Create a new babel plugin for webpack
At build time:
* runs the Invenio flask app and extract the full config
* replace any JS config import with the extracted config
----
```js
import { sortFields } from 'invenio-config/records-rest';
```
----
* **Advantages:**
* no extra complexity or development on Invenio or JS apps
* exports only the config that JS imports
* **Drawbacks:**
* does not support runtime config changes
* config change -> re-build (re-deploy)
* slightly slower build process
* maintenance of the Babel plugin
---
### SHARE YOUR THOUGHTS!
Thank you!