API response examples
Component (fixed block)
{
"seo": {
"meta_title": "Getting Started with ButterCMS",
"meta_description": "Learn how to integrate ButterCMS into your application",
"og_image": "https://cdn.buttercms.com/og-image.jpg",
"canonical_url": "https://example.com/getting-started"
}
}
Component Picker (dynamic sections)
{
"body_sections": [
{
"type": "hero",
"fields": {
"headline": "Build Faster with ButterCMS",
"subheadline": "The headless CMS developers love",
"background_image": "https://cdn.buttercms.com/hero-bg.jpg",
"cta_text": "Get Started",
"cta_link": "/signup"
}
},
{
"type": "features",
"fields": {
"section_title": "Why Choose Us",
"features": [
{ "icon": "⚡", "title": "Fast", "description": "Lightning quick" },
{ "icon": "🔧", "title": "Flexible", "description": "Works anywhere" }
]
}
},
{
"type": "testimonial",
"fields": {
"quote": "Best CMS decision we ever made!",
"author": "Jane Smith",
"company": "TechCorp"
}
},
{
"type": "cta",
"fields": {
"headline": "Ready to get started?",
"button_text": "Sign Up Free",
"button_link": "/signup"
}
}
]
}
Creating dynamic landing Pages
You can compose flexible page layouts and easily reorder them with ButterCMS’ Components. Instantly. As a marketer, you will have the freedom and flexibility you need to compose compelling, unique content experiences with Pages built using Components. Your team can define a library of reusable, custom Components that you can use to create limitless kinds of experiences.Working with Components in your application
- JavaScript/React
- Vue.js
- Next.js with TypeScript
const butter = require('buttercms')('your-api-key');
const response = await butter.page.retrieve('*', 'landing-page');
const page = response.data.data.fields;
// Component mapping for Component Picker
const componentMap = {
hero: HeroComponent,
features: FeaturesComponent,
testimonial: TestimonialComponent,
cta: CTAComponent,
content_block: ContentBlockComponent,
};
// Render dynamic sections
function DynamicPage({ sections }) {
return (
<main>
{sections.map((section, index) => {
const Component = componentMap[section.type];
if (!Component) {
console.warn(`Unknown component type: ${section.type}`);
return null;
}
return <Component key={index} {...section.fields} />;
})}
</main>
);
}
// Individual component
function HeroComponent({ headline, subheadline, background_image, cta_text, cta_link }) {
return (
<section
className="hero"
style={{ backgroundImage: `url(${background_image})` }}
>
<h1>{headline}</h1>
<p>{subheadline}</p>
<a href={cta_link} className="btn">{cta_text}</a>
</section>
);
}
function FeaturesComponent({ section_title, features }) {
return (
<section className="features">
<h2>{section_title}</h2>
<div className="features-grid">
{features.map((feature, i) => (
<div key={i} className="feature">
<img src={feature.icon} alt="" />
<h3>{feature.title}</h3>
<p>{feature.description}</p>
</div>
))}
</div>
</section>
);
}
<template>
<main>
<component
v-for="(section, index) in sections"
:key="index"
:is="getComponent(section.type)"
v-bind="section.fields"
/>
</main>
</template>
<script setup>
import HeroSection from './HeroSection.vue';
import FeaturesSection from './FeaturesSection.vue';
import TestimonialSection from './TestimonialSection.vue';
import CTASection from './CTASection.vue';
const props = defineProps({
sections: Array
});
const componentMap = {
hero: HeroSection,
features: FeaturesSection,
testimonial: TestimonialSection,
cta: CTASection,
};
const getComponent = (type) => componentMap[type] || null;
</script>
// types.ts
interface ComponentSection {
type: string;
fields: Record<string, any>;
}
interface HeroFields {
headline: string;
subheadline: string;
background_image: string;
cta_text: string;
cta_link: string;
}
// ComponentRenderer.tsx
import dynamic from 'next/dynamic';
const componentMap: Record<string, React.ComponentType<any>> = {
hero: dynamic(() => import('./components/Hero')),
features: dynamic(() => import('./components/Features')),
testimonial: dynamic(() => import('./components/Testimonial')),
cta: dynamic(() => import('./components/CTA')),
};
export function ComponentRenderer({ sections }: { sections: ComponentSection[] }) {
return (
<>
{sections.map((section, index) => {
const Component = componentMap[section.type];
if (!Component) return null;
return <Component key={index} {...section.fields} />;
})}
</>
);
}