@vulcantech/banners
v0.1.1
Published
CMS-driven announcement banners for consumer sites — top/bottom positions, page targeting, priority ordering, and dismissible bars backed by localStorage
Maintainers
Readme
@vulcantech/banners
CMS-driven announcement banners for VulcanTech consumer sites. Renders top/bottom bars fetched from the CMS, with page targeting, priority ordering, and per-user dismissal (localStorage).
Exports: CMSBanners (drop-in layout component), BannerBar (single bar), and the BannerData type.
Integration
Wire banners into a consumer site (Next.js App Router):
1. Add the dependency:
npm install @vulcantech/banners(Inside the VulcanTech monorepo, use the workspace wiring in MONOREPO.md instead.)
2. Set the env — see Required env below.
3. Create the server fetcher src/lib/cms/banners.ts (ISR-cached, fails open):
import type { BannerData } from "@vulcantech/banners";
const CMS_URL = process.env.VULCANTECH_CMS_URL || "https://cms.vulcantech.io";
const PROJECT_ID = process.env.VULCANTECH_PROJECT_ID;
const API_KEY = process.env.VULCANTECH_API_KEY;
export async function fetchBanners(): Promise<BannerData[]> {
if (!PROJECT_ID || !API_KEY) return [];
const params = new URLSearchParams({ projectId: PROJECT_ID, apiKey: API_KEY });
try {
const res = await fetch(`${CMS_URL}/api/banners?${params}`, {
next: { revalidate: 60, tags: [`banners:${PROJECT_ID}`] },
});
if (!res.ok) return [];
const json = (await res.json()) as { banners: BannerData[] };
return json.banners ?? [];
} catch {
return [];
}
}4. Render in the root layout (src/app/layout.tsx):
import { CMSBanners } from "@vulcantech/banners";
const banners = await fetchBanners();
// <body>
// <CMSBanners banners={banners} position="top" />
// {children}
// <CMSBanners banners={banners} position="bottom" />
// </body>5. ISR invalidation — ensure src/app/api/revalidate/route.ts exists; the CMS purges the banners:{projectId} tag when a banner is edited.
Required env
VULCANTECH_PROJECT_ID, VULCANTECH_API_KEY (required) · VULCANTECH_CMS_URL (optional, defaults to https://cms.vulcantech.io).
Per-app values
None beyond env — banners is fully config-driven from the CMS.
Notes
- Components are
"use client"; dismissal persists tolocalStorage(vulcantech_dismissed_banners).
