Search only lite client (CDN) as npm module


#1

There are React, Angular and Vue implementations for algoliasearch, but in my company we use lots of Ember and for SSR there’s Fastboot, which basically runs your app in Node.js and returns the generated html.

The problem is that algoliasearch try to access document but of course that doesn’t exist in Node…

I saw there’s a CDN search only lite client, that would actually make it for me, I can build the UI myself using ember, the issue is that search only lite client exposes algoliasearch to window, so it again doesn’t exists in Node…

What I’m asking is to simply make it an npm module, something like algoliasearch-search-only so any js dev, in any framework or plain JS can SSR as they please

Currently I have to guard algoliasearch like this, so it doesn’t break in Node.

The error says with normal algoliasearch package is: document doesn't exists
And the error with the CDN search only lite client is: algoliasearch doesn't exists so it has to be bundled and imported as a module.

import algoliasearch from 'algoliasearch-search-only`; //this is what I would love

class Listing extends Service {
   constructor() {
    super(...arguments);
    if (typeof FastBoot === "undefined") {
      this.algolia = algoliasearch('KEY', 'KEY');

      this.algolia.initIndex(this.currentIndex).search({
          facets: ['*']
        },
        function (error, content) {
          let facets = [];
          Object.keys(content.facets).forEach(facetKey => {
            let facet = content.facets[facetKey];
            Object.keys(facet).forEach(key => {
              facets.addObject(new Facet({
                key: facetKey,
                name: key,
                count: facet[key]
              }))
            })
          })
          this.facets = facets;
        }.bind(this)
      );
    }
}

This way we can have an alternative to truly be window/document free in Node envs

Thanks in advance


#2

Hi @betocantu93,

The algoliasearch/lite package is supposed to be platform agnostic.

We have multiple builds to target multiple platforms. The lite package supports both Node and the Browser. The environment you’re in is responsible to pick the correct version of the package. Here is two examples in two different environments with lite package:

To support both environments we leverage the browser filed of the package.json. It’s supported by the major module system/bundler like Node, Webpack, Rollup.

From what I’ve read Fastboot is not able to use this package field which explain the error in your case. You should be able to use Fastboot.require to import a dedicated version of the client on the server though.

Hope that helps, let me know if you have questions.


#3

Hey @samuel.vaillant thanks for your response, didn’t knew about the algoliasearch/lite package, and I googled tons I promise haha. I’m trying to make it work, FastBoot.require is actually is working at the moment. Would you recommend this approach? Can’t think of any other atm

import algoliasearch from 'algoliasearch';

class AlgoliaService extends Service {
  constructor(){
    super(...arguments);
    if(typeof FastBoot !== "undefined"){
       this.algolia = FastBoot.require('algoliasearch/lite')('KEY', 'KEY');
    } else {
       this.algolia = algoliasearch('KEY', 'KEY')
    }
  }
}

The thing is that I’m not sure if importing in two ways would cause performance issues, so maybe I can do some dynamic import stuff? what you think? using ember-auto-import


#4

So this was my final solution

import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default class ApplicationRoute extends Route {
	@service listing;

	async model(){
		if(typeof FastBoot === "undefined") {
			let module = await import('algoliasearch')
			this.listing.algolia = module.default(KEY, KEY)
		} else {
			this.listing.algolia = await FastBoot.require('algoliasearch/lite')(KEY, KEY);
		}
		await this.listing.getFacets();
	}
}