SeatSquirrel
DeploymentSelf-Hosted Mode

Standalone Mode

Integrate SeatSquirrel as a full-page app with direct JavaScript API

Overview

In Standalone mode, SeatSquirrel runs as a full-page application. There is no iFrame and no SDK file — you configure the Designer or Picker by editing the HTML file directly and setting a window.SeatSquirrelConfig object.

After the app initialises, a global window.SeatSquirrel object exposes the API.

Designer

Quick Start

Open designer.html and edit the <script> block that sets window.SeatSquirrelConfig:

<script>
  window.SeatSquirrelConfig = {
    // Wait for the designer to be ready to receive commands including load layout data
    onReady: function () {
      console.log('Designer ready!');
      // Load an existing layout from your API
      // fetch('/api/layouts/123')
      //   .then(r => r.json())
      //   .then(data => SeatSquirrel.designer.loadLayout(data));
    },
    
    onLayoutChanged: function (data) {
      // Layout was changed
      console.log('Has unsaved changes:', data.hasChanges);
    },

    onPricingCategoriesChanged: function (data) {
      // Handle in-Designer pricing changes — call getPricingCategories() for the data
      const { pricingCategories } = SeatSquirrel.designer.getPricingCategories();
      console.log('Pricing changed:', pricingCategories);
    },
  
    onError: function (error) {
      // Handle error
      console.error('Error:', error.message);
    },
    
    onSave: function (data) {
      // Save the layout to your backend
      console.log('Save layout data:', data.layout);
    }
  };
</script>

Designer Complete Example

<!DOCTYPE html>
<html>
  <head>
    <title>Venue Layout Designer</title>
  </head>
  <body>
    <div id="seatsquirrel-designer-root"></div>

    <script>
      window.SeatSquirrelConfig = {
        onReady: function () {
          console.log('Designer ready');
        },

        onSave: async function (data) {
          await fetch('/api/layouts', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(data.layout),
          });
          SeatSquirrel.designer.showToast({
            title: 'Layout saved',
            type: 'success',
          });
        },

        onLayoutChanged: function (data) {
          document.title = data.hasChanges
            ? '* Venue Layout Designer'
            : 'Venue Layout Designer';
        },

        onError: function (error) {
          console.error(error);
        },
      };
    </script>

    <!-- Bundled app script (do not modify) -->
    <script type="module" src="/assets/standalone-designer.js"></script>
  </body>
</html>

For the full list of constructor options, methods, and callbacks see the Designer API Reference.


Picker

Quick Start

Open picker.html and edit the <script> block that sets window.SeatSquirrelConfig:

<script>
  window.SeatSquirrelConfig = {
    onReady: function () {
      console.log('Picker ready!');
      // Load your layout and set availability
      // fetch('/api/layouts/123')
      //   .then(r => r.json())
      //   .then(data => {
      //     SeatSquirrel.picker.loadLayout(data);
      //     SeatSquirrel.picker.setAvailability({ mode: 'by-slug', ...availabilityData });
      //   });
    },

    onSelectionChanged: function (data) {
      console.log('Selected:', data.totals.count, 'items');
      console.log('Total:', data.totals.amount, 'cents');
    },

    onComplete: function (data) {
      // Handle checkout
      console.log('Checkout:', data.selections);
    },

    onError: function (error) {
      console.error('Error:', error.message);
    },
  };
</script>

Picker Complete Example

<!DOCTYPE html>
<html>
  <head>
    <title>Select Your Seats</title>
  </head>
  <body>
    <div id="seatsquirrel-picker-root"></div>

    <script>
      window.SeatSquirrelConfig = {
        onReady: async function () {
          const layout = await fetch('/api/layouts/123').then(r => r.json());
          SeatSquirrel.picker.loadLayout(layout);

          const availability = await fetch('/api/availability/123').then(r =>
            r.json(),
          );
          SeatSquirrel.picker.setAvailability({ mode: 'by-slug', ...availability });
        },

        onSelectionChanged: function (data) {
          document.getElementById('cart-count').textContent =
            data.totals.count;
          document.getElementById('cart-total').textContent =
            '$' + (data.totals.amount / 100).toFixed(2);
        },

        onComplete: async function (data) {
          const response = await fetch('/api/checkout', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              selections: data.selections,
              total: data.totals.amount,
            }),
          });
          if (response.ok) {
            window.location.href = '/checkout/success';
          }
        },

        onError: function (error) {
          console.error(error);
        },
      };
    </script>

    <!-- Bundled app script (do not modify) -->
    <script type="module" src="/assets/standalone-picker.js"></script>
  </body>
</html>

For the full list of constructor options, methods, and callbacks see the Picker API Reference.

Best Practices

  1. Wait for onReady — never call API methods before onReady fires.
  2. Load layout before setting availabilitysetAvailability() requires a loaded layout.
  3. Use slugs — slug-based modes (setAvailability({ mode: 'by-slug' }), setPricingCategories({ mode: 'update-by-slug' })) are recommended over label-based alternatives since slugs are stable, human-readable identifiers you control. You may also use ID-based identifiers which are globally unique ids set by the Designer during layout creation.
  4. Track unsaved changes — in the Designer use onLayoutChanged to warn users before navigating away.
  5. Handle errors — always provide an onError callback to surface issues.