Skip to content

Latest commit

 

History

History
216 lines (152 loc) · 10.8 KB

File metadata and controls

216 lines (152 loc) · 10.8 KB

GitHub license Build Status dependencies Status devDependencies Status codecov

Pathfora JS

Pathfora JS is a lightweight SDK for displaying personalized modules on your website, it integrates with your Lytics account to track user actions, and conditionally display modules based on your users' audience membership. For more info and full configuration examples check out the full documentation.

Modules

There are 4 types of modules and 5 layouts currently supported.

Modules can be of the following types:

  • Message - Module with a simple text message.
  • Form - Module with a form to capture user information, can contain fields for name, email, title and message.
  • Subscription - Module with a single input field, email.

Modules are displayed in one of following layouts:

  • Modal - A large size module with an overlay behind it - meant to cover a substantial area of the browser window, so that it demands attention from the user.
  • Slideout - A medium module which slides from either side into the window.
  • Bar - A thin module which appears at the top or bottom of the browser window.
  • Button - A small module which only allows for a short call to action and a single click action.
  • Inline - A module which can be inserted into an existing div on a page.
  • Gate - Module which gates the page behind it - essentailly the same as the Modal layout without the "x" button, so the user must interact with the gate content to dismiss it.

General Usage

  1. Add Lytics tracking tag to your website, and import pathfora.js file.
<!-- Pathfora Tag -->
<script src="https://c.lytics.io/static/pathfora.min.js"></script>
  1. Set up your module configuration, a simple example is provided below. See the documentation for a full list of settings and examples.
// example: show a bar module with a button leading to a new products page

var module = new pathfora.Message({
  id: 'bar-valued-customers',
  layout: 'bar',
  msg: 'Thanks for being a valued customer, please check out our new products.',
  cancelShow: false,
  okMessage: 'View Now',
  confirmAction: {
    name: 'view now',
    callback: function () {
      window.location.pathname = '/new-products';
    },
  },
});

pathfora.initializeWidgets([module]);

Communication

slack - There’s a slack channel. Feel free to join and collaborate!

Contributing to Pathfora

See contribution notes

Development

Pathfora uses yarn for package management, rollup as a module bundler, and Gulp to manage build tasks.

Install Dependencies:

Note: Node v12 is not compatiable with the current set of dependencies. See gulpjs/gulp#2324

$ yarn global add gulp-cli
$ yarn install

Gulp tasks:

  • gulp build - minify LESS files. Bundle, lint and uglify js modules in the src/rollup directory, and place output files in dist directory.

  • gulp - runs the build tasks above and watches for any changes in the src directory, files are served on localhost port 8080.

  • gulp docs - see below.

  • gulp lint - lint all the js source files with the rules defined in .eslintrc.

  • gulp local - reads some config params from an optional local file, .env.json and builds and watches as with the default gulp task. This can allow you to test CSS changes locally (by default dist/pathfora.min.js loads the most recently deployed CSS file) or override the Lytics API URL.

    Example .env.json file, (using local CSS):

    {
      "APIURL": "https://c.lytics.io",
      "CSSURL": "http://localhost:8080/dist/pathfora.min.css"
    }

Useful scripts:

  • yarn test - builds and activates Karma test runner on PhantomJS.

  • yarn run clean - removes files from the ./dist folder for a clean build.

  • yarn run build:prod - sets NODE_ENV to production and builds minified files in ./dist folder.

  • yarn run prod - run tests, clean and rebuild the /dist folder. This is built on top of the gulp build command. Important to know that this sets the NODE_ENV to production, removing instabul instrumentation for code coverage. Currently, this is the default command used for our Travis CI.

  • yarn run local - run the gulp server to test things locally.

Documentation

Documentation for the most recent release is available here.

You can also view and add to the docs by running the gulp docs task. Our docs are powered by mkdocs which you must install before attempting to run the docs.

$ pip install mkdocs
$ gulp docs

Documentation will be served on localhost port 8000 while running this task.

The source code for all the examples provided in the documentation can be found in docs/docs/examples/src. Preview images for the examples are stored in docs/docs/examples/images.

The docs task will walk through every .js file in the examples source directory and compile it as a working html example in docs/docs/examples/preview using a handlebars template. These js files also get used as the source code to populate the <pre> elements within the docs.

This allows us to keep our source code in one place. Changing a js file in the examples source folder will change the code snippet in the docs and update the example .html file.

Widget playground

playground/ is a local page for rendering any widget type and layout, for manual QA and for demoing. Start the dev server and open it:

$ yarn run local

Then visit http://localhost:8080/playground/.

Pick any combination from the sidebar to render it, then use either mode to configure it:

  • Form builds the config from controls covering content, buttons, placement, theme and colours, all 14 display conditions, content recommendations and custom form fields. Controls only appear where the option actually applies, which keeps you away from the combinations that throw - footerText on a bar, a position on a gate, a pushDown on a bar that is not top-positioned.
  • Config is the generated JavaScript, editable by hand. It is the same shape as the examples in docs/docs/examples/src, so a snippet from a bug report can be pasted in and run as-is. Switching back to Form regenerates the config from the controls.

Two things it handles that are easy to get wrong by hand:

  • It sets window.PathforaCSS to /dist/pathfora.min.css before loading the SDK. The SDK otherwise injects the CDN stylesheet, and that production CSS wins the cascade over your local build - so local CSS changes appear to do nothing, with no error.
  • It clears pathfora's stored state before each render. pathfora.clearAll() only resets in-memory trackers, so without this a submitted gate stays unlocked and impression caps stay spent, across renders and across reloads. Tick Keep stored state when you are deliberately testing impressions or hideAfterAction.

Lytics tag in the toolbar swaps the stubs for the real tag, against the same demo account the published docs examples use. It is off by default so the playground stays network-free for anyone just checking a layout. With it on:

  • Audience targeting works - the Audience section targets a segment, matched against the visitor's own memberships, an attribute against a field on their profile, or both. The segment suggestions are the demo account's Lytics managed audiences, hardcoded in playground/fields.js so that reading them live does not mean storing an API key; any other slug can be typed in. An exclude subtracts from that match, which is the only thing exclusions do: initTargetedWidgets filters the widgets a target already matched, so an exclusion on its own matches nothing. The exclude field only appears once a "show to" segment is set, for that reason.
  • "everyone" is the literal * segment, and it is not a target at all: validateWidgetsObject hoists a * entry into widgets.common, which initTargetedWidgets renders before the targeting callback ever runs. So there is nothing for an exclusion or an attribute to act on, and those controls hide while it is selected.
  • A segment and an attribute together come out as one target entry whose rule ORs pathfora.rules.inSegment with the attribute rule, rather than as two entries. Two entries each concat [widget], so a visitor matching both would hand initializeWidgetArray the same widget twice and it would throw on the duplicate id.
  • Content recommendations call the recommendation API for real, with the content default document as the fallback. The collection field suggests the account's Lytics managed collections, hardcoded alongside the audiences in playground/fields.js; any other slug can be typed in. Without the tag there is no account to call, so the default is all you see. Either way setupWidgetContentUnit needs both recommend and content set, so a default document on its own renders nothing.

The tag is configured with publish and preview disabled, which stops the demo account's own campaigns rendering on top of the widget under test and, as a side effect, stops the tag installing its own SDK - so the local dist/ build stays in charge.

SiteGate is deliberately absent: it is deprecated, and its confirm button is dead code because construct-widget-actions.js never assigns it a widgetAction. Use Form with layout gate instead.

Testing

Pathfora uses Jasmine as a test framework, and Karma to run tests. Before running tests, or commiting changes be sure to run gulp build instead of gulp local, or tests may fail due to mismatching URLs.

Running tests:

$ yarn run test

License

MIT Copyright (c) 2017, 2016, 2015 Lytics