Add a “Get design Thumbnail image” Button to Beefree SDK
Learn how to enable end users to export their designs as an Image by adding a simple button to your UI.
Why Export a Thumbnail Image?
Beyond HTML and plain text, a thumbnail image is super handy: you can show a visual preview in your app’s gallery, share it in approvals workflows, or attach it to tickets and briefs. In this recipe, you’ll add a button that end users click to generate a PNG thumbnail of the current design. It works by:
Converting the design's JSON to HTML as a first step. This is important, because the /image endpoint requires three fields in the
POSTrequest and HTML is one of them.Completing the remaining two fields
field_typeandsize, and sending the POST request.Returning a PNG end users can preview and download in their UI.
Project Map: Where to Look in the Sample Project
This recipe is based on the working example in this GitHub repository: beefree-sdk-csapi-simple-integration. Clone it and explore these files:
Node proxy server
How to keep secrets on the server, perform LoginV2 auth, and forward export requests (including /v1/message/image) to the CS API.
Dev proxy setup
How to proxy /proxy and /v1 calls from the browser to your Node server (no CORS headaches).
Editor wrapper
How to initialize the SDK, enable trackChanges, and keep live JSON in React state.
Main app logic
How to wire the “Get design Thumbnail image” button, call /v1/message/image, and show results.
src/App.tsx
Result display
A simple pattern to preview the PNG and provide a Download link.
Data Flow Diagram
+----------------+ +----------------+ +---------------------+
| | JSON | | HTML | |
| Beefree SDK | → | Node Proxy | → | Content Services |
| (Frontend) | | (proxy-server) | | API (/image) |
| | | | | |
+----------------+ +----------------+ +---------------------+
| | |
| | v
| | PNG image (binary)
| | |
v v |
+-------------------------------------------------------------+
| Frontend UI (React App) |
| "Get design Thumbnail image" → preview + Download link |
+-------------------------------------------------------------+Why this flow? Secrets (Client Secret, Client ID, and Content Services API token) stay server-side, and the frontend focuses on UI and displaying the image.
Prerequisites
Node.js 20+
Beefree SDK credentials:
BEE_CLIENT_ID,BEE_CLIENT_SECRETContent Services API token (server-side only)
Create .env (see the repository’s example in the README.md file):
BEE_CLIENT_ID=your-client-id
BEE_CLIENT_SECRET=your-client-secret
CS_API_TOKEN=your-csapi-token-or-"Bearer ..."
PORT=3001Step 1: Clone the Project
git clone https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration.git
cd beefree-sdk-csapi-simple-integration
npm installStep 2: Proxy Server (LoginV2 + Image Forwarder)
Reference: proxy-server.js
Performs LoginV2 on the server (see the LoginV2 docs).
Forwards the required design HTML to the Content Services API
/imageendpointReturns binary data to the browser with proper headers.
Example code snippet
// proxy-server.js
// POST /v1/message/image → forwards to CS API /image and returns PNG bytes
app.post('/v1/message/image', async (req, res) => {
// req.body must include: { html, file_type: 'png' | 'jpg', size: '600'|'1000'... }
const response = await axios.post('https://api.getbee.io/v1/message/image', req.body, {
headers: { Authorization: `Bearer ${process.env.CS_API_TOKEN}` },
responseType: 'arraybuffer', // critical: get binary data
});
res.setHeader('Content-Type', 'image/png'); // inform browser it’s a PNG
res.setHeader('Content-Disposition', 'inline');
res.status(200).send(response.data);
});Step 3: Vite Dev Proxy (Frontend → Proxy)
Reference: vite.config.ts
// vite.config.ts (excerpt)
server: {
proxy: {
'/v1': { target: 'http://localhost:3001', changeOrigin: true },
'/proxy': { target: 'http://localhost:3001', changeOrigin: true },
},
},Step 4: Initialize Beefree SDK and Track JSON
Reference: src/BeefreeEditor.tsx
// BeefreeEditor.tsx (excerpt)
const beeConfig = {
container: 'beefree-editor',
trackChanges: true,
onChange(json: unknown) {
onChangeJson(json); // keep React state in sync with the builder
},
};Step 5: Add the “Get design Thumbnail image” Button
Reference: src/App.tsx
The Image endpoint requires HTML. Follow the same UX pattern as the repo:
First, generate HTML (for example, through your Get design HTML button that calls
/v1/message/html) and cache it.Then, when the user clicks Get design Thumbnail image, send that cached HTML to
/v1/message/image.
Core UI logic (guard + request + blob preview):
// App.tsx
const lastHtmlRef = useRef<string | undefined>(undefined);
// somewhere after HTML export completes:
/// lastHtmlRef.current = html; // cache HTML for image export
async function onGetImage() {
if (!lastHtmlRef.current) {
alert('Convert template to HTML first'); // guard (same UX as repo)
return;
}
const res = await fetch('/v1/message/image', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
file_type: 'png', // or 'jpg'
size: '1000', // longer side in pixels (e.g., 600, 1000)
html: lastHtmlRef.current,
}),
});
if (!res.ok) return alert('Failed to create image');
const blob = await res.blob();
setImageUrl(URL.createObjectURL(blob)); // displayable preview URL
}Step 6: Display the Image + Download Link
Reference: inline in src/App.tsx or a small component
function ImageResult({ imageUrl }: { imageUrl?: string }) {
if (!imageUrl) return <div>Export results will appear here.</div>;
return (
<div>
<a href={imageUrl} download="design.png">Download image</a>
<div style={{ marginTop: 8 }}>
<img src={imageUrl} alt="Exported Thumbnail" style={{ maxWidth: '100%', height: 'auto' }} />
</div>
</div>
);
}Running the Sample
From the project root:
npm run dev:proxy # start the Node proxy (LoginV2 + CS API forwarding)
npm run dev # start the React appOpen http://localhost:3000 → design something → click Get design HTML → then click Get design Thumbnail image.
Troubleshooting
“Convert template to HTML first” The Image endpoint requires HTML. Export HTML first (or compute it on demand).
401/403 from CS API Check
CS_API_TOKEN. Ensure it’s correctly set and includes theBearerprefix (the repo normalizes this pattern).Unexpected size/quality Adjust
sizeandfile_typein your request body per the API options.
Learn More
Working example: beefree-sdk-csapi-simple-integration
API docs (Export → Image): https://docs.beefree.io/beefree-sdk/apis/content-services-api/export#image
Key Takeaway
API docs tell you what the /image endpoint does.
This recipe shows you how it’s implemented end-to-end as a button in a real app:
Secure proxy (
proxy-server.js) with LoginV2 server-sideFrontend dev proxy (
vite.config.ts)Live JSON tracking (
BeefreeEditor.tsx)“Get design Thumbnail image” button (
App.tsx)
Clone the project, explore the files, and bring these core concepts into your own host application so your users can generate thumbnails with a single click.
Last updated
Was this helpful?

