Skip to content

Initialization ​

After Haven is loaded, you configure global settings and render a module using the fluent API.

Global object ​

Haven exposes a single global instance:

javascript
window.haven  // lowercase

All integration code uses haven (not Haven).

Initialization flow ​

mermaid
sequenceDiagram
  participant Page
  participant Kit as HavenKit
  participant Haven as window.haven
  participant API as HavenAPI

  Page->>Kit: Load script tag
  Kit->>Haven: haven.init(credentials)
  Haven->>Haven: Check Mapbox / FontAwesome
  Haven-->>Page: haven.ready() = true
  Page->>Haven: haven.config(globalSettings)
  Page->>Haven: .directory.init(moduleSettings)
  Page->>Haven: .render()
  Haven->>API: Fetch products
  API-->>Haven: Product data
  Haven-->>Page: Render into #haven-app

haven.init() ​

Called automatically by the Haven Kit. For standalone loading, call it manually:

javascript
haven.init({
  havenFeedId: 'YOUR_FEED_ID',
  havenDomain: 'https://havenapi.havendestinations.ca/',
  havenVersion: 1,
  mapboxApiKey: 'YOUR_MAPBOX_KEY',
  imgixDomain: 'https://havenapi.imgix.net/',
  defaultSelector: '#haven-app',
  useFontAwesome: true,
  useMapBox: true,
}, function () {
  console.log('Haven is ready');
});
SettingDefaultDescription
havenFeedId''API key (haven-key header)
havenDomainhttps://havenapi.havendestinations.ca/API base URL (trailing slash required)
havenVersion1API version segment
mapboxApiKey''Mapbox access token
defaultSelector#haven-appDefault render target
useFontAwesomeauto-detectedEnable icon rendering
useMapBoxauto-detectedEnable map rendering

See Global Config for the full list.

haven.ready() ​

Returns true after haven.init() completes (including Mapbox/Font Awesome checks).

javascript
if (haven.ready()) {
  // safe to configure and render
}

haven.config() ​

Sets global options and creates plugin instances. Returns haven for chaining.

javascript
haven.config({
  templatePath: 'https://YOUR_TEMPLATE_HOST/haven-templates/',
  userTemplates: ['haven-directory-list-item.html', 'haven-directory-detail.html'],
  useMapBox: true,
  useFontAwesome: true,
  breakpoints: {
    mobile: 480,
    tablet: 800,
    desktop: 1024,
    'desktop-large': 1200,
    'desktop-xlarge': 1360,
  },
});

After config(), two plugin accessors are available:

  • haven.directory — business listings
  • haven.calendar — events

Fluent render chain ​

The standard pattern chains configuration, module init, and render:

javascript
haven.config({ /* global */ })
  .directory.init({ /* module */ })
  .render();

Or for calendar:

javascript
haven.config({ /* global */ })
  .calendar.init({ /* module */ })
  .render();

Module init parameters ​

javascript
.directory.init({
  routing: { /* URL routing */ },
  selector: '#haven-app',
  format: 'list',
  category: null,
  data: null,
  options: { /* feature options */ },
}, function () {
  // optional post-init callback
})

Shorthand render ​

For simple cases (e.g. a single-category page), use the shorthand on haven.config():

javascript
haven.config({ /* global */ })
  .render({
    type: 'directory',
    format: 'list',
    category: 'YOUR_CATEGORY',
    options: { /* ... */ },
  });

This is equivalent to calling .directory.init() with a locked category.

Manual data render ​

If you fetch data yourself via haven.fetch, pass it into init:

javascript
haven.fetch.getProducts(function (response) {
  haven.config({ /* global */ })
    .directory.init({
      format: 'itinerary',
      data: response,
      options: { /* ... */ },
    })
    .render();
}, 'plugin', { ids: [1234, 5678] });

See Fetching Data.

Other facade methods ​

MethodPurpose
haven.render({ data, type, format, options, selector, id, category })Generic render without plugin chain
haven.initUI({ type, format })Initialize UI behaviors after render
haven.setTemplatePath(path)Override template base URL
haven.getFilterValues(type)Read persisted filter state from localStorage
haven.setFilterValues(type, value)Persist filter state
haven.faves()Access favorites helper
haven.removeEmptyNode(selector)Remove empty DOM nodes

Complete example ​

javascript
(function () {
  var poll = setInterval(function () {
    if (window.haven && haven.ready && haven.ready()) {
      clearInterval(poll);

      haven.config({
        templatePath: 'https://YOUR_TEMPLATE_HOST/haven-templates/',
        userTemplates: ['haven-directory-list-item.html'],
        useMapBox: true,
        useFontAwesome: true,
      })
      .directory.init({
        selector: '#haven-app',
        routing: {
          path: '/directory/',
          type: 'hash',
          doPathChange: true,
        },
        options: {
          sort: 'name',
          cols: 3,
          includeMap: true,
          includeLightbox: true,
        },
      })
      .render();
    }
  }, 10);
})();

Next ​

Haven Destinations integration documentation