Beefreesdk Skill
Beefree SDK Guidelines
Guidelines and best practices for building applications with Beefree SDK, including installation, authentication, configuration, customization, and template management.
Installation Guidelines
Package Installation
Dependencies
- Beefree SDK requires the following core dependencies:
{
"dependencies": {
"@beefree.io/sdk": "^9.0.2-fix-optional-url-config.0",
"axios": "^1.10.0",
"express": "^5.1.0",
"cors": "^2.8.5",
"dotenv": "^17.2.0"
}
}
Environment Setup
Authentication Guidelines
Proxy Server Setup
ALWAYS use a proxy server for authentication to protect your credentials
Create a proxy server file (e.g., proxy-server.js) to handle authentication:
import express from 'express';
import cors from 'cors';
import axios from 'axios';
import dotenv from 'dotenv';
dotenv.config();
const app = express();
const PORT = 3001;
app.use(cors());
app.use(express.json());
const BEE_CLIENT_ID = process.env.BEE_CLIENT_ID;
const BEE_CLIENT_SECRET = process.env.BEE_CLIENT_SECRET;
// V2 Auth Endpoint
app.post('/proxy/bee-auth', async (req, res) => {
try {
const { uid } = req.body;
const response = await axios.post(
'https://auth.getbee.io/loginV2',
{
client_id: BEE_CLIENT_ID,
client_secret: BEE_CLIENT_SECRET,
uid: uid || 'demo-user',
},
{ headers: { 'Content-Type': 'application/json' } }
);
res.json(response.data);
} catch (error) {
console.error('Auth error:', error.message);
res.status(500).json({ error: 'Failed to authenticate' });
}
});
app.listen(PORT, () => {
console.log(`Proxy server running on http://localhost:${PORT}`);
});
Authentication Process
- Use the V2 authentication endpoint:
https://auth.getbee.io/loginV2
- Pass the ENTIRE API response to the Beefree SDK, not just the token
- Example authentication call:
const token = await fetch('http://localhost:3001/proxy/bee-auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ uid: 'demo-user' }),
}).then(res => res.json());
Container Setup Guidelines
HTML Container
CSS Styling
React Container
For React applications, the following code snippet shows an example using refs to manage the container:
const containerRef = useRef<HTMLDivElement>(null);
return (
<div
id="beefree-react-demo"
ref={containerRef}
style={{
height: '600px',
width: '90%',
margin: '20px auto',
border: '1px solid #ddd',
borderRadius: '8px'
}}
/>
);
Configuration Guidelines
Required Configuration Parameters
Optional Configuration Parameters
- Customize your SDK with optional parameters:
const beeConfig = {
container: 'beefree-sdk-container', // Required
language: 'en-US',
specialLinks: [
{
type: 'unsubscribe',
label: 'Unsubscribe',
link: 'http://[unsubscribe]/',
},
{
type: 'subscribe',
label: 'Subscribe',
link: 'http://[subscribe]/',
},
],
mergeTags: [
{
name: 'First Name',
value: '[first_name]',
},
{
name: 'Last Name',
value: '[last_name]',
},
{
name: 'Email',
value: '[email]',
},
],
};
Callback Functions
- Implement essential callback functions for proper functionality:
const beeConfig = {
container: 'beefree-sdk-container',
onSave: function (jsonFile, htmlFile) {
console.log('Template saved:', jsonFile);
// Implement custom save logic here
},
onAutoSave: function (jsonFile) {
console.log('Auto-saving template...');
localStorage.setItem('email.autosave', jsonFile);
},
onSend: function (htmlFile) {
console.log('Email ready to send:', htmlFile);
// Implement custom send logic here
},
onError: function (errorMessage) {
console.error('Beefree SDK error:', errorMessage);
// Handle errors appropriately
},
};
SDK Initialization Guidelines
Basic Initialization
- Initialize the Beefree SDK with proper error handling:
async function initializeBeefree(authResponse) {
try {
const bee = new BeefreeSDK(authResponse);
bee.start(beeConfig, {});
console.log('Beefree SDK initialized successfully');
} catch (error) {
console.error('Failed to initialize Beefree SDK:', error);
}
}
React Integration
For React applications, the following code snippet shows an example using useEffect for initialization:
useEffect(() => {
async function initializeEditor() {
const beeConfig = {
container: 'beefree-react-demo',
language: 'en-US',
onSave: (
pageJson: string,
pageHtml: string,
ampHtml: string | null,
templateVersion: number,
language: string | null
) => {
console.log('Saved!', { pageJson, pageHtml, ampHtml, templateVersion, language });
},
onError: (error: unknown) => {
console.error('Error:', error);
},
};
const token = await fetch('http://localhost:3001/proxy/bee-auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ uid: 'demo-user' }),
}).then(res => res.json());
const bee = new BeefreeSDK(token);
bee.start(beeConfig, {});
}
initializeEditor();
}, []);
Template Loading Guidelines
Loading Templates
Use the start() method with template data to load existing templates:
// Load template from localStorage
const selectedTemplate = JSON.parse(localStorage.getItem('currentEmailData'));
if (selectedTemplate) {
beefreeSDKInstance.start(selectedTemplate);
console.log('Loaded template from localStorage');
} else {
// Start with empty template
beefreeSDKInstance.start();
console.log('Started with empty template');
}
Template Storage
Store templates in localStorage for persistence while testing:
// Save template data
localStorage.setItem('currentEmailData', JSON.stringify(templateData));
localStorage.setItem('currentEmailName', emailName);
// Load template data
const emailData = localStorage.getItem('currentEmailData');
const emailName = localStorage.getItem('currentEmailName');
Autosave Functionality
HTML Import Guidelines
HTML Importer API
- Use the HTML Importer API to convert existing HTML templates to Beefree SDK format
- API endpoint:
https://api.getbee.io/v1/conversion/html-to-json
- Reference: HTML Importer API Documentation
Import Process
- Convert HTML templates to Beefree SDK's native JSON format:
const response = await fetch('https://api.getbee.io/v1/conversion/html-to-json', {
method: 'POST',
headers: {
Authorization: 'Bearer Enter Dev Console API Key as Bearer token',
'Content-Type': 'text/html',
},
body: '<!DOCTYPE html><html><body><h1>Hello World</h1></body></html>',
});
const data = await response.json();
Loading Imported Templates
Error Handling Guidelines
onError Callback
Authentication Error Handling
- Handle authentication failures gracefully:
function getBeeToken(callback) {
fetch('/api/beefree/auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: 'your_client_id',
client_secret: 'your_client_secret',
uid: beeConfig.uid,
}),
})
.then(response => {
if (!response.ok) throw new Error('Auth failed: ' + response.status);
return response.json();
})
.then(data => {
callback(data);
})
.catch(error => {
console.error('Error getting Beefree token:', error);
document.getElementById('beefree-sdk-container').innerHTML =
'<div class="error">Failed to authenticate with Beefree. Please check your credentials and try again.</div>';
});
}
Template Change Tracking Guidelines
Track Message Changes
Change Detection
- Use the
onChange callback to track template changes:onChange: function (jsonFile, response) {
console.log('json', jsonFile);
console.log('response', response);
},
Customization Guidelines
UI Customization
Customize the Beefree SDK appearance with:
Language Customization
- Set the language for internationalization:
const beeConfig = {
container: 'beefree-sdk-container',
language: 'en-US', // or 'es-ES', 'fr-FR', etc.
};
Merge Tags and Special Links
- Configure merge tags and special links for email personalization:
const beeConfig = {
container: 'beefree-sdk-container',
mergeTags: [
{ name: 'First Name', value: '[first_name]' },
{ name: 'Last Name', value: '[last_name]' },
{ name: 'Email', value: '[email]' },
{ name: 'Company', value: '[company]' },
],
specialLinks: [
{ type: 'unsubscribe', label: 'Unsubscribe', link: 'http://[unsubscribe]/' },
{ type: 'subscribe', label: 'Subscribe', link: 'http://[subscribe]/' },
{ type: 'webview', label: 'View in Browser', link: 'http://[webview]/' },
],
};
Other Customizations
Reference the official Beefree SDK technical documentation for a comprehnsive reference of possible customizations.
Best Practices
Performance Optimization
- Initialize the Beefree SDK only when it is actually needed in your application.
- Properly clean up SDK resources when they are no longer required (e.g., when navigating away or closing the editor).
- Handle errors gracefully to prevent application crashes or unexpected behavior.
Security
- Never expose your Beefree SDK client credentials in any frontend or public code.
- Always use a secure backend or proxy server to handle authentication and sensitive operations.
- Validate and sanitize all user inputs before passing them to the SDK to prevent security vulnerabilities.
User Experience
- Show appropriate loading indicators while the SDK is initializing or performing operations.
- Display clear and helpful error messages to users if something goes wrong.
- Implement automatic saving or progress tracking to prevent data loss.
Code Organization
- Keep SDK configuration separate from initialization and business logic for better maintainability.
- Use strong typing (e.g., TypeScript or similar) where possible to improve code safety and clarity.
- Ensure robust error handling throughout your integration, regardless of the tech stack or framework used.
Examples
Complete React Component
Reference the full project at beefree-react-demo.
import { useEffect, useRef } from 'react';
import BeefreeSDK from '@beefree.io/sdk';
export default function BeefreeEditor() {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
async function initializeEditor() {
const beeConfig = {
container: 'beefree-react-demo',
language: 'en-US',
onSave: (pageJson: string, pageHtml: string, ampHtml: string | null, templateVersion: number, language: string | null) => {
console.log('Saved!', { pageJson, pageHtml, ampHtml, templateVersion, language });
},
onError: (error: unknown) => {
console.error('Error:', error);
}
};
const token = await fetch('http://localhost:3001/proxy/bee-auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ uid: 'demo-user' })
}).then(res => res.json());
const bee = new BeefreeSDK(token);
bee.start(beeConfig, {});
}
initializeEditor();
}, []);
return (
<div
id="beefree-react-demo"
ref={containerRef}
style={{
height: '600px',
width: '90%',
margin: '20px auto',
border: '1px solid #ddd',
borderRadius: '8px'
}}
/>
);
}
Complete HTML Implementation
Reference the complete project at Beefree SDK multiple-versions-concept.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Beefree SDK - Email Builder</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
#beefree-sdk-container {
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}
</style>
</head>
<body>
<div id="beefree-sdk-container"></div>
<script src="https://app-rsrc.getbee.io/plugin/BeefreeSDK.js"></script>
<script type="text/javascript">
const beeConfig = {
container: 'beefree-sdk-container',
uid: 'demo-user-' + Date.now(),
language: 'en-US',
onSave: function (jsonFile, htmlFile) {
console.log('Template saved:', jsonFile);
},
onError: function (errorMessage) {
console.error('Beefree SDK error:', errorMessage);
},
};
function getBeeToken(callback) {
fetch('/api/beefree/auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: 'your_client_id',
client_secret: 'your_client_secret',
uid: beeConfig.uid,
}),
})
.then(response => response.json())
.then(data => callback(data))
.catch(error => {
console.error('Error getting Beefree token:', error);
});
}
function initializeBeefree(authResponse) {
BeefreeSDK.create(authResponse, beeConfig, function (beefreeSDKInstance) {
console.log('Beefree SDK initialized successfully');
beefreeSDKInstance.start();
});
}
getBeeToken(initializeBeefree);
</script>
</body>
</html>
Memory Protocol (MANDATORY)
Before starting:
cat .claude/context/memory/learnings.md
After completing: Record any new patterns or exceptions discovered.
ASSUME INTERRUPTION: Your context may reset. If it's not in memory, it didn't happen.
1---2name: beefreesdk3description: Guidelines and best practices for building applications with [Beefree SDK](https://docs.beefree.io/beefree-sdk), including installation, authentication, configuration, customization, and template mana4---5
6# Beefreesdk Skill
7
8<identity>
9You are a coding standards expert specializing in beefreesdk.
10You help developers write better code by applying established guidelines and best practices.
11</identity>
12
13<capabilities>
14- Review code for guideline compliance
15- Suggest improvements based on best practices
16- Explain why certain patterns are preferred
17- Help refactor code to meet standards
18</capabilities>
19
20<instructions>
21When reviewing or writing code, apply these guidelines:
22
23# Beefree SDK Guidelines
24
25Guidelines and best practices for building applications with [Beefree SDK](https://docs.beefree.io/beefree-sdk), including installation, authentication, configuration, customization, and template management.
26
27## Installation Guidelines
28
29### Package Installation
30
31- Install the Beefree SDK package using npm or yarn:
32 ```bash
33 npm install @beefree.io/sdk
34 # or
35 yarn add @beefree.io/sdk
36 ```
37
38### Dependencies
39
40- Beefree SDK requires the following core dependencies:
41 ```json
42 {
43 "dependencies": {
44 "@beefree.io/sdk": "^9.0.2-fix-optional-url-config.0",
45 "axios": "^1.10.0",
46 "express": "^5.1.0",
47 "cors": "^2.8.5",
48 "dotenv": "^17.2.0"
49 }
50 }
51 ```
52
53### Environment Setup
54
55- Create a `.env` file in your project root with your Beefree credentials:
56 ```env
57 BEE_CLIENT_ID=your_client_id_here
58 BEE_CLIENT_SECRET=your_client_secret_here
59 ```
60
61## Authentication Guidelines
62
63### Proxy Server Setup
64
65- ALWAYS use a proxy server for authentication to protect your credentials
66- Create a proxy server file (e.g., `proxy-server.js`) to handle authentication:
67
68 ```javascript
69 import express from 'express';
70 import cors from 'cors';
71 import axios from 'axios';
72 import dotenv from 'dotenv';
73
74 dotenv.config();
75
76 const app = express();
77 const PORT = 3001;
78
79 app.use(cors());
80 app.use(express.json());
81
82 const BEE_CLIENT_ID = process.env.BEE_CLIENT_ID;
83 const BEE_CLIENT_SECRET = process.env.BEE_CLIENT_SECRET;
84
85 // V2 Auth Endpoint
86 app.post('/proxy/bee-auth', async (req, res) => {
87 try {
88 const { uid } = req.body;
89
90 const response = await axios.post(
91 'https://auth.getbee.io/loginV2',
92 {
93 client_id: BEE_CLIENT_ID,
94 client_secret: BEE_CLIENT_SECRET,
95 uid: uid || 'demo-user',
96 },
97 { headers: { 'Content-Type': 'application/json' } }
98 );
99
100 res.json(response.data);
101 } catch (error) {
102 console.error('Auth error:', error.message);
103 res.status(500).json({ error: 'Failed to authenticate' });
104 }
105 });
106
107 app.listen(PORT, () => {
108 console.log(`Proxy server running on http://localhost:${PORT}`);
109 });
110 ```
111
112### Authentication Process
113
114- Use the V2 authentication endpoint: `https://auth.getbee.io/loginV2`
115- Pass the ENTIRE API response to the Beefree SDK, not just the token
116- Example authentication call:
117 ```typescript
118 const token = await fetch('http://localhost:3001/proxy/bee-auth', {
119 method: 'POST',
120 headers: { 'Content-Type': 'application/json' },
121 body: JSON.stringify({ uid: 'demo-user' }),
122 }).then(res => res.json());
123 ```
124
125## Container Setup Guidelines
126
127### HTML Container
128
129- Create a dedicated container element for the Beefree SDK:
130 ```html
131 <div id="beefree-sdk-container"></div>
132 ```
133
134### CSS Styling
135
136- Style the container to ensure proper display:
137 ```css
138 #beefree-sdk-container {
139 position: absolute;
140 top: 0px;
141 bottom: 0px;
142 left: 0px;
143 right: 0px;
144 height: 600px;
145 width: 90%;
146 margin: 20px auto;
147 border: 1px solid #ddd;
148 border-radius: 8px;
149 }
150 ```
151
152### React Container
153
154- For React applications, the following code snippet shows an example using refs to manage the container:
155
156 ```typescript
157 const containerRef = useRef<HTMLDivElement>(null);
158
159 return (
160 <div
161 id="beefree-react-demo"
162 ref={containerRef}
163 style={{
164 height: '600px',
165 width: '90%',
166 margin: '20px auto',
167 border: '1px solid #ddd',
168 borderRadius: '8px'
169 }}
170 />
171 );
172 ```
173
174## Configuration Guidelines
175
176### Required Configuration Parameters
177
178- ALWAYS include the `container` parameter in your configuration:
179 ```typescript
180 const beeConfig = {
181 container: 'beefree-sdk-container', // Required
182 language: 'en-US',
183 };
184 ```
185
186### Optional Configuration Parameters
187
188- Customize your SDK with optional parameters:
189 ```typescript
190 const beeConfig = {
191 container: 'beefree-sdk-container', // Required
192 language: 'en-US',
193 specialLinks: [
194 {
195 type: 'unsubscribe',
196 label: 'Unsubscribe',
197 link: 'http://[unsubscribe]/',
198 },
199 {
200 type: 'subscribe',
201 label: 'Subscribe',
202 link: 'http://[subscribe]/',
203 },
204 ],
205 mergeTags: [
206 {
207 name: 'First Name',
208 value: '[first_name]',
209 },
210 {
211 name: 'Last Name',
212 value: '[last_name]',
213 },
214 {
215 name: 'Email',
216 value: '[email]',
217 },
218 ],
219 };
220 ```
221
222### Callback Functions
223
224- Implement essential callback functions for proper functionality:
225 ```typescript
226 const beeConfig = {
227 container: 'beefree-sdk-container',
228 onSave: function (jsonFile, htmlFile) {
229 console.log('Template saved:', jsonFile);
230 // Implement custom save logic here
231 },
232 onAutoSave: function (jsonFile) {
233 console.log('Auto-saving template...');
234 localStorage.setItem('email.autosave', jsonFile);
235 },
236 onSend: function (htmlFile) {
237 console.log('Email ready to send:', htmlFile);
238 // Implement custom send logic here
239 },
240 onError: function (errorMessage) {
241 console.error('Beefree SDK error:', errorMessage);
242 // Handle errors appropriately
243 },
244 };
245 ```
246
247## SDK Initialization Guidelines
248
249### Basic Initialization
250
251- Initialize the Beefree SDK with proper error handling:
252 ```typescript
253 async function initializeBeefree(authResponse) {
254 try {
255 const bee = new BeefreeSDK(authResponse);
256 bee.start(beeConfig, {});
257 console.log('Beefree SDK initialized successfully');
258 } catch (error) {
259 console.error('Failed to initialize Beefree SDK:', error);
260 }
261 }
262 ```
263
264### React Integration
265
266- For React applications, the following code snippet shows an example using useEffect for initialization:
267
268 ```typescript
269 useEffect(() => {
270 async function initializeEditor() {
271 const beeConfig = {
272 container: 'beefree-react-demo',
273 language: 'en-US',
274 onSave: (
275 pageJson: string,
276 pageHtml: string,
277 ampHtml: string | null,
278 templateVersion: number,
279 language: string | null
280 ) => {
281 console.log('Saved!', { pageJson, pageHtml, ampHtml, templateVersion, language });
282 },
283 onError: (error: unknown) => {
284 console.error('Error:', error);
285 },
286 };
287
288 const token = await fetch('http://localhost:3001/proxy/bee-auth', {
289 method: 'POST',
290 headers: { 'Content-Type': 'application/json' },
291 body: JSON.stringify({ uid: 'demo-user' }),
292 }).then(res => res.json());
293
294 const bee = new BeefreeSDK(token);
295 bee.start(beeConfig, {});
296 }
297
298 initializeEditor();
299 }, []);
300 ```
301
302## Template Loading Guidelines
303
304### Loading Templates
305
306- Use the `start()` method with template data to load existing templates:
307
308 ```typescript
309 // Load template from localStorage
310 const selectedTemplate = JSON.parse(localStorage.getItem('currentEmailData'));
311
312 if (selectedTemplate) {
313 beefreeSDKInstance.start(selectedTemplate);
314 console.log('Loaded template from localStorage');
315 } else {
316 // Start with empty template
317 beefreeSDKInstance.start();
318 console.log('Started with empty template');
319 }
320 ```
321
322### Template Storage
323
324- Store templates in localStorage for persistence while testing:
325
326 ```typescript
327 // Save template data
328 localStorage.setItem('currentEmailData', JSON.stringify(templateData));
329 localStorage.setItem('currentEmailName', emailName);
330
331 // Load template data
332 const emailData = localStorage.getItem('currentEmailData');
333 const emailName = localStorage.getItem('currentEmailName');
334 ```
335
336### Autosave Functionality
337
338- Implement autosave to prevent data loss:
339 ```typescript
340 onAutoSave: function (jsonFile) {
341 console.log("Auto-saving template...");
342 localStorage.setItem("email.autosave", jsonFile);
343 }
344 ```
345
346## HTML Import Guidelines
347
348### HTML Importer API
349
350- Use the HTML Importer API to convert existing HTML templates to Beefree SDK format
351- API endpoint: `https://api.getbee.io/v1/conversion/html-to-json`
352- Reference: [HTML Importer API Documentation](https://docs.beefree.io/beefree-sdk/apis/html-importer-api/import-html)
353
354### Import Process
355
356- Convert HTML templates to Beefree SDK's native JSON format:
357 ```javascript
358 const response = await fetch('https://api.getbee.io/v1/conversion/html-to-json', {
359 method: 'POST',
360 headers: {
361 Authorization: 'Bearer Enter Dev Console API Key as Bearer token',
362 'Content-Type': 'text/html',
363 },
364 body: '<!DOCTYPE html><html><body><h1>Hello World</h1></body></html>',
365 });
366 const data = await response.json();
367 ```
368
369### Loading Imported Templates
370
371- Load imported templates into the Beefree SDK:
372 ```typescript
373 const importedTemplate = await importHtmlTemplate(htmlContent);
374 beefreeSDK.start(importedTemplate);
375 ```
376
377## Error Handling Guidelines
378
379### onError Callback
380
381- ALWAYS implement the `onError` callback to handle SDK errors:
382 ```typescript
383 onError: function (errorMessage) {
384 console.error("Beefree SDK error:", errorMessage);
385 // Display user-friendly error message
386 document.getElementById('beefree-sdk-container').innerHTML =
387 '<div class="error">Error loading Beefree SDK: ' + errorMessage.message + '</div>';
388 }
389 ```
390
391### Authentication Error Handling
392
393- Handle authentication failures gracefully:
394 ```typescript
395 function getBeeToken(callback) {
396 fetch('/api/beefree/auth', {
397 method: 'POST',
398 headers: { 'Content-Type': 'application/json' },
399 body: JSON.stringify({
400 client_id: 'your_client_id',
401 client_secret: 'your_client_secret',
402 uid: beeConfig.uid,
403 }),
404 })
405 .then(response => {
406 if (!response.ok) throw new Error('Auth failed: ' + response.status);
407 return response.json();
408 })
409 .then(data => {
410 callback(data);
411 })
412 .catch(error => {
413 console.error('Error getting Beefree token:', error);
414 document.getElementById('beefree-sdk-container').innerHTML =
415 '<div class="error">Failed to authenticate with Beefree. Please check your credentials and try again.</div>';
416 });
417 }
418 ```
419
420## Template Change Tracking Guidelines
421
422### Track Message Changes
423
424- Implement template change tracking to monitor changes made by end users
425- Reference: [Track Message Changes Documentation](https://docs.beefree.io/beefree-sdk/getting-started/tracking-message-changes)
426
427### Change Detection
428
429- Use the `onChange` callback to track template changes:
430 ```typescript
431 onChange: function (jsonFile, response) {
432 console.log('json', jsonFile);
433 console.log('response', response);
434 },
435 ```
436
437## Customization Guidelines
438
439### UI Customization
440
441Customize the Beefree SDK appearance with:
442
443- [Customized Themes](https://docs.beefree.io/beefree-sdk/other-customizations/appearance/themes)
444- [Custom CSS](https://docs.beefree.io/beefree-sdk/other-customizations/appearance/custom-css)
445
446### Language Customization
447
448- Set the language for internationalization:
449 ```typescript
450 const beeConfig = {
451 container: 'beefree-sdk-container',
452 language: 'en-US', // or 'es-ES', 'fr-FR', etc.
453 };
454 ```
455
456### Merge Tags and Special Links
457
458- Configure merge tags and special links for email personalization:
459 ```typescript
460 const beeConfig = {
461 container: 'beefree-sdk-container',
462 mergeTags: [
463 { name: 'First Name', value: '[first_name]' },
464 { name: 'Last Name', value: '[last_name]' },
465 { name: 'Email', value: '[email]' },
466 { name: 'Company', value: '[company]' },
467 ],
468 specialLinks: [
469 { type: 'unsubscribe', label: 'Unsubscribe', link: 'http://[unsubscribe]/' },
470 { type: 'subscribe', label: 'Subscribe', link: 'http://[subscribe]/' },
471 { type: 'webview', label: 'View in Browser', link: 'http://[webview]/' },
472 ],
473 };
474 ```
475
476### Other Customizations
477
478Reference the official [Beefree SDK technical documentation](https://docs.beefree.io/beefree-sdk) for a comprehnsive reference of possible customizations.
479
480## Best Practices
481
482### Performance Optimization
483
484- Initialize the Beefree SDK only when it is actually needed in your application.
485- Properly clean up SDK resources when they are no longer required (e.g., when navigating away or closing the editor).
486- Handle errors gracefully to prevent application crashes or unexpected behavior.
487
488### Security
489
490- **Never** expose your Beefree SDK client credentials in any frontend or public code.
491- Always use a secure backend or proxy server to handle authentication and sensitive operations.
492- Validate and sanitize all user inputs before passing them to the SDK to prevent security vulnerabilities.
493
494### User Experience
495
496- Show appropriate loading indicators while the SDK is initializing or performing operations.
497- Display clear and helpful error messages to users if something goes wrong.
498- Implement automatic saving or progress tracking to prevent data loss.
499
500### Code Organization
501
502- Keep SDK configuration separate from initialization and business logic for better maintainability.
503- Use strong typing (e.g., TypeScript or similar) where possible to improve code safety and clarity.
504- Ensure robust error handling throughout your integration, regardless of the tech stack or framework used.
505
506## Examples
507
508### Complete React Component
509
510Reference the full project at [beefree-react-demo](https://github.com/BeefreeSDK/beefree-react-demo).
511
512```typescript
513import { useEffect, useRef } from 'react';
514import BeefreeSDK from '@beefree.io/sdk';
515
516export default function BeefreeEditor() {
517 const containerRef = useRef<HTMLDivElement>(null);
518
519 useEffect(() => {
520 async function initializeEditor() {
521 const beeConfig = {
522 container: 'beefree-react-demo',
523 language: 'en-US',
524 onSave: (pageJson: string, pageHtml: string, ampHtml: string | null, templateVersion: number, language: string | null) => {
525 console.log('Saved!', { pageJson, pageHtml, ampHtml, templateVersion, language });
526 },
527 onError: (error: unknown) => {
528 console.error('Error:', error);
529 }
530 };
531
532 const token = await fetch('http://localhost:3001/proxy/bee-auth', {
533 method: 'POST',
534 headers: { 'Content-Type': 'application/json' },
535 body: JSON.stringify({ uid: 'demo-user' })
536 }).then(res => res.json());
537
538 const bee = new BeefreeSDK(token);
539 bee.start(beeConfig, {});
540 }
541
542 initializeEditor();
543 }, []);
544
545 return (
546 <div
547 id="beefree-react-demo"
548 ref={containerRef}
549 style={{
550 height: '600px',
551 width: '90%',
552 margin: '20px auto',
553 border: '1px solid #ddd',
554 borderRadius: '8px'
555 }}
556 />
557 );
558}
559```
560
561### Complete HTML Implementation
562
563Reference the complete project at Beefree SDK [multiple-versions-concept](https://github.com/BeefreeSDK/beefree-sdk-simple-schema/tree/main/multiple-versions-concept).
564
565```html
566<!DOCTYPE html>
567<html lang="en">
568 <head>
569 <title>Beefree SDK - Email Builder</title>
570 <meta charset="utf-8" />
571 <meta name="viewport" content="width=device-width, initial-scale=1" />
572 <style type="text/css">
573 #beefree-sdk-container {
574 position: absolute;
575 top: 0px;
576 bottom: 0px;
577 left: 0px;
578 right: 0px;
579 }
580 </style>
581 </head>
582 <body>
583 <div id="beefree-sdk-container"></div>
584 <script src="https://app-rsrc.getbee.io/plugin/BeefreeSDK.js"></script>
585 <script type="text/javascript">
586 const beeConfig = {
587 container: 'beefree-sdk-container',
588 uid: 'demo-user-' + Date.now(),
589 language: 'en-US',
590 onSave: function (jsonFile, htmlFile) {
591 console.log('Template saved:', jsonFile);
592 },
593 onError: function (errorMessage) {
594 console.error('Beefree SDK error:', errorMessage);
595 },
596 };
597
598 function getBeeToken(callback) {
599 fetch('/api/beefree/auth', {
600 method: 'POST',
601 headers: { 'Content-Type': 'application/json' },
602 body: JSON.stringify({
603 client_id: 'your_client_id',
604 client_secret: 'your_client_secret',
605 uid: beeConfig.uid,
606 }),
607 })
608 .then(response => response.json())
609 .then(data => callback(data))
610 .catch(error => {
611 console.error('Error getting Beefree token:', error);
612 });
613 }
614
615 function initializeBeefree(authResponse) {
616 BeefreeSDK.create(authResponse, beeConfig, function (beefreeSDKInstance) {
617 console.log('Beefree SDK initialized successfully');
618 beefreeSDKInstance.start();
619 });
620 }
621
622 getBeeToken(initializeBeefree);
623 </script>
624 </body>
625</html>
626```
627
628</instructions>
629
630<examples>
631Example usage:
632```
633User: "Review this code for beefreesdk compliance"
634Agent: [Analyzes code against guidelines and provides specific feedback]
635```
636</examples>
637
638## Memory Protocol (MANDATORY)
639
640**Before starting:**
641
642```bash
643cat .claude/context/memory/learnings.md
644```
645
646**After completing:** Record any new patterns or exceptions discovered.
647
648> ASSUME INTERRUPTION: Your context may reset. If it's not in memory, it didn't happen.