Implementation Patterns
Structured Data & Custom Code
Brease provides two components for injecting page-level metadata into your rendered output: BreaseStructuredData for JSON-LD structured data and BreaseCustomCode for arbitrary scripts and HTML. This page covers both components plus site-level custom code.
BreaseStructuredData
Renders JSON-LD <script> tags from the structured data configured on a page in the CMS.
Usage
import { BreaseStructuredData } from 'brease-next'
export default async function Page({ params }) {
const { slug } = await params
const slugStr = (slug ?? []).join('/')
const page = ensureSuccess(await getPage(slugStr))
return (
<>
<BreaseStructuredData page={page} />
<BreasePage page={page} sectionMap={componentMap} />
</>
)
}
How it works
- Reads
page.structuredData, which is an array of structured data objects defined in the CMS - Renders each object as a
<script type="application/ld+json">tag - Returns
nullifpage.structuredDataisnull,undefined, or an empty array
Example output
If the CMS has a page with an Organization schema configured, the component renders:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Acme Corp",
"url": "https://acme.com"
}
</script>
Setting up structured data in the CMS
- Open a page in the Brease editor
- Navigate to the page's SEO settings
- Add structured data entries using the JSON-LD editor
- Choose from common schemas (Organization, Article, Product, FAQ, etc.) or write custom JSON-LD
Validate your structured data
Use Google's Rich Results Test to verify your JSON-LD output. Errors in structured data will not break rendering but will prevent rich results in search engines.
BreaseCustomCode
Renders page-level custom code defined in the CMS. This is typically used for analytics snippets, tracking pixels, chat widgets, or inline HTML/CSS that applies to a specific page.
Usage
import { BreaseCustomCode } from 'brease-next'
export default async function Page({ params }) {
const { slug } = await params
const slugStr = (slug ?? []).join('/')
const page = ensureSuccess(await getPage(slugStr))
return (
<>
<BreaseStructuredData page={page} />
<BreasePage page={page} sectionMap={componentMap} />
<BreaseCustomCode page={page} />
</>
)
}
How it works
- Reads
page.customCode, which contains raw HTML/script content defined in the CMS - Renders the content using
dangerouslySetInnerHTML - Returns
nullifpage.customCodeisnull,undefined, or empty
Common use cases
- Page-specific analytics events
- Embedded widgets (calendars, booking forms)
- Conversion tracking pixels
- Custom CSS overrides for a single page
Full Page Component Example
Here is a complete page component with both structured data and custom code:
// src/app/[[...slug]]/page.tsx
import { notFound } from 'next/navigation'
import {
BreasePage,
BreaseStructuredData,
BreaseCustomCode,
generateBreasePageParams,
generateBreasePageMetadata,
ensureSuccess,
} from 'brease-next'
import { componentMap } from '@/lib/brease/config'
import { getPage } from '@/lib/brease/get-page'
export async function generateStaticParams() {
return generateBreasePageParams()
}
export async function generateMetadata({
params,
}: {
params: Promise<{ slug?: string[] }>
}) {
const { slug } = await params
const slugStr = (slug ?? []).join('/')
const result = await getPage(slugStr)
if (!result.success) return {}
return generateBreasePageMetadata(result.data, {
metadataBase: 'https://example.com',
})
}
export default async function Page({
params,
}: {
params: Promise<{ slug?: string[] }>
}) {
const { slug } = await params
const slugStr = (slug ?? []).join('/')
const result = await getPage(slugStr)
if (!result.success) {
notFound()
}
const page = ensureSuccess(result)
return (
<>
<BreaseStructuredData page={page} />
<BreasePage page={page} sectionMap={componentMap} />
<BreaseCustomCode page={page} />
</>
)
}
Component Placement Summary
| Component | Data source | Where to place |
|---|---|---|
BreaseStructuredData | page.structuredData | Before or after BreasePage in the page component |
BreaseCustomCode | page.customCode | After BreasePage in the page component |
Both BreaseStructuredData and BreaseCustomCode are safe to include unconditionally. They render nothing when their data is empty.
Next Steps
- Deployment — production checklist including SEO verification
- Pages & Dynamic Routes — the page component that hosts these components
- Media & Images — Open Graph images in metadata