Get started

Install Meles

Meles runs on your site from one small script. It loads after your page is idle (or two seconds after it starts, on a page that never is), draws nothing until a campaign shows, and never throws into your page. You need a site in Meles first: Settings → Sites in the dashboard.

Before you paste

On your site’s page in the dashboard (Settings → Sites, then the site):

  • Copy the site key. It starts pk_. It’s public: it goes in your page. A browser uses it only on your allowed origins, but that check isn’t access control: a script outside a browser can send any origin, or none, so treat whatever arrives with the key as something anyone could have sent. What stops someone posing as one of your users is the signed user ID in Identify your users.
  • Add your allowed origins, such as https://app.example.com. Meles runs only on these; https://*.example.com covers the subdomains, and http://localhost is allowed for development. Until there is one, Meles runs nowhere.

The script tag

Paste this into your page’s <head>, with your site key:

HTML
<script src="https://js.cdn.meles.app/s/v1/loader.js" data-site-key="pk_…" async></script>

That’s the whole install. The tag starts Meles by itself, so a page with a strict Content Security Policy needs no inline script.

  • The /s/v1/ address always serves the newest 1.x version, so fixes reach your site without a change to the tag. It is cached for five minutes.
  • To pin an exact version, use /s/<version>/loader.js with its integrity and crossorigin="anonymous". Each version’s hashes are at /s/<version>/integrity.json, and a version never changes. The loader checks every file it loads against the hashes built into it, so the pin covers the whole version.
  • A nonce on the tag is passed on to the script it loads, for a nonce-based Content Security Policy.
  • Your Content Security Policy needs https://js.cdn.meles.app in script-src, and https://c.cdn.meles.app, where your site’s settings come from, and https://app.meles.app in connect-src. If it enforces Trusted Types and lists its policies in trusted-types, add meles: Meles’s own policy, which lets through only Meles’s script files, of any version, from https://js.cdn.meles.app.

The npm package

For an app you bundle yourself:

Terminal
npm install @melesapp/sdk@next
TypeScript
import { Meles } from '@melesapp/sdk';

Meles.init({ siteKey: 'pk_…' });

The package is in beta, on npm’s next tag, and MIT-licensed. It ships its TypeScript types, and it leaves window alone. One version names the same build on npm and on the CDN.

Calls before the script has loaded

Every call you make after the tag is safe: it waits in a queue until Meles has loaded. For code that runs even earlier, such as a tag manager in the <head>, paste this first. It’s yours, so it can carry your nonce:

HTML
<script>
  window.Meles = window.Meles || { _q: [] };
  'init identify track page show dismiss reset setConsent on'.split(' ').forEach(function (m) {
    Meles[m] = Meles[m] || function () { Meles._q.push([m, [].slice.call(arguments)]); };
  });
</script>

Check it’s working

  1. Add data-debug to the tag. Meles then tells the browser’s console about anything it ignored or dropped, without the values you passed.
  2. Open your browser’s network panel and reload. You should see loader.js, then runtime.js, then your site’s settings, c.cdn.meles.app/c/pk_….json, answered 200. Within five seconds, a page view goes to app.meles.app/v1/events.
  3. Publish a test campaign in the dashboard with no targeting, and reload: it shows. Your site’s fatigue budget then holds the next showing back, by default for 30 minutes, so open a private window to see it again. Archive the test campaign when you’re done.

If nothing loads, check that your page’s origin is one of the site’s allowed origins, and that your Content Security Policy allows the three hosts above.

The calls

Call What it does
Meles.init({ siteKey, … }) Starts Meles, if the tag’s data-site-key didn’t. A second call is ignored
Meles.identify(userId, traits?, { company?, userHash? }) Says who is using your app: Identify your users
Meles.track(event, properties?) Records an event, for targeting
Meles.page(url?) Records a page view. Meles already records one on every page and every route change of a single-page app
Meles.show(campaignId) Shows a campaign now, skipping its targeting but not its frequency caps or your fatigue budget
Meles.dismiss(campaignId) Closes a campaign that is showing
Meles.reset() Forgets the identified person: call it when they sign out
Meles.setConsent('granted' | 'denied') Passes on your consent platform’s answer: Consent and cookieless mode
Meles.on(event, handler) Listens for shown, dismissed, response or completed, and returns a function that stops listening

No call returns a promise, and no call throws: a call with the wrong arguments is ignored, and says so in debug mode. A trait or property is a string, a number, a boolean or null.