# Add a “Get design Thumbnail image” Button to Beefree SDK

## 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:

1. Converting the design's JSON to HTML as a first step. This is important, because the [/image endpoint](https://docs.beefree.io/beefree-sdk/apis/content-services-api/export#image) requires three fields in the `POST` request and HTML is one of them.
2. Completing the remaining two fields `field_type` and `size`, and sending the POST request.
3. 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**](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration). Clone it and explore these files:

| File                                                                                                                          | Purpose           | What You’ll Learn                                                                                                                     |
| ----------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| [`proxy-server.js`](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration/blob/main/proxy-server.js)             | 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. |
| [`vite.config.ts`](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration/blob/main/vite.config.ts)               | Dev proxy setup   | How to proxy `/proxy` and `/v1` calls from the browser to your Node server (no CORS headaches).                                       |
| [`src/BeefreeEditor.tsx`](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration/blob/main/src/BeefreeEditor.tsx) | Editor wrapper    | How to initialize the SDK, enable `trackChanges`, and keep live JSON in React state.                                                  |
| [`src/App.tsx`](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration/blob/main/src/App.tsx)                     | 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.                                                                  |

{% hint style="info" %}
Tip: The repo also demonstrates **HTML export**. Since the Image endpoint needs **HTML** input, you’ll either (a) click your **Get design HTML** button first, cache that HTML, then click **Get design Thumbnail image**, or (b) compute HTML on demand inside your image handler.
{% endhint %}

### 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](https://docs.beefree.io/beefree-sdk/getting-started/readme/create-an-application), [Client ID](https://docs.beefree.io/beefree-sdk/getting-started/readme/create-an-application), and [Content Services API token](https://docs.beefree.io/beefree-sdk/apis/content-services-api/authentication)) stay server-side, and the frontend focuses on UI and [displaying the image](https://docs.beefree.io/beefree-sdk/apis/content-services-api/export#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](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration) file):

```bash
BEE_CLIENT_ID=your-client-id
BEE_CLIENT_SECRET=your-client-secret
CS_API_TOKEN=your-csapi-token-or-"Bearer ..."
PORT=3001
```

{% hint style="info" %}
**Important:** `.env` must be in `.gitignore` so you don’t commit secrets.
{% endhint %}

### Step 1: Clone the Project

```bash
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`](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration/blob/main/proxy-server.js)

* Performs **LoginV2** on the server (see the [LoginV2 docs](https://docs.beefree.io/beefree-sdk/getting-started/readme/installation/authorization-process-in-detail)).
* Forwards the required design HTML to the [Content Services API `/image` endpoint](https://docs.beefree.io/beefree-sdk/apis/content-services-api/export#image)
* Returns **binary** data to the browser with proper headers.

**Example code snippet**

```js
// 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);
});
```

{% hint style="info" %}
**Note:** Keep secrets on the server—never expose your Client Secret or Content Services API key to the browser.
{% endhint %}

### Step 3: Vite Dev Proxy (Frontend → Proxy)

**Reference:** [`vite.config.ts`](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration/blob/main/vite.config.ts)

```ts
// vite.config.ts (excerpt)
server: {
  proxy: {
    '/v1': { target: 'http://localhost:3001', changeOrigin: true },
    '/proxy': { target: 'http://localhost:3001', changeOrigin: true },
  },
},
```

{% hint style="info" %}
**Note:** This allows you to use `fetch('/v1/...')` in the sample project without running into CORS issues.
{% endhint %}

### Step 4: Initialize Beefree SDK and Track JSON

**Reference:** [`src/BeefreeEditor.tsx`](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration/blob/main/src/BeefreeEditor.tsx)

```tsx
// BeefreeEditor.tsx (excerpt)
const beeConfig = {
  container: 'beefree-editor',
  trackChanges: true,
  onChange(json: unknown) {
    onChangeJson(json); // keep React state in sync with the builder
  },
};
```

{% hint style="info" %}
You’ll use this JSON to produce **HTML** (for image export) and for any other export flows.
{% endhint %}

### Step 5: Add the “Get design Thumbnail image” Button

**Reference:** [`src/App.tsx`](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration/blob/main/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):**

```tsx
// 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
}
```

{% hint style="info" %}
**Note:** Prefer a two-step UX (HTML first → image), but you can also compute HTML on demand inside `onGetImage` by calling your `/v1/message/html` endpoint first.
{% endhint %}

### Step 6: Display the Image + Download Link

**Reference:** inline in [`src/App.tsx`](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration/blob/main/src/App.tsx) or a small component

```tsx
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>
  );
}
```

{% hint style="info" %}
**Note:** Users can preview the thumbnail and click **Download** to save the PNG.
{% endhint %}

### Running the Sample

From the project root:

```bash
npm run dev:proxy   # start the Node proxy (LoginV2 + CS API forwarding)
npm run dev         # start the React app
```

Open [**http://localhost:3000**](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 the `Bearer` prefix (the repo normalizes this pattern).
* **Unexpected size/quality**\
  Adjust `size` and `file_type` in your request body per the API options.

### Learn More

* Working example: [**beefree-sdk-csapi-simple-integration**](https://github.com/BeefreeSDK/beefree-sdk-csapi-simple-integration)
* API docs (**Export → Image**): [**https://docs.beefree.io/beefree-sdk/apis/content-services-api/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-side
* **Frontend 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.beefree.io/beefree-sdk/resources/cookbook/add-a-get-design-thumbnail-image-button-to-beefree-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
