Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Guidelines and best practices for building applications with [Beefree SDK](https://docs.beefree.io/beefree-sdk), including installation, authentication, configuration, customization, and template management
.claude/skills/amariahak-guidelines-and-best-practices-for-building-applications-with-beefree-sdk-https/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 146% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 38% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 157% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 304% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 510% | 0% |
Guidelines and best practices for building applications with Beefree SDK, including installation, authentication, configuration, customization, and template management
Synced from https://github.com/PatrickJS/awesome-cursorrules/tree/main/rules/beefreeSDK.mdc.
Guidelines and best practices for building applications with Beefree SDK, including installation, authentication, configuration, customization, and template management.
bash npm install @beefree.io/sdk # or yarn add @beefree.io/sdk
json { "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" } }
.env file in your project root with your Beefree credentials:env BEE_CLIENT_ID=your_client_id_here BEE_CLIENT_SECRET=your_client_secret_here
proxy-server.js) to handle authentication:javascript 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}); });
https://auth.getbee.io/loginV2typescript 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());
html <div id="beefree-sdk-container"></div>
css #beefree-sdk-container { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; height: 600px; width: 90%; margin: 20px auto; border: 1px solid #ddd; border-radius: 8px; }
typescript 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' }} /> );
container parameter in your configuration:typescript const beeConfig = { container: 'beefree-sdk-container', // Required language: 'en-US' };
typescript 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]", }, ] };
typescript 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 } };
typescript 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); } }
typescript 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(); }, ]);
start() method with template data to load existing templates:typescript // 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'); }
typescript // 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');
typescript onAutoSave: function (jsonFile) { console.log("Auto-saving template..."); localStorage.setItem("email.autosave", jsonFile); }
https://api.getbee.io/v1/conversion/html-to-jsonjavascript 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();
typescript const importedTemplate = await importHtmlTemplate(htmlContent); beefreeSDK.start(importedTemplate);
onError callback to handle SDK errors:typescript onError: function (errorMessage) { console.error("Beefree SDK error:", errorMessage); // Display user-friendly error message document.getElementById('beefree-sdk-container').innerHTML = '<div class="error">Error loading Beefree SDK: ' + errorMessage.message + '</div>'; }
typescript 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>'; }); }
onChange callback to track template changes:typescript onChange: function (jsonFile, response) { console.log('json', jsonFile); console.log('response', response); },
Customize the Beefree SDK appearance with:
typescript const beeConfig = { container: 'beefree-sdk-container', language: 'en-US', // or 'es-ES', 'fr-FR', etc. };
typescript 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]/" } ] };
Reference the official Beefree SDK technical documentation for a comprehnsive reference of possible customizations.
Reference the full project at beefree-react-demo.
typescriptimport { 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' }} /> ); }
Reference the complete project at Beefree SDK multiple-versions-concept.
html<!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> <!-- Bundle the official @beefree.io/sdk package and expose BeefreeSDK from your app entrypoint. --> <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({ uid: beeConfig.uid }) }) .then(response => response.json()) .then(data => callback(data)) .catch(error => { console.error('Error getting Beefree token:', error); }); } function initializeBeefree(authResponse) { const bee = new BeefreeSDK(authResponse); bee.start(beeConfig, {}); } getBeeToken(initializeBeefree); </script> </body> </html>
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-08 | pass→pass | 5,248 | 1,824 | -65% | 1 | 1 | 0% | 867 | 4,936 | +469% | 0 | 0 | — |
case-01 | fail→pass | 11,577 | 7,324 | -37% | 1 | 1 | 0% | 2,550 | 6,263 | +146% | 0 | 0 | — |
case-02 | fail→pass | 23,996 | 11,544 | -52% | 1 | 1 | 0% | 5,239 | 7,207 | +38% | 0 | 0 | — |
case-03 | fail→pass | 14,052 | 11,711 | -17% | 1 | 1 | 0% | 2,748 | 7,050 | +157% | 0 | 0 | — |
case-04 | fail→pass | 6,586 | 2,605 | -60% | 1 | 1 | 0% | 1,258 | 5,081 | +304% | 0 | 0 | — |
case-05 | pass→pass | 11,196 | 3,940 | -65% | 1 | 1 | 0% | 2,032 | 5,378 | +165% | 0 | 0 | — |
case-06 | pass→pass | 10,877 | 1,700 | -84% | 1 | 1 | 0% | 1,932 | 4,806 | +149% | 0 | 0 | — |
case-07 | fail→pass | 4,494 | 1,792 | -60% | 1 | 1 | 0% | 796 | 4,855 | +510% | 0 | 0 | — |
case-09 | pass→pass | 8,620 | 4,773 | -45% | 1 | 1 | 0% | 1,511 | 5,424 | +259% | 0 | 0 | — |
case-10 | pass→pass | 5,484 | 2,374 | -57% | 1 | 1 | 0% | 875 | 4,898 | +460% | 0 | 0 | — |
case-11 | pass→pass | 6,829 | 1,207 | -82% | 1 | 1 | 0% | 1,088 | 4,731 | +335% | 0 | 0 | — |
case-12 | pass→pass | 4,501 | 2,241 | -50% | 1 | 1 | 0% | 688 | 4,931 | +617% | 0 | 0 | — |
case-13 | pass→pass | 10,627 | 4,357 | -59% | 1 | 1 | 0% | 1,788 | 5,369 | +200% | 0 | 0 | — |
case-14 | pass→pass | 8,844 | 8,560 | -3% | 1 | 1 | 0% | 1,500 | 6,133 | +309% | 0 | 0 | — |
case-15 | pass→pass | 11,461 | 5,690 | -50% | 1 | 1 | 0% | 2,067 | 5,667 | +174% | 0 | 0 | — |
case-16 | pass→pass | 3,037 | 1,830 | -40% | 1 | 1 | 0% | 542 | 4,838 | +793% | 0 | 0 | — |
case-17 | pass→pass | 8,572 | 3,313 | -61% | 1 | 1 | 0% | 1,609 | 5,189 | +222% | 0 | 0 | — |
case-18 | fail→fail | 7,685 | 1,453 | -81% | 1 | 1 | 0% | 1,253 | 4,808 | +284% | 0 | 0 | — |
case-19 | pass→pass | 12,459 | 2,467 | -80% | 1 | 1 | 0% | 1,372 | 5,032 | +267% | 0 | 0 | — |
case-20 | pass→pass | 15,983 | 7,069 | -56% | 1 | 1 | 0% | 2,323 | 5,984 | +158% | 0 | 0 | — |
case-21 | pass→fail | 24,191 | 8,219 | -66% | 1 | 1 | 0% | 2,710 | 6,157 | +127% | 0 | 0 | — |
case-22 | pass→pass | 10,453 | 8,456 | -19% | 1 | 1 | 0% | 2,096 | 6,203 | +196% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +18 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.