> For the complete documentation index, see [llms.txt](https://bogos-api-integration.gitbook.io/bogos-api-integration/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bogos-api-integration.gitbook.io/bogos-api-integration/bogos-js-sdk.md).

# Integration with BOGOS JS/SDK

<details>

<summary>🔔 New Update</summary>

* [Booster](#step-7-booster)

</details>

## Integration flow

```mermaid
flowchart TD
    A[Add the bogos-core script to your page] --> B["updateCore(option)<br/>with cart / customer / locale"]
    B --> C{Which offer do you want?}
    C --> D["Gift: dispatch 'bogos:gifts' on cart change"]
    C --> E["Bundle / Mix-match: add view div<br/>+ dispatch 'bogos:bundle-init'"]
    C --> F["Upsell (FBT): add view div<br/>+ dispatch 'bogos:upsell-init'"]
    C --> G["Discount: add view div<br/>+ dispatch 'bogos:discount-init'"]
    C --> H["Booster: add view div<br/>+ dispatch 'bogos:progress-rerender' / 'bogos:to-widget-render'"]
    D --> I[BOGOS renders the offer UI for you]
    E --> I
    F --> I
    G --> I
    H --> I
```

## 1. Requirements <a href="#requirements" id="requirements"></a>

* Install BOGOS app: [https://apps.shopify.com/freegifts](https://apps.shopify.com/freegifts?utm_source=gitbook\&utm_medium=headlessapi)
* Your store must be built using the [Storefront API](https://shopify.dev/docs/api/storefront).
* Always create a cart after applying BOGOS to ensure the [cart ID](https://shopify.dev/docs/api/storefront/latest/queries/cart#returns-Cart.fields.id) is received correctly. [*Example*](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/root.tsx#L79)
* For advanced customization in your Headless store, refer to the [BOGOS API](/bogos-api-integration/integration-steps.md) documentation.
* Please refer to BOGOS' Demo store for all features demo: [Demo store](https://demo-store-by-bogos.myshopify.com/?utm_source=Headless_docs)

{% hint style="info" %}
If you need integration in a development environment, contact BOGOS via live chat or email at ***<help@bogos.io>***
{% endhint %}

## 2. Installation <a href="#installation" id="installation"></a>

### Version source <a href="#version-source" id="version-source"></a>

```
  BOGOS_JS_SDK=https://cdn.bogos.io/bogos-app-ext/20260309-1773072681/core.min.js
```

### Step 1: Getting started <a href="#step-1-getting-started" id="step-1-getting-started"></a>

1. **Add the following script to your project:**

   ```html
   <script id="bogos-core" src={{BOGOS_JS_SDK}} defer
     data-storefront-api-token={{PUBLIC_STOREFRONT_API_TOKEN}}
     data-api-version={{PUBLIC_STOREFRONT_API_VERSION}}
     data-myshopify-domain={{MYSHOPIFY_DOMAIN}}
     data-bogos-key={{BOGOS_KEY}}
   />
   ```

   | **Property**                             | **Description**                                                                                                                            | **Example**                                        |
   | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- |
   | `VERSION_SOURCE: String!`                | The script URL for the current version                                                                                                     | <https://cdn.bogos.io/\\{{version\\}}/core.min.js> |
   | `PUBLIC_STOREFRONT_API_TOKEN: String!`   | [Public Storefront API token](https://shopify.dev/docs/api/storefront/latest#token-based-authentication)                                   | abcd...                                            |
   | `PUBLIC_STOREFRONT_API_VERSION: String!` | [Storefront API version](https://shopify.dev/docs/api/storefront/latest#versioning)                                                        | 2025-04                                            |
   | `MYSHOPIFY_DOMAIN: String!`              | [Myshopify domain](https://shopify.dev/docs/api/storefront/latest#endpoints-and-queries) (found in **Shopify Admin > Settings**)           | bogos.myshopify.com                                |
   | `BOGOS_KEY: String!`                     | [Key generated by the BOGOS app](https://bogos-api-integration.gitbook.io/bogos-api-integration/integration-requirements#id-4.-middleware) | bogoskey...                                        |

   > 💡 **Example Available**\
   > 👉 [root.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/root.tsx#L164)
2. **Update your project with the required BOGOS data:**

   ```javascript
   typeof window !== 'undefined' && typeof window.BOGOS_CORE !== 'undefined' &&
     window.BOGOS_CORE?.helper?.updateCore(option: BOGOSOptions)
   ```

   ```typescript
   export type BOGOSOptions = {
     cart?: Cart;
     customer?: string | Customer;
     locale?: string; https://shopify.dev/docs/api/storefront/latest#@inContext-(Language)
     country?: string; https://shopify.dev/docs/api/storefront/latest#@inContext-(Country-Code)
     currency?: {
       active: string;
       rate: number;
     };
     market?: {
       id: number;
       handle: string;
     }
   };
   ```

   Note:

   * You must provide at least one of the above properties.

   * If you provide the full Cart object, BOGOS will not fetch the cart again.

   * If only the Cart ID is provided, BOGOS will fetch the cart again.

   * The customer parameter can be either a [customer access token](https://shopify.dev/docs/api/storefront/latest/queries/customer) or [customer object](https://shopify.dev/docs/api/storefront/latest/objects/Customer)

   > 💡 **Example Available**\
   > 👉 [root.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/root.tsx#L131)\
   > 👉 [Layout.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/components/Layout.tsx#L86)\
   > 👉 [Cart.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/components/Cart.tsx#L27)

### Step 2: Gift Offer <a href="#step-2-gift-offer" id="step-2-gift-offer"></a>

1. **Trigger the gift logic whenever the cart is updated:**

   ```javascript
     typeof document !== 'undefined' && document.dispatchEvent(new CustomEvent('bogos:gifts', { detail: cart }));
   ```

   Note:

   * cart: [Cart](https://shopify.dev/docs/api/storefront/latest/objects/Cart)

   * If you provide the full Cart, it won’t fetch again.

   * If only the Cart ID is provided, it will fetch again.

   > 💡 **Example Available**\
   > 👉 [Cart.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/components/Cart.tsx#L24)
2. **Add prepareCheckout to your checkout process to validate gift items before proceeding to checkout:**

   ```javascript
   async function {your_function_checkout} (args) {
       ...
       typeof window !== 'undefined' && typeof window.BOGOS_CORE !== 'undefined' &&
         await BOGOS_CORE?.helper?.gift?.prepareCheckout();
       ...
   }
   ```

   > 💡 **Example Available**\
   > 👉 [Cart.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/components/Cart.tsx#L135)
3. **Customize**

   **3.1. Gift Icon & Gift thumbnail**

   * On the product page Add class "fg-secomapp-product-title" where you want to display gift icon Add class "bogos-gift-thumbnail-view" where you want to display gift thumbnail

   ```javascript
   typeof window !== 'undefined' && window.BOGOS_CORE?.helper?.gift?.renderCustomizeForProduct([{ id: product_id }], { product: true });
   ```

   or

   ```javascript
   // An event is triggered for all customizations on the product page
   typeof document !== 'undefined' && document.dispatchEvent(new CustomEvent("bogos:product-change", {
     detail: {
       products: [{ id: product_id }],
       options: { product: true, selectedVariants?: [{ product_id: product_id, id: selected_variant_id }] }
     }
   }));
   ```

   > 💡 **Example Available**\
   > 👉 [products.$handle.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/routes/products.%24handle.tsx#L164)

   * For collection page Add class "fg-secomapp-collection-img" to where you want to display gift icon on product card

   ```javascript
   typeof window !== 'undefined' && window.BOGOS_CORE?.helper?.gift?.renderCustomizeForProduct([{ id: product.id }], { collection: true });
   ```

   > 💡 **Example Available**\
   > 👉 [collections.$handle.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/routes/collections.%24handle.tsx#L97)

   **3.2. Cart message**

   Add the class "bogos-cart-message-view" to the element where you want the message displayed

   ```html
   <div class="bogos-cart-message-view"></div>
   ```

   **3.3. Gift slider**

   To embed the gift slider instead of displaying as a popup, include the following code:

   ```html
   <div id="freegifts-main-page-container"></div>
   ```

### Step 3: Bundle Offer <a href="#step-3-bundle-offer" id="step-3-bundle-offer"></a>

1. **Classic bundle**

   Add the following element to where you want to display the bundle offer.

   ```html
     <div id="bogos-bundle-view" data-product-handle={{product_handle}} data-product-id={{product_id}} data-offer-id={{offer_id}}></div>

     /* 
       product_id: number; legacy product id
       offer_id: number; BOGOS offer id
     */
   ```

   Dispatch this element to render the bundle offer

   ```javascript
     typeof document !== "undefined" && document.dispatchEvent(new CustomEvent("bogos:bundle-init"));
   ```

   or

   ```javascript
   // An event is triggered for all customizations on the product page
   typeof document !== 'undefined' && document.dispatchEvent(new CustomEvent("bogos:product-change", {
     detail: {
       products: [{ id: product_id }],
       options: { 
         product?: true, 
         selectedVariants?: [{ product_id: product_id, id: selected_variant_id }] 
       }
     }
   }));
   ```

   > 💡 **Example Available**\
   > 👉 [products.$handle.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/routes/products.%24handle.tsx#L164)
2. **Mix-match**

   Add the following element to where you want to display the bundle offer.

   ```html
     <div id="bogos-mix-match-view" data-product-handle={{product_handle}} data-product-id={{product_id}} data-offer-id={{offer_id}}></div>

     /* 
       product_id: number; legacy product id
       offer_id: number; BOGOS offer id
     */
   ```

   Dispatch this element to show bundle offer

   ```javascript
     typeof document !== "undefined" && document.dispatchEvent(new CustomEvent("bogos:bundle-init"));
   ```

   or

   ```javascript
   // An event is triggered for all customizations on the product page
   typeof document !== 'undefined' && document.dispatchEvent(new CustomEvent("bogos:product-change", {
     detail: {
       products: [{ id: product_id }],
       options: { 
         product?: true, 
         selectedVariants?: [{ product_id: product_id, id: selected_variant_id }] 
       }
     }
   }));
   ```

   > 💡 **Example Available**\
   > 👉 [products.$handle.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/routes/products.%24handle.tsx#L164)

### Step 4: Bundle Page <a href="#step-4-bundle-page" id="step-4-bundle-page"></a>

Add the following element to where you want to display the bundle offer.

```html
  <div id="bogos-bundle-page-view" data-offer-id={{offer_id}}></div>

  /* offer_id: number; BOGOS offer id */
```

Dispatch this element to render the bundle offer.

```javascript
  typeof document !== "undefined" && document.dispatchEvent(new CustomEvent("bogos:bundle-page-init"));
```

> 💡 **Example Available**\
> 👉 [bundle-page.$id.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/routes/bundle-page.%24id.tsx#L24)

### Step 5: Upsell Offer <a href="#step-5-upsell-offer" id="step-5-upsell-offer"></a>

1. **Frequently Bought Together (FBT)**

   Add the following element to where you want to display the upsell offer

   ```html
     <div id="bogos-fbt-upsell-view" data-product-handle={{product_handle}} data-product-id={{product_id}} data-offer-id={{offer_id}}></div>

     /* 
       product_id: number; legacy product id
       offer_id: number; BOGOS offer id
     */
   ```

   Dispatch this element to render the upsell offer

   ```javascript
     typeof document !== "undefined" && document.dispatchEvent(new CustomEvent("bogos:upsell-init"));
   ```

   > 💡 **Example Available**\
   > 👉 [products.$handle.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/routes/products.%24handle.tsx#L164)

### Step 6: Discount Offer <a href="#step-6-discount-offer" id="step-6-discount-offer"></a>

1. **Volume Discount**

   Add the following element to where you want to display the discount offer

   ```html
     <div id="bogos-volume-discount-view" data-product-handle={{product_handle}} data-product-id={{product_id}} data-offer-id={{offer_id}}></div>

     /* 
       product_id: number; legacy product id
       offer_id: number; BOGOS offer id
     */
   ```

   Dispatch this element to render the discount offer

   ```javascript
     typeof document !== "undefined" && document.dispatchEvent(new CustomEvent("bogos:discount-init"));
   ```

   or

   ```javascript
   // An event is triggered for all customizations on the product page
   typeof document !== 'undefined' && document.dispatchEvent(new CustomEvent("bogos:product-change", {
     detail: {
       products: [{ id: product_id }],
       options: { 
         product?: true, 
         selectedVariants?: [{ product_id: product_id, id: selected_variant_id }] 
       }
     }
   }));
   ```

   > 💡 **Example Available**\
   > 👉 [products.$handle.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/routes/products.%24handle.tsx#L164)

### Step 7: Booster <a href="#step-7-booster" id="step-7-booster"></a>

1. **Progressing bar**

   Add the following element to where you want to display the progressing bar

   ```html
     <div class="bogos-progressing-bar-view" data-offer-id={{offer_id}}></div>

     /* 
       offer_id: number; BOGOS booster id
     */
   ```

   Dispatch this element to render the progressing bar

   ```javascript
     typeof document !== "undefined" && document.dispatchEvent(new CustomEvent("bogos:progress-rerender"));
   ```

   > 💡 **Example Available**\
   > 👉 [Cart.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/be9dcfb7ffb92e7c9108c9c223488152a98e0034/app/components/Cart.tsx#L38)
2. **Today offer**

   Add the following element to where you want to display the today offer block

   ```html
     <div class="bogos-to-block-view" data-offer-id={{offer_id}}></div>

     /* 
       offer_id: number; BOGOS booster id
     */
   ```

   Dispatch this element to render the today offer block and today offer widget

   ```javascript
     typeof document !== "undefined" && document.dispatchEvent(new CustomEvent("bogos:to-widget-render"));
   ```

   > 💡 **Example Available**\
   > 👉 [\_index.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/be9dcfb7ffb92e7c9108c9c223488152a98e0034/app/routes/_index.tsx#L35)\
   > 👉 [Cart.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/be9dcfb7ffb92e7c9108c9c223488152a98e0034/app/components/Cart.tsx#L26)

## 3. Other integrations <a href="#step-7-other-integration" id="step-7-other-integration"></a>

### 3. 1. Hide gift product (cloned product)

* If you use [products](https://shopify.dev/docs/api/storefront/lastes/queries/products) query, you should add : `query: "tag_not:bogos-gift"`

```graphql
products (
    ...,
    query: "tag_not:bogos-gift"
) {
...
}
```

* For collection and product page, you can import **`checkItemIsGift`** and use returned value to skip gift products or replace to other pages

```typescript
export type ProductObject = {
    handle: string;
    tags: string[];
    variant_id: number;
};

/* item can be product handle */
checkItemIsGift: (item: string | ProductObject) => boolean;
```

> 💡 **Example Available**\
> 👉 [collections.$handle.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/routes/collections.%24handle.tsx#L107)\
> 👉 [products.$handle.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/routes/products.%24handle.tsx#L193)

### 3.2. Customize gift popup/slider

* Hide all default gift slider elements, and override with your custom implementation.

```css
  #freegifts-main-popup-container, #freegifts-main-page-container {
    display: none !important;
  }
```

```typescript
type GiftItem = {
    id: number;
    discount_type: 'percentage' | 'fixed_amount';
    discount_value: number;
    original_price: number;  // Original price - price before discount
    price: number;           // Discount price - price after discount
    title: string;
    thumbnail?: string;
};

type GiftProduct = {
    id: number;
    title: string;
    handle: string;
    thumbnail?: string;
    belongs_to_offer: string;
    variants: GiftItem[];
};

document.addEventListener("fg-gifts:show-slider", (e) => {
    console.log((e as CustomEvent).detail);
    /* render gift slider with detail {
        addGiftToCartFunc: (variant_id: number, quantity: number, offer_id: number) => {};
        gifts?: GiftProduct[]; // show all gifts
        giftsOffer?: { // show gifts by offer
          arrGiftShow: GiftProduct[];
        }
    } */
});

```

### 3.3. Details of additional event listeners

* `fg-gifts:updated`: Event gift is updated in cart

```typescript
document.addEventListener("fg-gifts:updated", (e) => {
    /* use this function to re-render cart */
    console.log((e as CustomEvent).detail);
});
```

> 💡 **Example Available**\
> 👉 [Layout.tsx](https://github.com/krycek-fengdx/bogos-headless-js/blob/f17a2faab77baa85413af3fa3ad36bf28019d97a/app/components/Layout.tsx#L61)

* `fg-cart:auto-updated`: Event gift auto add

```typescript
document.addEventListener("fg-cart:auto-updated", (e) => {
    console.log((e as CustomEvent).detail);
});
```

* `fg-gifts:added`: Fired when a gift is added from the slider. This event will not fire if you customize the gift popup/slider (see section 3.2 above).

```typescript
document.addEventListener("fg-gifts:added", (e) => {
    console.log((e as CustomEvent).detail);
});
```

* `fg-gifts:gift-icon`: Show gift icons
* `bogos:message`: Show cart message

## 4. Note <a href="#notice" id="notice"></a>

{% hint style="info" %}
For deeper customization, please contact our support team via live chat or email - <help@bogos.io>
{% endhint %}

### 4.1. Publish Gift/Cloned Products <a href="#publish-giftcloned-products" id="publish-giftcloned-products"></a>

* After creating or editing an offer, ensure that the gift/cloned product is published to your Headless channel (or any channel where you want BOGOS to run).

### 4.2. Some features are not yet available in this version

* Draft-Order API
* Market
* Bundle page button block
* Some Shopify object-based params (if only id provided, BOGOS will fetch the rest).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://bogos-api-integration.gitbook.io/bogos-api-integration/bogos-js-sdk.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
