Last updated

FairShare Web Widgets

This package provides web components for integrating FairShare into your website using a simple script tag approach.

CDN/Script Tag Distribution

Use this method for direct inclusion in a website without a build step.

<!-- Basic server-side attribution -->
<script
  id="fluid-cdn-script"
  src="https://assets.fluid.app/scripts/fluid-sdk/latest/web-widgets/index.js"
  data-fluid-shop="your-shop-id"
  data-fluid-api-base-url="https://api.your-custom-endpoint.com"
></script>

<!-- With attribution override -->
<script
  id="fluid-cdn-script"
  src="https://assets.fluid.app/scripts/fluid-sdk/latest/web-widgets/index.js"
  data-fluid-shop="your-shop-id"
  data-share-guid="your-affiliate-id"
></script>

<!-- Add the cart widget anywhere on your page -->
<fluid-cart-widget
  position="bottom_right"
  fluidShopDisplayName="Your Store Name"
></fluid-cart-widget>

Key Benefits of CDN Distribution

  • No build process required - Works with any HTML page
  • Automatic style injection - No separate CSS file to include
  • Single script tag does everything - Initializes SDK, loads styles, registers components
  • Server-side attribution - Attribution calculated automatically server-side

Configuration Options

Data AttributeDescriptionRequired
data-fluid-shopYour FairShare shop identifierYes
data-share-guidAttribution override share GUID (overrides server-side)No
data-fluid-rep-idAttribution override Fluid Rep ID (numeric)No
data-emailAttribution override email addressNo
data-usernameAttribution override usernameNo
data-external-idAttribution override external IDNo
data-fluid-api-base-urlCustom API endpoint URL for development or testing environmentsNo
data-debugEnable debug mode (set to "true" to enable)No

The data-fluid-api-base-url attribute allows you to specify a custom API endpoint for local development or testing against different environments. When not provided, the system uses the default production endpoint.

Server-Side Attribution: Attribution is calculated server-side automatically based on the current page URL. The system detects page changes (including SPA navigation) and refreshes attribution data as needed. Use attribution override attributes when you need to override this with specific attribution values. Attribution methods are checked in priority order: share-guid → fluid-rep-id → email → username → external-id.

Controlling the Cart

There are two ways to control the cart functionality:

Declarative Controls (HTML)

Use data attributes for the simplest implementation:

<button data-fluid-cart="open">Open Cart</button>
<button data-fluid-cart="close">Close Cart</button>
<button data-fluid-cart="toggle">Toggle Cart</button>

JavaScript Controls

For programmatic control using the FairShare SDK:

// Primary SDK (recommended)
window.FairShareSDK.cart.control.open();
window.FairShareSDK.cart.control.close();
window.FairShareSDK.cart.control.toggle();

// Legacy cart controls (for backwards compatibility)
window.fluidCart.open();
window.fluidCart.close();
window.fluidCart.toggle();

Cart Settings Override

You can dynamically override cart widget settings using the nested settings API:

// Override cart widget settings dynamically
window.FairShareSDK.cart.settings.set({
  hideWidget: true, // Hide the cart button but keep functionality
  position: "top_left", // Change position: 'top_left', 'top_right', 'bottom_left', 'bottom_right'
  size: 80, // Change button size in pixels
  placement: "left", // Cart drawer placement: 'left' or 'right'
  primaryColor: "#ff6b35", // Override primary color
  secondaryColor: "#2d3748", // Override secondary color
  xMargin: 20, // Horizontal margin from screen edge
  yMargin: 50, // Vertical margin from screen edge
});

// Get current cart settings overrides
const cartSettings = window.FairShareSDK.cart.settings.get();

// Clear all cart settings overrides (revert to server settings)
window.FairShareSDK.cart.settings.clear();

Cart Settings Override Properties:

PropertyTypeDescription
hideWidgetbooleanHide the cart button while keeping cart functionality accessible
positionstringButton position: 'top_left', 'top_right', 'bottom_left', 'bottom_right'
sizenumberButton size in pixels
placementstringCart drawer placement: 'left' or 'right'
primaryColorstringPrimary color for cart styling
secondaryColorstringSecondary color for cart styling
xMarginnumberHorizontal margin from screen edge in pixels
yMarginnumberVertical margin from screen edge in pixels
shopobjectOverride shop information (name, primary_color, logo_url)
affiliateobjectOverride affiliate information (name, image_url)

Page-Scoped Settings:

Cart settings are automatically scoped to the current page URL path (excluding query parameters and fragments). This means:

  • Settings on /products page won't affect /checkout page
  • Settings persist across page reloads for the same path
  • Each page can have its own independent cart configuration
// Settings are automatically scoped to current page
window.FairShareSDK.cart.settings.set({ hideWidget: true }); // Only affects current page

Note: Cart settings overrides are applied immediately and persist until cleared. They take precedence over server-side settings and original widget attributes.

Chat Settings Override

You can dynamically override chat widget (lead capture) settings using the nested settings API:

// Override chat widget settings dynamically
window.FairShareSDK.chat.settings.set({
  hideWidget: true, // Hide the chat button but keep functionality
  position: "top_left", // Change position: 'top_left', 'top_right', 'bottom_left', 'bottom_right'
  size: 80, // Change button size in pixels
  primaryColor: "#ff6b35", // Override primary color
  xMargin: 20, // Horizontal margin from screen edge
  yMargin: 50, // Vertical margin from screen edge
  title: "Need help?", // Override widget title
  description: "Chat with us!", // Override description text
  submitButtonText: "Send Message", // Override submit button text
  successMessage: "Thanks! We'll be in touch soon.", // Override success message
  contactMethod: "phone", // Override contact method: 'email' or 'phone'
});

// Get current chat settings overrides
const chatSettings = window.FairShareSDK.chat.settings.get();

// Clear all chat settings overrides (revert to server settings)
window.FairShareSDK.chat.settings.clear();

Chat Settings Override Properties:

PropertyTypeDescription
hideWidgetbooleanHide the chat button while keeping chat functionality accessible
positionstringButton position: 'top_left', 'top_right', 'bottom_left', 'bottom_right'
sizenumberButton size in pixels
primaryColorstringPrimary color for chat styling
xMarginnumberHorizontal margin from screen edge in pixels
yMarginnumberVertical margin from screen edge in pixels
titlestringWidget title text displayed in the header
descriptionstringDescription text shown in the chat bubble
submitButtonTextstringText displayed on the submit button
successMessagestringMessage shown after successful form submission
contactMethodstringContact method: 'email' or 'phone'

Page-Scoped Settings:

Chat settings are automatically scoped to the current page URL path (excluding query parameters and fragments). This means:

  • Settings on /products page won't affect /checkout page
  • Settings persist across page reloads for the same path
  • Each page can have its own independent chat configuration
// Settings are automatically scoped to current page
window.FairShareSDK.chat.settings.set({ hideWidget: true }); // Only affects current page

Note: Chat settings overrides are applied immediately and persist until cleared. They take precedence over server-side settings and original widget attributes.

JavaScript SDK Functions

The FairShare SDK provides comprehensive functionality through window.FairShareSDK. All functions are also available on window.FluidCommerceSDK for backwards compatibility.

Cart Management

// Get the current cart
const cart = await window.FairShareSDK.getCart();

// Get cart from local storage (no API call)
const localCart = window.FairShareSDK.getLocalCart();

// Get current cart item count
const itemCount = window.FairShareSDK.getCartItemCount();

// Add items to cart
await window.FairShareSDK.addCartItems([
  { variant_id: 123, quantity: 2, subscribe: true },
  { variant_id: 456, quantity: 1 },
]);

// Add single item to cart
await window.FairShareSDK.addCartItems(123, { quantity: 2, subscribe: true });

// Remove/decrement cart item
await window.FairShareSDK.decrementCartItem(123, { quantity: 1 });

// Remove cart item by ID
await window.FairShareSDK.removeCartItemById(456);

// Update cart items
await window.FairShareSDK.updateCartItems([{ variant_id: 123, quantity: 3 }]);

// Subscribe/unsubscribe cart items
await window.FairShareSDK.subscribeCartItem(itemId, subscriptionPlanId);
await window.FairShareSDK.unsubscribeCartItem(itemId);

// Clear entire cart
await window.FairShareSDK.clearCart();

// Proceed to checkout
await window.FairShareSDK.checkout();

// Get checkout URL
const checkoutUrl = window.FairShareSDK.getCheckoutUrl();

Enrollment Packs

// Add enrollment pack to cart
await window.FairShareSDK.addEnrollmentPack(42);

Lead Capture

// Capture lead information
await window.FairShareSDK.captureLead({
  first_name: "John",
  last_name: "Doe",
  email: "john@example.com",
  phone: "+1234567890",
  message: "I'm interested in your products",
});

Media & Library Functions

// Get library/playlist data
const library = await window.FairShareSDK.getLibrary("library-slug-or-id");

// Get media data
const media = await window.FairShareSDK.getMedia("media-slug-or-id");

Settings & Configuration

// Fetch settings from API
const settings = await window.FairShareSDK.fetchSettings();

// Get cached settings
const cachedSettings = window.FairShareSDK.getSettings();

// Get settings (fetch if not cached)
const settings = await window.FairShareSDK.getOrFetchSettings();

// Update locale settings
await window.FairShareSDK.updateLocaleSettings({
  language: "en",
  country: "US",
});

// Get current country code and language
const countryCode = window.FairShareSDK.getCountryCode();
const language = window.FairShareSDK.getLanguage();

Authentication

// Set authentication token
await window.FairShareSDK.setAuthentication("jwt-token");

// Get authenticated user
const user = window.FairShareSDK.getAuthenticatedUser();

Affiliate Lookup

// Look up affiliate by various attribution methods
const affiliate = await window.FairShareSDK.lookupAffiliate({
  share_guid: "affiliate-share-guid",
});

const affiliate = await window.FairShareSDK.lookupAffiliate({
  email: "affiliate@example.com",
});

Custom Checkout Handler

// Set custom checkout handler
window.FairShareSDK.setOnCheckout(async () => {
  // Custom checkout logic
  console.log("Custom checkout triggered");
  // Redirect to custom checkout page, etc.
});

// Get current checkout handler
const handler = window.FairShareSDK.getOnCheckout();

Event Tracking & Analytics

// Track custom events
window.FairShareSDK.trackFairshareEvent({
  event: "custom_event",
  properties: { key: "value" },
});

// Track checkout started
window.FairShareSDK.trackCheckoutStarted({ cart_token: "token" });

// Get session token
const sessionToken = window.FairShareSDK.getSessionToken();

// Get attribution data
const attribution = window.FairShareSDK.getAttribution();

// Flush pending events
await window.FairShareSDK.flushEvents();

// Flush events with beacon (for page unload)
await window.FairShareSDK.flushEventsWithBeacon();

SDK Management

// Initialize FairShare SDK manually (usually done automatically via data attributes)
window.FairShareSDK.initializeFluid({
  fluidShop: "your-shop-id",
  debug: true,
});

// Reset SDK state
window.FairShareSDK.reset();

// Reset FairShare tracking only
window.FairShareSDK.resetFairshare();

Displaying Cart Count

You can easily display the current cart item count anywhere on your page by using an element with the ID fluid-cart-count. The SDK will automatically update this element whenever the cart changes.

<!-- Simple cart count display -->
<span id="fluid-cart-count">0</span>

<!-- Cart count with styling -->
<div class="cart-icon">
  <i class="fas fa-shopping-cart"></i>
  <span class="badge" id="fluid-cart-count">0</span>
</div>

The cart count is updated automatically when:

  • Items are added to the cart
  • Items are removed from the cart
  • Item quantities are updated
  • The cart is cleared
  • A new cart is created
  • The cart is refreshed from the API

Adding Products to Cart

Declarative Product Controls (HTML)

Use data attributes to add products to cart without writing JavaScript:

<!-- Add a single product (variant) to cart -->
<button data-fluid-add-to-cart="123456">Add to Cart</button>

<!-- Specify quantity -->
<button data-fluid-add-to-cart="123456" data-fluid-quantity="2">
  Add 2 to Cart
</button>

<!-- Add to cart and open cart drawer immediately -->
<button data-fluid-add-to-cart="123456" data-fluid-open-cart-after-add="true">
  Add to Cart and View
</button>

<!-- Add with subscription enabled -->
<button data-fluid-add-to-cart="123456" data-fluid-subscribe="true">
  Add with Subscription
</button>

<!-- Add multiple products with different subscription settings -->
<button
  data-fluid-add-to-cart="123456,789012"
  data-fluid-subscribe="true,false"
>
  Add Multiple Items
</button>

<!-- Combine subscription with quantity and cart opening -->
<button
  data-fluid-add-to-cart="123456"
  data-fluid-subscribe="true"
  data-fluid-quantity="2"
  data-fluid-open-cart-after-add="true"
>
  Add 2 with Subscription and View
</button>

Adding Enrollment Packs

Enrollment packs can be added to the cart using data attributes:

<!-- Add an enrollment pack to cart -->
<button data-fluid-add-enrollment-pack="42">Add Enrollment Pack</button>

<!-- Add enrollment pack and open cart drawer immediately -->
<button
  data-fluid-add-enrollment-pack="42"
  data-fluid-open-cart-after-add="true"
>
  Add Enrollment Pack and View
</button>

Customizing Widget Styles

You can customize the widgets to match your brand's color scheme and typography using CSS variables:

/* In your CSS file */
:root {
  --company-color: #3461ff; /* Replace with your brand color */
  --ff-body: "Your Custom Font", sans-serif; /* Your custom font */
}

Available customization variables:

  • --company-color: Controls primary colors, accents, and highlights
  • --ff-body: Sets the font family used throughout the widgets (falls back to system fonts if not specified)

Available Components

Cart Widget (<fluid-cart-widget>)

Attribute/PropertyTypeDefaultDescription
useBrandbooleanfalseWhether to use brand colors
primaryColorstring-Primary color for the cart widget
secondaryColorstring-Secondary color for the cart widget
placementstring-Placement of cart sheet: 'right' or 'left'
positionstring'bottom_right'Position on screen: 'top_left', 'top_right', 'bottom_left', 'bottom_right'
sizenumber60Size of the widget button in pixels
xMarginnumber40Horizontal margin from the edge of the screen in pixels
yMarginnumber98Vertical margin from the edge of the screen in pixels
fluidShopDisplayNamestring'Fluid'Shop name displayed in the cart header
hideWidgetbooleanfalseWhen true, hides button but keeps cart functionality
demoModebooleanfalseEnable demo mode to prevent SDK API calls for testing
alwaysOpenbooleanfalseIf true, the cart sidebar is always open (no floating button)

Lead Capture Widget (<fluid-lead-capture-widget>)

Attribute/PropertyTypeDefaultDescription
use-brandbooleanfalseWhether to use brand colors
primary-colorstring-Primary color for the widget
secondary-colorstring-Secondary color for the widget
titlestring'Have a question?'Title of the widget
descriptionstring"We'd love to get in touch!"Description text
submit-button-textstring'Send Message'Text for the submit button
success-messagestring"Thank you for your message! We'll get back to you soon."Success message shown after form submission
showbooleantrueWhether to show the widget
positionstring'bottom_right'Position on screen: 'top_left', 'top_right', 'bottom_left', 'bottom_right'
sizenumber60Size of the widget trigger button in pixels
z-indexnumber9999Z-index for layering
x-marginnumber40Horizontal margin from the edge of the screen in pixels
y-marginnumber98Vertical margin from the edge of the screen in pixels
hide-widgetbooleanfalseWhen true, hides trigger button but keeps functionality accessible
avatar-srcstring-Avatar image URL
logo-srcstring-Logo URL for the footer
logo-altstring-Logo alt text
footer-textstring'Use is subject to terms'Footer text
terms-urlstring'https://fluid.app/terms-conditions'URL for the terms and conditions page
fluid-shop-display-namestring'Fluid'Shop display name for the consent text
contact-methodstring'email'Preferred contact method: 'email' or 'phone'
attract-bubble-show-delaynumber1000Milliseconds to wait before showing the attract bubble
attract-bubble-hide-delaynumber20000Milliseconds to wait before hiding the attract bubble

Media Widget (<fluid-media-widget>)

Attribute/PropertyTypeDefaultDescription
library-idstring-Library ID to fetch media from
media-idstring-Single media ID to display
hide-widgetbooleanfalseWhether to hide the media widget
class-namestring-Optional additional CSS classes
heightstring-Height of the thumbnail
widthstring-Width of the thumbnail

Future features coming soon:

  • embed-type (string, default: "popover") - Controls how the media widget displays, options: "popover" or "inline"
  • auto-open (boolean, default: false) - Automatically opens the media widget on load (only works when embedType is "popover", ignored when embedType is "inline")

Usage Examples

<!-- Basic media widget with library ID -->
<fluid-media-widget library-id="your-library-id"></fluid-media-widget>

<!-- Media widget with specific media ID -->
<fluid-media-widget media-id="your-media-id"></fluid-media-widget>

<!-- Media widget with custom dimensions -->
<fluid-media-widget
  library-id="your-library-id"
  height="300px"
  width="500px"
></fluid-media-widget>

<!-- Media widget with custom CSS classes -->
<fluid-media-widget
  media-id="your-media-id"
  class-name="custom-media-widget my-style"
></fluid-media-widget>