DEV Community

Alberto CantĂş GĂłmez
Alberto CantĂş GĂłmez

Posted on • Edited on

5 1

Understanding Ember.js Public Assets Path for Browser and Cordova đź—„

Correction

Thanks to @neojp for his response https://twitter.com/neojp/status/1269708074387939329

I wrote this blog post without fully understanding the reasoning behind ember rewriting urls, fingerprinting and the TIL <base /> tag, the simple and pretty straightforward solution to handle urls in both environments is to just add a <base href={{rootURL}} /> in /app/index.html. I started using ember around 2.8, and I just found out what was the actual purpose of baseURL in config/environment.js and well, it got deprecated back in ember-cli 2.7, this practically changes how assets urls work in ember. Surprisingly the recommended solution is to use

fully-qualified paths or a root-relative URL.

For example

{{! Old: (with baseURL and/or <base /> tag) }}
<img src="assets/images/logo.png" />

{{! New: }}
<img src="/assets/images/logo.png" />

If you want to add the base tag, which I do recommend:

<!-- index.html -->
...
<head>
  <base href="{{rootURL}}" /> 
</head>

This means that all non fully-qualified urls will get the rootURL of your config/environment.js prefixed by the browser.

I think this is not really that well documented in Ember.js guides or Ember.js tutorial. New ember apps starts without the <base /> tag, thus won't seamlessly work in the browser and in corber, because while running in cordova you can't simply point relative paths i.e /asset/img/photo.jpg, all assets are placed elsewhere. The silver bullet is the <base /> tag.

The helper proposed in this blog post is useful if you want another way around adding the <base /> tag in your index.html because of some unexpected behaviors around it or just to follow(?) the current ember-cli blueprint... the following helper gives you the correct relative path in templates and JS regardless if you are running in cordova or the browser, you just gotta make sure this helper runs after cordova.deviceReady

// helpers/public-url
import Helper from '@ember/component/helper';
import config from 'ember-get-config';

let IS_READY = false;

export function publicUrl(url) {
  if (typeof FastBoot === 'undefined' && window.cordova && IS_READY) {
    return `${window.cordova.file.applicationDirectory}www/${config.ENV.rootURL}${url}`;
  }
  return `${config.ENV.rootURL}${url}`;
}

export default Helper.extend({
  cordovaEvents: service('ember-cordova/events'),

  deviceReadyObserver: subscribe('cordovaEvents.deviceready', 
    function(){
      IS_READY = true;
      recompute();
    })

  compute([url]){
    return publicUrl(url);
  }
});

And use it in templates like this

<img src={{public-url "assets/images/teams/{{team.short_name}}.png"}} alt="{{team.name}}'s flag" style="width: 50px;">

And in js like this

import { publicUrl } from '../helpers/public-url';
publicUrl(`assets/images/teams/${team.short_name}.png`);

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

đź‘‹ Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay