Business Details
The page bundle includes the business identity that your BusinessDash account owns: organization-wide defaults, public business locations, social profiles, structured data, and share metadata. Use the same response for contact UI, location pages, footers, local SEO, and social links.
The top-level address, phone, hours, and service areas remain
organization-wide defaults. profile.locations is the canonical source for
branches, stores, offices, showrooms, warehouses, and service centers.
Location values override the defaults when present.
Fetch the company bundle
import { createBdApiClient } from '@businessdash/sdk'
const client = createBdApiClient({
baseUrl: process.env.BD_API_URL!,
apiKey: process.env.BD_API_KEY!,
})
const bundle = await client
.site(process.env.BD_SITE_ID!)
.marketing
.getPageBundle({ pageKey: 'home', locale: 'en' })
const company = bundle.company
const profile = company?.profile
const locations = profile?.locations ?? []
const primaryLocation =
locations.find((location) => location.isPrimary) ?? locations[0] ?? null
company contains:
| Property | Purpose |
|---|---|
profile | Company defaults, social profiles, and locations |
jsonLd | The parent schema.org Organization node |
locationJsonLd | One LocalBusiness node per public location |
shareMetadata | Title, description, image URL, and site name |
Organization defaults and location overrides
This two-level model avoids duplicating common values:
company.profile
├─ website, phone, supportEmail
├─ address, operationHours, serviceAreas
└─ locations[]
├─ Downtown showroom (primary, public)
├─ North service center (public)
└─ Fulfillment warehouse (internal)
A location can provide its own phone, email, website, hours, and service
areas. If it omits hours or service areas, BusinessDash's generated structured data
inherits the organization-wide value. isPublic: false keeps an internal
location in BusinessDash without publishing a location JSON-LD node.
Location shape
Import the SDK type when building location cards, route parameters, or custom forms:
import type { BusinessLocation } from '@businessdash/sdk'
function LocationCard({ location }: { location: BusinessLocation }) {
return {
name: location.name,
href: `/locations/${location.slug}`,
phone: location.phone,
address: location.address,
}
}
| Field | Meaning |
|---|---|
id | Stable location identity |
name | Customer-facing branch name |
slug | Stable URL and JSON-LD key |
isPrimary | Marks the default location; at most one can be primary |
isPublic | Controls public SDK structured-data output |
type | office, store, showroom, warehouse, service_center, or other |
businessType | Optional schema.org subtype such as Restaurant or HVACBusiness |
address | Street, locality, region, postal code, and two-letter country code |
phone, webPhone, supportEmail, website | Location-specific contact overrides |
googlePlaceId | Location-specific Google Maps identity |
latitude, longitude, timezone | Geo and scheduling metadata |
operationHours, serviceAreas | Optional location-specific overrides |
BusinessDash validates unique location IDs and slugs and permits no more than one primary location.
Render a location selector
Select by stable id in application state and use slug in public URLs:
import type { BusinessLocation } from '@businessdash/sdk'
export function LocationSelect({
locations,
selectedId,
onSelect,
}: {
locations: BusinessLocation[]
selectedId: string | null
onSelect: (location: BusinessLocation) => void
}) {
const publicLocations = locations.filter((location) => location.isPublic)
return (
<select
value={selectedId ?? ''}
onChange={(event) => {
const selected = publicLocations.find(
(location) => location.id === event.target.value,
)
if (selected) onSelect(selected)
}}
>
<option value="" disabled>Select a location</option>
{publicLocations.map((location) => (
<option key={location.id} value={location.id}>
{location.name}
</option>
))}
</select>
)
}
For a route such as /locations/[slug], select by code:
const location = locations.find((item) => item.slug === params.slug)
if (!location || !location.isPublic) {
notFound()
}
Structured data for every location
BusinessDash emits an Organization parent and one independently addressable
LocalBusiness node per public location. This is more precise than putting
several unrelated addresses on one LocalBusiness.
import { renderJsonLdNodes } from '@businessdash/sdk'
const nodes = [
company.jsonLd,
...(company.locationJsonLd ?? []),
]
export function BusinessJsonLd() {
return renderJsonLdNodes(nodes).map(({ type, html }, index) => (
<script
key={index}
type={type}
dangerouslySetInnerHTML={{ __html: html }}
/>
))
}
To build the nodes from manually supplied data instead:
import { bdSchemas } from '@businessdash/sdk'
const locationNodes = bdSchemas.localBusinessLocations({
siteUrl: 'https://example.com',
locations: locations.map((location) => ({
slug: location.slug,
isPublic: location.isPublic,
name: location.name,
businessType: location.businessType ?? undefined,
telephone: location.phone ?? undefined,
address: {
streetAddress: location.address.addressLine1 ?? undefined,
addressLocality: location.address.city ?? undefined,
addressRegion: location.address.state ?? undefined,
postalCode: location.address.zip ?? undefined,
addressCountry: location.address.country ?? 'US',
},
})),
})
Available builders also include organization(), website(), service(),
faq(), breadcrumb(), article(), review(), and productOffer().
Social profiles
The profile's socials value can drive a custom list or the SDK React
component:
import { resolveSocialProfiles } from '@businessdash/sdk'
const profiles = resolveSocialProfiles(profile?.socials)
// [{ key: 'meta', label: 'Facebook', iconSlug: 'facebook', url: '…' }]
import { SocialLinks } from '@businessdash/sdk/react'
<SocialLinks socials={profile?.socials} />
Social profiles are configured in Settings → Company Profile. Business locations are configured in the adjacent Business locations section.