Skip to main content

Banners

The Banners Plugin for @inappstory/react-sdk provides a simple way to display banner placements on your website


Table of Contents

  1. Overview
  2. Requirements
  3. Integration
  4. Initialization
  5. Usage
  6. Customization
  7. Events
  8. Tips & Best Practices
  9. Errors & Debugging
  10. FAQ

Overview

The Banners plugin allows you to:

  • Embed banners.
  • Manage display via API or InAppStory Console.
  • Integrate custom sliders (e.g., Swiper.js).
  • React to loading, error, and user interaction events.

Requirements

PlatformCompatibility
JavaScript SDK@inappstory/react-sdk@>=1.8.0
SSR Support❌ No support
TypeScript Support✅ Full
BrowsersModern ES6+ browsers

Integration

npm install @inappstory/react-sdk
import { StoryManager, storyManager } from "@inappstory/react-sdk";
import BannersPlugin from "@inappstory/react-sdk/plugins/banners";

StoryManager.use(BannersPlugin);
/* storyManager.banners is now available */

Initialization

import React, { useState } from "react";
import {
IasBannerCarousel,
type BannerPlace,
type BannerCarouselAppearance,
} from "@inappstory/react-sdk/plugins/banners";

type MyBannerPlaceProps = {
placeId: string; // e.g., "homepage-top"
};

export function MyBannerPlace({ placeId }: MyBannerPlaceProps) {
const [bannerPlace, setBannerPlace] = useState<BannerPlace | null>(null);
const [appearance, setAppearance] = useState<BannerCarouselAppearance>({
autoplay: true,
autoplayDelay: 3000,
gap: 16,
navigation: { enabled: true },
pagination: { enabled: true },
banner: {
borderRadius: 8,
}
});

return (
<IasBannerCarousel
placeId={placeId}
appearance={appearance}
onReady={setBannerPlace}
onLoadStart={() => {
// loading started
}}
onLoadEnd={() => {
// loading finished
}}
onLoadError={(err) => {
// loading error
console.error("Banners load error", err);
}}
/>
);
}

❗️placeId must match the ID from InAppStory Console.
❗️Do not call destroy() on the banner place instance created by <IasBannerCarousel />. Component unmounting handles cleanup automatically.


Usage

Update Appearance

Preferred approach: update the appearance prop.

setAppearance((prev) => ({
...prev,
gap: 24,
banner: {
borderRadius: 16
},
navigation: { enabled: false },
}));

Alternatively, update appearance imperatively (Not recommended, instead use React state management):

bannerPlace.updateAppearance({
gap: 24,
banner: {
borderRadius: 16
},
navigation: { enabled: false },
});

Pause/Resume Autoplay

bannerPlace.resume();
bannerPlace.pause();

Reload Banners

await bannerPlace.reload();

Run transition to next slide.

bannerPlace.showNext();

Run transition to previous slide.

bannerPlace.showPrevious();

Run transition to the slide by index

bannerPlace.showByIndex(index: number, speed?: number);

Access Banner List

const banners = bannerPlace.banners;
banners.forEach((b) => console.log(b.name));

Customization

Appearance Settings

The following appearance settings are supported:

ParameterTypeDescriptionDefault Value
loopbooleanEnables continuous loop mode.true
gapnumberSpacing between slides (in pixels).16
autoplaybooleanEnables automatic slide playback.false
animationSpeednumberTransition duration between slides (in ms).300
navigationobjectNavigation settings.
enabledbooleanEnables default navigation (prev/next buttons).true
paginationobjectPagination settings.
enabledbooleanEnables default pagination (slide indicators/dots).true
bannerobjectBanner settings.
borderRadiusnumberBanner corner rounding (in pixels).16
directionstringList direction. Possible values: row, column. Since 1.8.0.row
allowTouchMovebooleanToggles touch on the list. Since 1.8.0true

Nested properties (navigation.enabled, pagination.enabled, banner.borderRadius) are indicated with .

Custom Navigation Controls

function BannerWithCustomNav({ placeId }: { placeId: string }) {
const [bannerPlace, setBannerPlace] = useState<BannerPlace | null>(null);

return (
<div>
{bannerPlace && <div style={{ display: "flex", gap: 8, marginBottom: 8 }}>
<button onClick={() => bannerPlace.showNext()}>Prev</button>
<button onClick={() => bannerPlace.showPrevious()}>Next</button>
</div>}

<IasBannerPlace
placeId={placeId}
appearance={{ navigation: { enabled: false } }}
onReady={setBannerPlace}
/>
</div>
);
}

Pagination CSS Custom Properties

--ias-banners-pagination-inactive-color: hsla(0, 0%, 100%, 0.5)
--ias-banners-pagination-width: 8px
--ias-banners-pagination-height: 8px

Custom Pagination Indicators

function BannerWithCustomPagination({ placeId }: { placeId: string }) {
const [bannerPlace, setBannerPlace] = useState<BannerPlace | null>(null);
const [totalBullets, setTotalBullets] = useState(0);
const [activeIndex, setActiveIndex] = useState(0);

const updateMeta = () => {
setTotalBullets(bannerPlace.paginationBullets);
setActiveIndex(bannerPlace.activeIndex);
};

const onLoadEnd = () => updateMeta();
const onActiveIndexChange = () =>
setActiveIndex(bannerPlace.activeIndex);

useEffect(() => {
if (!bannerPlace) return;
updateMeta();
bannerPlace.on("loadEnd", onLoadEnd);
bannerPlace.on("activeIndexChange", onActiveIndexChange);

return () => {
bannerPlace.off("loadEnd", onLoadEnd);
bannerPlace.off("activeIndexChange", onActiveIndexChange);
};
}, [bannerPlace]);

return (
<div>
<IasBannerPlace
placeId={placeId}
appearance={{ pagination: { enabled: false } }}
onReady={setBannerPlace}
/>

<div style={{ display: "flex", gap: 6, marginTop: 8 }}>
{bannerPlace && Array.from({ length: totalPages }).map((_, i) => (
<button
key={i}
onClick={() => bannerPlace.showByIndex(i)}
aria-current={i === activeIndex}
style={{
width: 24,
height: 24,
borderRadius: 12,
border: "1px solid #ccc",
opacity: i === activeIndex ? 1 : 0.5,
}}
>
{i + 1}
</button>
))}
</div>
</div>
);
}

Events

loadStart

Description: fired when loading starts.

No payload.


loadEnd

Description: fired when loading ends.

No payload.


loadError

Description: fired when loading fails.

No payload.


activeIndexChange

Description: fired when the active banner changes.

Payload:

FieldTypeDescription
numberIndex of the currently active banner.

autoplayTimeLeft

Description: fired before transition to the next slide after the duration has elapsed.

No payload.


autoplayTimerTick

Description: fired while autoplay timer tick.

Payload:

FieldTypeDescription
bannerIndexnumberBanner index in banner place.
currentTimenumberCurrent progress.
totalTimenumberTotal duration.
percentsnumberCurrent progress in percents.

showBanner

Description: fired when the banner is in the viewport and started.

Payload:

FieldTypeDescription
idstringBanner identifier.
bannerPlacestringBanner place identifier.
payloadstring?Optional additional banner payload data.

showBannerFailed

Description: fired when the banner is in the viewport and error occurs on start.

Payload:

FieldTypeDescription
idstringBanner identifier.
bannerPlacestringBanner place identifier.
errorErrorError that occurred.
payloadstring?Optional additional banner payload data.

bannerWidget

Description: fired when interacting with banner widgets.

Payload:

FieldTypeDescription
idstringBanner identifier.
bannerPlacestringBanner place identifier.
widgetEventNamestringName of the widget event (e.g., "click").
widgetDataRecord<string, any>Arbitrary data related to the widget event.
payloadstring?Optional additional banner payload data.

Example (imperative API):

bannerPlace.on("loadEnd", () => console.log("Loaded"));

When using <IasBannerCarousel />, prefer the onLoadStart, onLoadEnd, and onLoadError props.


Tips and Best Practices

  • Do not call destroy() for an instance created by <IasBannerCarousel />; unmounting the component disposes it automatically.
  • Connect third-party sliders via setSliderController() for full UI/UX control.
  • Use unique placeId values for analytics and A/B testing.
  • Prefer updating appearance through the prop for declarative updates.

Errors and Debugging

ProblemCauseSolution
Banners not showingInvalid placeId or missing contentCheck placeId and ensure banners are configured in the InAppStory Console
loadError firedNetwork error or empty configurationValidate console content and network connection
banners.length === 0No banners configuredFill the banner place in the InAppStory Console

FAQ

Banners are not loading. What should I check?

Verify the placeId and ensure that the banner place contains active content in the InAppStory Console.

Can I use multiple banner places on the same page?

Yes, you can render multiple <IasBannerPlace placeId="..." /> components with different placeId values.

Does it work with SSR/Next.js?

No, the plugin does not support SSR. In Next.js, load it on the client side:

import dynamic from "next/dynamic";

const IasBannerPlace = dynamic(
() => import("@inappstory/react-sdk/plugins/banners").then((module) => module.IasBannerPlace),
{ ssr: false }
);