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
POST
request and HTML is one of them.Completing the remaining two fields
field_type
andsize
, 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_SECRET
Content 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=3001
Step 1: Clone the Project
git clone https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration.git
cd beefree-sdk-csapi-simple-integration
npm install
Step 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
/image
endpointReturns 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 app
Open 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 theBearer
prefix (the repo normalizes this pattern).Unexpected size/quality Adjust
size
andfile_type
in 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?