Skip to main content

Next.js SDK — API Reference & Troubleshooting

Reference for the @bildit-platform/nextjs and @bildit-platform/nextjs-api APIs used in the Integration Guide, plus how free-trial plan entitlement gates production rendering and how to diagnose a blank production site.

How rendering works (architecture)

There are two independent paths, and they never touch each other:

  • Visual Editor (postMessage). When a page is opened inside the VEE, the site's editor bridge and the Visual Editor handshake over postMessage (IFRAME_READYINJECT_SCRIPTSCRIPT_INJECTED): the site injects the Visual Editor script, and the editor pushes scheduled content to it via postMessage. This is for editing slots; it works regardless of plan / API-key state and never calls the public scheduled content endpoint.
  • Production site (server fetch). On your real website, the @bildit-platform/nextjs SDK fetches published scheduled content server-side from {BILDIT_API_URL}/remote-webbanners_v1_4 and renders it through BilditProvider + SlotPlaceholder.

Because they're separate, scheduled content can render in the VEE preview while showing nothing on the production site — that difference is almost always plan entitlement (a free-trial plan is blocked on production) or a location mismatch (below).

Free-trial plan entitlement

Whether your key serves on the production site depends on your plan, not the key itself. On a free trial, the production endpoint returns nothing (the live site stays blank) — while the Visual Editor still renders, because the editor uses a separate path that doesn't go through the keyed endpoint. Upgrade to a paid plan and the same key serves on production; no key re-issue needed.

WhereFree trialPaid plan
Visual Editor✅ renders✅ renders
Production site (real traffic)🚫 blank✅ renders
"Renders in the editor, blank on production"

That's the signature of a free trial, not a key problem. The same key serves once you upgrade. Working as designed.

RemoteConnector (@bildit-platform/nextjs-api)

Server-side data connector. Construct it with your key + Functions base URL, then call getWebBanners.

new RemoteConnector(options)
OptionTypeRequiredNotes
keystringYour web instance API key (sent as ?key=).
baseURLstringVEE Functions base URL. The SDK appends /remote-webbanners_v1_4.
appCheckTokenstringFirebase App Check token, if enabled.
previewDatestringSent as the X-Bildit-Preview-Date header.
timeoutnumberRequest timeout (ms); default 30000.
onResponseFulfilled / onResponseRejectedfunctionAxios response interceptors.

getWebBanners(params)

const result = await connector.getWebBanners({
location: pathname, // match scheduled content by page path
date: previewDate, // optional preview date
mode: 'csr',
tomorrow: true,
source: 'live',
})
// result.data => WebBanner[]
ParamTypeNotes
locationstringMatched against each scheduled content item's assigned location(s). Omit/mismatch → empty result.
datenumber | stringPreview date; omit for production "now".
mode'csr' | 'ssr' | 'both'Render mode.
tomorrowbooleanInclude scheduled content set to start soon.
source'auto' | 'live' | 'cdn''live' fetches the Functions endpoint directly.
apiVersionstringOptional version prefix.

Returns { data, codelib, lastUpdated, meta }; pass data (WebBanner[]) to BilditProvider's banners prop — see the Integration Guide for the wiring.

BilditProvider (@bildit-platform/nextjs)

Client component that processes fetched scheduled content and exposes it to SlotPlaceholder.

PropTypeRequiredNotes
bannersBannerType[]The data from getWebBanners.
extraDependenciesConfigRecord<string, { module, globalName? }>recommendedModules scheduled content may import (see cmsDependencies in the guide).
contentRemoteContentResponse[]Remote content blocks, if used.
extraStylesstring[]Extra CSS to inject.
onRenderError(error) => voidRender-error callback.
errorFallback(bannerId, error) => ReactNodePer-item error UI.

SlotPlaceholder (@bildit-platform/nextjs)

PropTypeRequiredNotes
slotIdstringMust match the web slot assigned to the scheduled content in the VEE.
classNamestringClass on the slot element.
fallback / childrenReactNodeDefault content when no scheduled content is assigned.
forceFallbackbooleanKeep the fallback in place (for admin tooling).
disableStyleScopingbooleanDisable automatic CSS scoping for this slot.

Middleware & preview-date helpers (@bildit-platform/nextjs)

  • enhanceMiddlewareWithBildit(middleware) — wraps your middleware to forward the VEE preview date. Your middleware should also set x-pathname from request.nextUrl.pathname so scheduled content can be matched by location.
  • getPreviewDateFromHeaders(headers) — returns the preview date (epoch ms) from the request headers, or undefined on production traffic.

For the raw HTTP endpoint behind the connector, see Remote API Endpoints.

Troubleshooting: blank on the production site

Work top to bottom — these are ordered by how often they're the culprit:

  1. Preview / trial key — blocked on production by design. Upgrade or use a production key. (See Preview & free-trial keys.)
  2. Scheduled content location — the scheduled content must have a Location matching the page path; /remote-webbanners_v1_4 returns an empty set otherwise. (Note: this is stricter than the legacy non-versioned endpoint, which ignored location.)
  3. BILDIT_API_URL — must be the VEE Functions base URL; the SDK appends /remote-webbanners_v1_4. Wrong host → no scheduled content.
  4. force-dynamic missing — without it the layout is statically cached and never reads the per-request headers.
  5. Env vars in production — are BILDIT_API_KEY and BILDIT_API_URL set in your host's environment (not just locally)? Missing in prod → nothing renders.
  6. transpilePackages missing@bildit-platform/nextjs must be listed, or the build errors.
  7. cmsDependencies incomplete — scheduled content importing an unregistered module throws a render error (check the server/browser console).
  8. Response caching — the connector caches responses (~5 min, in-memory per process). After flipping a key or schedule, wait briefly or redeploy.