sauronnikko
sauronnikko

Reputation: 5455

EmberJS: Set environment variables in index.html

We have an Ember (3.5) application. For technical reasons we need environment variables to be set on page load, as opposed to build time. We're trying to set them in index.html the following way:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>App</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    {{content-for "head"}}
    <script type="application/javascript">
      // Object.assign polyfill
      Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(e,r){"use strict";if(null==e)throw new TypeError("Cannot convert first argument to object");for(var t=Object(e),n=1;n<arguments.length;n++){var o=arguments[n];if(null!=o)for(var a=Object.keys(Object(o)),c=0,b=a.length;c<b;c++){var i=a[c],l=Object.getOwnPropertyDescriptor(o,i);void 0!==l&&l.enumerable&&(t[i]=o[i])}}return t}});
      window.env = {};

      var request = new XMLHttpRequest();
      request.open('GET', '/api/frontend_settings', true);
      request.send(null);

      request.addEventListener('readystatechange', () => {
        if (request.status === 200) {
          if (request.readyState === 4) {
            Object.assign(window.env, JSON.parse(request.response).settings);
          }
        }
      }, false);
    </script>

    <link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
    <link integrity="" rel="stylesheet" href="{{rootURL}}assets/app-frontend.css">

    {{content-for "head-footer"}}
  </head>
  <body>
    <script integrity="" src="{{rootURL}}assets/vendor.js"></script>
    <script integrity="" src="{{rootURL}}assets/app-frontend.js"></script>
  </body>
</html>

We added a script which makes a request to some endpoint (/api/frontend_env_vars) in the snippet. This endpoint responds with a JSON with the key-values of environment variables which we then assign to window.env.

The problem we have is that sometimes Ember scripts load before the variables have been assigned (since we do a request that takes some time to complete), which makes the application crash.

We tried the following alteration to the script, but it didn't work (the error was different, though):

<script type="application/javascript">
  // Object.assign polyfill
  Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(e,r){"use strict";if(null==e)throw new TypeError("Cannot convert first argument to object");for(var t=Object(e),n=1;n<arguments.length;n++){var o=arguments[n];if(null!=o)for(var a=Object.keys(Object(o)),c=0,b=a.length;c<b;c++){var i=a[c],l=Object.getOwnPropertyDescriptor(o,i);void 0!==l&&l.enumerable&&(t[i]=o[i])}}return t}});
  window.env = {};
  var request = new XMLHttpRequest();
  request.open('GET', '/api/frontend_env_vars', true);
  request.send(null);
  function loadScript(src) {
    const script = document.createElement('script');
    script.src = src;
    document.body.append(script);
  }
  request.addEventListener('readystatechange', () => {
    if (request.status === 200) {
      if (request.readyState === 4) {
        Object.assign(window.env, JSON.parse(request.response).settings);
        loadScript('assets/vendor.js');
        loadScript('assets/app-frontend.js');
      }
    }
  }, false);
</script>

Upvotes: 0

Views: 571

Answers (1)

jrjohnson
jrjohnson

Reputation: 2474

We accomplish this using ember-cli-server-variables

Which allows you to define variables in index.html

<html>
  <head>
    <meta name='your-app-token' content='example:app:token'>
    <meta name='your-app-user-location' content='Denver'>
    <meta name='your-app-json-data' content='{"foo":"bar"}'>
  </head>
</html>

and then access them from the application.

We build our index.html on the server with the needed variables to there is no async needed to fetch them.

Upvotes: 1

Related Questions