/ember-filestack

Support for Filestack service within EmberJS

Primary LanguageJavaScriptMIT LicenseMIT

ember-filestack

npm version CI Ember Observer Score

Provides file picking, storing, and converting funtionality from Filestack using filestack-js.

Installation

ember install ember-filestack

Compatibility

  • Ember.js v3.24 or above
  • Ember CLI v3.24 or above
  • Node.js v12 or above

ember-filestack supports all ember LTS versions (that means 3.24+ at the moment). With that being said, it may support versions even older than that.

Your consuming app must depend on ember-auto-import >= 2 in order to use this addon.

Migration from 1.0.0

There are important changes since v1.0.0. Most will be supported with deprecation notices until v3.0.0. However, there have also been important changes in the underlyng filestack.js module. Please refer to the Filestack API changelog for changes to available options.

Please read our migration guide for changes to environment.js and the Ember components.

Configuration

API Key

// config/environment.js
module.exports = function (environment) {
  let ENV = {
    //...
    'ember-filestack': {
      apiKey: 'AOkSBYOLvTqK3GzWzQMOuz',
    },
  };
  //...
};

Custom CDN

To minimize your quota usage (both bandwidth and process quotas), you can put filestack behind your own CDNs (e.g. AWS CloudFront). To do that you will want to proxy all urls with the host https://cdn.filestackcontent.com.

Then you can configure your custom CDN url like:

// config/environment.js
module.exports = function (environment) {
  let ENV = {
    //...
    'ember-filestack': {
      apiKey: '<your filestack api key>',
      customCDN: '<your-cdn.cloudfront.net>',
    },
  };
  //...
};

When customCDN is defined, ember-filestack will ensure that Filestack’s CDN is never accessed directly.

Global config for picker and preview

You can add global options for the picker and preview components (read more about them in the next sections). For that, you can use the pickerOptions and previewOptions keys in the ember-filestack config. Additionally, any necessary filestack client options must be defined here.

Example:

// config/environment.js
module.exports = function(environment) {
  let ENV = {
    //...
    'ember-filestack': {
      // ...
      clientOptions: {
        // add any client options here
      },
      pickerOptions: {
        // add any global picker options here
      },
      previewOptions: {
        // add any global preview options here
      }
    }
  };
  //...

Usage

File Picker

The file picker is rendered using the <FilestackPicker/> component. This component accepts all the available picker options that the filestack picker accepts. Complete documentation of all the available options can be found here.

Example:

<button type='button' {{on 'click' (fn (mut this.showFilePicker) true)}}>Choose
  file</button>

{{#if this.showFilePicker}}
  <FilestackPicker
    @accept='image/*'
    @onUploadDone={{this.fileSelected}}
    @onClose={{fn (mut this.showFilePicker) false}}
  />
{{/if}}
export default class FileUploader extends Component {
  fileSelected(result) {
    // `result` is an array of files you've just uploaded
    console.log(result.filesUploaded);
  }
}

Generate file urls

When you need to generate a filestack url, you should use the {{filestack-url}} helper.

This helper accepts a filestack handle or any image url as the first (and only) positional parameter.

Additionally, you can pass in additional multiple named parameters that correspond to transforms. The helper accepts all the available transforms that filestack provides. You can check the available transform options here.

Examples:

{{filestack-url this.handleOrUrl}}

{{filestack-url this.handleOrUrl resize=(hash width=50 height=50 fit='scale')}}

{{filestack-url this.handleOrUrl output=(hash format='jpg')}}

{{filestack-url
  this.handleOrUrl
  output=(hash format='png')
  resize=(hash width=500 height=500 fit='max')
}}

You can also use the included filestack service to generate image urls:

import Component from '@glimmer/component';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';

export default class MyComponent extends Component {
  @service filestack;

  get scaledImage() {
    let url = this.args.imageUrl;
    let transformations = {
      output: {
        format: 'png',
      },
      resize: {
        width: 500,
        height: 500,
        fit: 'max',
      },
    };

    return this.filestack.getUrl(url, transformations);
  }
}

All of these will respect the customCDN configuration, if present.

Notice that it is possible to write invalid transforms. For example, you can't specify a transform of resize=(hash fit="some-invalid-value"). Under the hook, filestack-js will validate the passed transform options, so expect errors if you do something wrong.

Filestack previewer

Filestack has a feature to preview documents in a nice file previewer. This renders an iframe with filestack's previewer and it supports multiple formats. Read more about this feature here.

ember-filestack provides a <FilestackPreview/> component that you can use to quickly insert this iframe anywhere in your DOM.

Example:

<FilestackPreview @handle={{this.fileHandle}} />

This component supports all the preview options that filestack supports. Complete documentation of all the available options can be found here.

Direct filestack client Access

Sometimes you might need to use the filestack client manually. To do that, you can use the filestack service initClient method as follows:

import Component from '@glimmer/component';
import { inject as service } from '@ember/service';

export default class MyComponent extends Component {
  // inject the filestack service
  @service filestack;

  async someFunction() {
    // Use the promise in case you are not sure that your component will be initialized after filestack has been loaded

    let filestack = await this.filestack.initClient();

    // do something with filestack
  }
}

Notice that initClient is asynchronous (returns a Promise). This happens because we lazily initialize and import filestack client. Please read the next section for more information.

Lazy filestack initialization

All the filestack javascript and the respective filestack initialization is done only when needed. This means that, if a user never renders a filepicker or generates a filestack url, your app won't spend any resources or bandwidth with filestack related work.

With that being said, ember-filestack makes sure that it only initializes filestack once. This means that, for example, if you call this.filestack.initClient() twice, all the heavy work will be done once. In this example the second call would return the filestack client immediately.

Fastboot considerations

ember-filestack will no-op on fastboot environments since filestack-js requires access to document (which isn't available on node).