Link Search Menu Expand Document

Navigation Examples

This page covers navigation implementation patterns and the URL parameters that the controller reads on initialization.

Spaaza’s controller does not handle navigation. It only emits content:select events when users click content. How you respond to those events is up to you. Below are example implementations for different environments.

URL-Driven (Simplest)

Listen to content:select, change window.location.search. Page reloads, controller reads URL params to show correct view.

// spaaza controller emits content:select when user clicks content
document.addEventListener('content:select', (event) => {
  const { campaign, voucher } = event.detail;

  // your code — preserve auth params and change the navigation params
  const params = new URLSearchParams(window.location.search);

  if (voucher) {
    params.delete('campaign_id');
    params.delete('name');
    params.set('voucher_id', voucher.id);
    window.location.search = params.toString();
  } else if (campaign?.image_link) {
    if (campaign.image_link.startsWith('http')) {
      window.open(campaign.image_link, '_blank');  // external link
    } else {
      // merge image_link params (e.g. ?campaign_id=123) with existing auth params
      const intentParams = new URLSearchParams(campaign.image_link);
      intentParams.forEach((value, key) => params.set(key, value));
      window.location.search = params.toString();
    }
  }
});

Two WebViews (React Native)

Listen to content:select, postMessage to native app. Native manages two separate WebView instances (page + detail) and swaps between them.

WebView URLs:

  • Page: elements.html?name=home
  • Detail: elements.html?campaign_id=123 or elements.html?voucher_id=456

Page WebView — send intent to native:

// spaaza controller emits content:select when user clicks content
document.addEventListener('content:select', (event) => {
  const { campaign, voucher } = event.detail;

  // your code — forward the click intent to the native app
  window.ReactNativeWebView?.postMessage(JSON.stringify({
    type: 'navigate',
    contentType: voucher ? 'voucher' : 'campaign',
    id: voucher?.id || campaign?.id,
    imageLink: campaign?.image_link
  }));
});

Native side — handle the message:

// your code — native receives the message and loads the detail WebView with URL params
function onWebViewMessage(message) {
  const { contentType, id, imageLink } = JSON.parse(message);

  if (imageLink?.startsWith('http')) {
    Linking.openURL(imageLink);  // external link
  } else if (contentType === 'voucher') {
    showDetailWebView(`?voucher_id=${id}`);  // controller reads params on init
  } else {
    showDetailWebView(`?campaign_id=${id}`);  // controller reads params on init
  }
}

Back button: Native toggles WebView visibility. No WebView communication needed.

SPA (Client-Managed)

Listen to content:select, set properties on the mounted components to trigger data loading, and manage component visibility yourself. No page reload.

// spaaza controller initializes and mounts both components
const controller = await initializeSpaazaElements({
  target: '#spaaza-elements',
  config: config,
  pageName: 'home',
  componentBaseUrl: 'https://elements.spaaza.com/'
});

// your code — get references to both mounted components (see Web Components for IDs)
const pageEl = document.getElementById('spaazaContentPage');
const detailEl = document.getElementById('spaazaContentPageDetail');

// your code — show campaign detail by setting campaignId property
function showCampaignDetail(campaignId) {
  detailEl.campaignId = campaignId;  // controller reactively fetches campaign data
  pageEl.style.display = 'none';
  detailEl.style.display = 'block';
}

// your code — show voucher detail by setting voucherId property
function showVoucherDetail(voucherId) {
  detailEl.voucherId = voucherId;  // controller reactively fetches voucher data
  pageEl.style.display = 'none';
  detailEl.style.display = 'block';
}

// your code — show page view by setting pageName property
function showPage(name) {
  if (name) pageEl.pageName = name;  // controller reactively fetches page data
  detailEl.style.display = 'none';
  pageEl.style.display = 'block';
}

// spaaza controller emits content:select when user clicks content
document.addEventListener('content:select', (event) => {
  const { campaign, voucher } = event.detail;

  // your code — decide what to show based on the clicked content
  if (voucher) {
    showVoucherDetail(voucher.id);
  } else if (campaign?.image_link) {
    const intent = controller.parseImageLink(campaign.image_link);

    if (intent.type === 'detail') {
      showCampaignDetail(intent.campaignId);
    } else if (intent.type === 'page') {
      showPage(intent.pageName);
    } else if (intent.type === 'external') {
      window.open(intent.url, '_blank');
    }
  }
});

URL Parameters

When using URL-driven navigation, the controller reads these query parameters on initialization to determine what to display.

Parameter Required Description
session_key Yes Session key from login
user_id Yes User ID from login
my_price_app_host Yes Spaaza app hostname
origin No API origin (defaults to production)
name No Page name (default: “home”)
business_id No Store ID for filtering
campaign_id No Campaign ID for detail view
voucher_id No Voucher ID for detail view

Example URLs (staging):

Home page:

https://elements-test01.spaaza.com/demo.html?session_key=KEY&user_id=ID&my_price_app_host=yourapp.spaaza.com&origin=https://apistage0.spaaza.com&name=home

Page filtered by store:

https://elements-test01.spaaza.com/demo.html?session_key=KEY&user_id=ID&my_price_app_host=yourapp.spaaza.com&origin=https://apistage0.spaaza.com&name=home&business_id=3522

Campaign detail page:

https://elements-test01.spaaza.com/demo.html?session_key=KEY&user_id=ID&my_price_app_host=yourapp.spaaza.com&origin=https://apistage0.spaaza.com&campaign_id=4911

Campaign detail page with home route:

https://elements-test01.spaaza.com/demo.html?session_key=KEY&user_id=ID&my_price_app_host=yourapp.spaaza.com&origin=https://apistage0.spaaza.com&campaign_id=4911&name=home