Skip to content
Last updated

Frontend setup

Once your backend can obtain Spotnana access tokens, configure your frontend to load the Spotnana iframe and handle the token exchange.

Query parameter

When loading the iframe, include the idp=token-exchange-auth query parameter in the URL. This instructs the Spotnana system to initiate the token exchange authentication flow.

For example, the URL containing the query parameter may look like this:

https://<spotnana-embed-url>/path?idp=token-exchange-auth&orgId=<your-org-id>

Note: This query parameter clears all previous session storage and starts a fresh authentication. This is also important to capture any changes that may have happened to the user's status within your system since the last session (e.g., a user's access may have been revoked if they've left the organization).

Frontend token exchange process

When the iframe loads, Spotnana and your application exchange messages through the browser's postMessage API. Here's how the process works:

  1. Spotnana sends a TOKEN_EXCHANGE_REQUEST message to your application. Here's a sample message you may receive:
{
  "type": "TOKEN_EXCHANGE_REQUEST",
  "from": "spotnana-embed"
}
  1. Your application listens for this message. Then, it fetches the access token and refresh token from your backend setup, and responds with the following TOKEN_EXCHANGE_RESPONSE.
{
  "type": "TOKEN_EXCHANGE_RESPONSE",
  "payload": {
    "accessToken": "<spotnana-access-token>",
    "refreshToken": "<spotnana-refresh-token>"
  }
}

Note: If the token exchange fails, Spotnana sends a TOKEN_EXCHANGE_ERROR message as shown below:

{
  "from": "spotnana-embed",
  "type": "TOKEN_EXCHANGE_ERROR",
  "payload": {
    "errorCode": "INVALID_TOKEN",
    "errorMessage": "<error description>"
  }
}

Your application must be designed to listen for this event and handle authentication failures appropriately (e.g., redirecting the user to a login page or displaying an error message).

Code sample to implement frontend logic

The following HTML sample demonstrates the frontend integration. This code will render the Spotnana iframe upon the click of a button (i.e., in this code, clicking the Launch Spotnana button will initiate the rendering). This code also handles the frontend token exchange.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Spotnana Embed</title>
  <style>
    html, body { height: 100%; margin: 0; padding: 0 20px; }
    .iframe-wrapper {
      height: calc(100% - 100px);
      width: 100%;
      border: 1px solid #ccc;
    }
  </style>
</head>
<body>
  <h1>Spotnana Integration</h1>
  <button id="renderIframe">Launch Spotnana</button>
  <div class="iframe-wrapper" id="iframeWrapper"></div>

  <script>
    const spotnanaDomain = 'https://sboxmeta-embed-app.partners.spotnana.com';
    const orgId = '<YOUR_ORG_ID>';

    // Listen for token exchange requests from the iframe
    window.addEventListener('message', async (event) => {
      if (event.origin !== spotnanaDomain) return;
      const { data, source } = event;

      if (data.type === 'TOKEN_EXCHANGE_REQUEST') {
        try {
          // Fetch tokens from your backend
          const response = await fetch('/api/spotnana/tokens');
          const { accessToken, refreshToken } = await response.json();

          source.postMessage({
            type: 'TOKEN_EXCHANGE_RESPONSE',
            payload: { accessToken, refreshToken }
          }, spotnanaDomain);
        } catch (error) {
          console.error('Token fetch failed:', error);
        }
      }

      if (data.type === 'TOKEN_EXCHANGE_ERROR') {
        console.error('Token exchange error:', data.payload);
        // Handle authentication failure
      }
    });

    // Render iframe on button click
    document.getElementById('renderIframe').addEventListener('click', () => {
      const wrapper = document.getElementById('iframeWrapper');
      const params = new URLSearchParams({
        'idp': 'token-exchange-auth',
        'orgId': orgId,
        // Add other parameters as needed
      });

      const iframe = document.createElement('iframe');
      iframe.src = `${spotnanaDomain}/hotels/search?${params}`;
      iframe.width = '100%';
      iframe.height = '100%';
      iframe.title = 'Spotnana';

      wrapper.innerHTML = '';
      wrapper.appendChild(iframe);
    });
  </script>
</body>
</html>