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.comcovers the subdomains, andhttp://localhostis allowed for development. Until there is one, Meles runs nowhere.
The script tag
Paste this into your page’s <head>, with your site key:
<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.jswith itsintegrityandcrossorigin="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.appinscript-src, andhttps://c.cdn.meles.app, where your site’s settings come from, andhttps://app.meles.appinconnect-src. If it enforces Trusted Types and lists its policies intrusted-types, addmeles: Meles’s own policy, which lets through only Meles’s script files, of any version, fromhttps://js.cdn.meles.app.
The npm package
For an app you bundle yourself:
npm install @melesapp/sdk@nextimport { 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:
<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
- Add
data-debugto the tag. Meles then tells the browser’s console about anything it ignored or dropped, without the values you passed. - Open your browser’s network panel and reload. You should see
loader.js, thenruntime.js, then your site’s settings,c.cdn.meles.app/c/pk_….json, answered200. Within five seconds, a page view goes toapp.meles.app/v1/events. - 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.