> ## Documentation Index
> Fetch the complete documentation index at: https://docs.topsort.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Banners.js

> Learn how to integrate Topsort with Banners.js

export const IntegrationsCard1A = () => {
  return <>
      <style>{`
        .integrations-card-1a {
          display: flex;
          flex-direction: column;
          background-color: #f0f2f4;
          border: 1px solid rgba(0, 0, 0, 0.08);
          border-radius: 12px;
          padding: 1.25rem 1.5rem;
          gap: 0.25rem;
          color: #25253b;
          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
          transition: box-shadow 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
          margin-top: 2rem;
        }

        .integrations-card-1a:hover {
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
          border-color: rgba(0, 0, 0, 0.12);
        }

        .dark .integrations-card-1a {
          background-color: #25253b;
          color: #f6f8fa;
          border-color: rgba(255, 255, 255, 0.08);
          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        }

        .dark .integrations-card-1a:hover {
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
          border-color: rgba(255, 255, 255, 0.12);
        }

        .integrations-card-1a-avatar-row {
          display: flex;
          margin-left: 14px;
          flex-wrap: nowrap;
        }

        .integrations-card-1a-avatar {
          width: 44px;
          height: 44px;
          border-radius: 50%;
          border: 2px solid #f0f2f4;
          margin-left: -14px;
          object-fit: cover;
          box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
          pointer-events: none;
          cursor: default;
        }

        .dark .integrations-card-1a-avatar {
          border-color: #25253b;
          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        }

        .integrations-card-1a h2 {
          margin: 0;
          line-height: 1.25;
          font-size: clamp(1.25rem, calc(0.875rem + 1.25vw), 1.75rem);
          font-weight: 700;
          letter-spacing: -0.025em;
          color: #111827;
        }

        .dark .integrations-card-1a h2 {
          color: #f9fafb;
        }

        .integrations-card-1a-subtitle {
          font-size: 0.9375rem;
          font-weight: 500;
          line-height: 1.5;
          color: #4b5563;
          margin: 0;
        }

        .dark .integrations-card-1a-subtitle {
          color: #d1d5db;
        }

        .integrations-card-1a p {
          margin: 0;
          line-height: 1.5;
          font-size: 0.875rem;
          color: #374151;
        }

        .dark .integrations-card-1a p {
          color: #d1d5db;
        }

        .integrations-card-1a a {
          color: #0500ff;
          text-decoration: none;
          font-weight: 500;
          transition: color 0.15s ease;
        }

        .integrations-card-1a a:hover {
          color: #0400cc;
        }

        .dark .integrations-card-1a a {
          color: #8280ff;
        }

        .dark .integrations-card-1a a:hover {
          color: #a19fff;
        }

        @media (max-width: 640px) {
          .integrations-card-1a-avatar {
            width: 38px;
            height: 38px;
            margin-left: -12px;
          }

          .integrations-card-1a-avatar-row {
            margin-left: 12px;
          }
        }

        @media (min-width: 1280px) {
          .integrations-card-1a p {
            font-size: 0.6875rem;
            line-height: 1.4;
            letter-spacing: -0.01em;
          }

          .integrations-card-1a h2 {
            font-size: clamp(1rem, calc(0.75rem + 1vw), 1.25rem);
          }

          .integrations-card-1a-subtitle {
            font-size: 0.75rem;
          }
        }
      `}</style>
      <div className="integrations-card-1a">
        <div className="integrations-card-1a-avatar-row">
          <img src="/images/integration-team/agustin.webp" alt="Agustin - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/amelia.webp" alt="Amelia - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/bernardita.webp" alt="Bernardita - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/borumy.webp" alt="Borumy - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/felipe.webp" alt="Felipe - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/gui.webp" alt="Gui - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/javiera.webp" alt="Javiera - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/linn.webp" alt="Linn - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/marcio.webp" alt="Marcio - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/mateus.webp" alt="Mateus - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/max.webp" alt="Max - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
          <img src="/images/integration-team/rodrigo.webp" alt="Rodrigo - Integrations Team Member" loading="lazy" className="integrations-card-1a-avatar" />
        </div>

        <h2>Need help with your Topsort integration?</h2>

        <p className="integrations-card-1a-subtitle">
          Talk to us, the integrations engineering team.
        </p>

        <p>
          Reach us via <strong>your dedicated messaging channel</strong> or at{" "}
          <a href="mailto:support@topsort.com">support@topsort.com</a>.
        </p>

        <p>
          If you're not a customer yet,{" "}
          <a href="https://www.topsort.com/book-a-demo">book a demo</a> with our
          sales team instead.
        </p>
      </div>
    </>;
};

Topsort's [banner.js public library](https://github.com/Topsort/banners.js/) allows marketplaces display banner ads through a low-code integration. By using a simple HTML tag, the marketplace can connect to Topsort's ad server and render banners from active campaigns without complex integrations.

## Installation

You can install the library using npm or yarn, or load the SDK directly in your HTML file by including a `<script>` tag:

```html theme={null}
<script
  async
  type="module"
  src="https://unpkg.com/@topsort/banners@latest/dist/banners.mjs"
></script>
<script>
  // Global configuration for Topsort
  window.TS = {
    token: "TSE_XXXXXXXXXXXX", // Replace with your Topsort API key
  };
</script>
```

## Usage

This example shows a minimal setup required to do it. The integration works with standard HTML and Javascript, making it compatible with most frontend stacks.

To test it, you just need to add your Marketplace API Key and the banner slot id, configured in the campaign.

```html theme={null}
<script
  async
  type="module"
  src="https://unpkg.com/@topsort/banners@latest/dist/banners.mjs"
></script>
<script
  async
  type="module"
  src="https://unpkg.com/@topsort/analytics.js/dist/ts.js"
></script>
<script>
  // Set API key for auctions and events
  window.TS = {
    token: "TSE_XXXXXXXXXXXX",
  };
  // Custom behavior can be configured for each site.
  window.TS_BANNERS = {
    // handle the destination link
    getLink(banner) {
      return `https://example.com/${banner.id}`;
    },
    // handle loading/fetching state
    getLoadingElement() {
      const el = document.createElement("div");
      el.innerText = "Loading...";
      return el;
    },
    // handle errors
    getErrorElement() {
      const el = document.createElement("div");
      el.innerText = "Error loading banner";
      return el;
    },
  };
</script>
<body>
  <topsort-banner width="600" height="400" id="<your slot id>"></topsort-banner>
</body>
```

## Banner Attributes

These are the attributes available for the `<topsort-banner>` component. They serve as input to the auction request, to fetch the right winners for that context.

| Name                    | Type   | Description                                             |
| ----------------------- | ------ | ------------------------------------------------------- |
| width                   | number | Banner width                                            |
| height                  | number | Banner height                                           |
| id                      | string | The slot ID for this banner, configured at the campaign |
| Category-id (optional)  | string | Contextual category for targeting                       |
| Search-query (optional) | string | Contextual keyword for targeting                        |

## Banner Behaviors

These are the attributes available for the `<topsort-banner>` component. They serve as input to the auction request, to fetch the right winners for that context.

| Name              | Type        | Description                                                |
| ----------------- | ----------- | ---------------------------------------------------------- |
| getLink(banner)   | string      | Destination URL of the banner, configured at the campaign. |
| getLoadingElement | HTMLElement | A custom element to be shown when the banner is loading.   |
| getErrorElement   | HTMLElement | A custom element to be shown when an error occurs.         |

## Banner Interface

The banner interface is the structure of a banner object. Each banner contains metadata about the campaign, and the resolvedBidId, the parameter needed for tracking user interactions (clicks and impressions).

| Name          | Type                                      | Description                                                                                                             |
| ------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| type          | "product" \| "vendor" \| "brand" \| "url" | The type of the winning entity, represented by the banner, configured at the campaign.                                  |
| id            | string                                    | The ID of the winning entity. If the entity is of type URL, this is the URL.                                            |
| resolvedBidId | string                                    | The corresponding bid ID of the winning entity, needed for tracking user interaction (clicks, impressions) with the ad. |
| asset         | \[\{ url: string }]                       | An array of urls linking to the assets of the banner.                                                                   |

<IntegrationsCard1A />
