{"_id":"@beefree.io/react-email-builder","_rev":"4-0fcd006750fa23fe4ba532e7537171ef","name":"@beefree.io/react-email-builder","dist-tags":{"latest":"1.0.4"},"versions":{"1.0.2":{"name":"@beefree.io/react-email-builder","version":"1.0.2","keywords":["react","beefree","beefree-sdk","email-builder","email-template","email-template-builder","email-design","email-editor","html-email","responsive-email","newsletter","page-builder","landing-page-builder","popup-builder","drag-and-drop","drag-drop-editor","wysiwyg","visual-editor","no-code","low-code","react-component","react-hooks","collaborative-editing","real-time-collaboration"],"author":{"url":"https://www.beefree.io","name":"Beefree","email":"dev@beefree.io"},"license":"Apache-2.0","_id":"@beefree.io/react-email-builder@1.0.2","maintainers":[{"name":"gaggero","email":"davide.gaggero@beefree.io"},{"name":"robmar","email":"rmarchet@gmail.com"},{"name":"pinkynrg","email":"biggyapple@gmail.com"},{"name":"davide.ponti","email":"davide.ponti@beefree.io"},{"name":"clarissabarbieri","email":"clarissa.barbieri@growens.io"},{"name":"mailupinc.2012","email":"dev@beefree.io"},{"name":"sferrario","email":"simone.ferrario@beefree.io"}],"homepage":"https://github.com/BeefreeSDK/npm-react#readme","bugs":{"url":"https://github.com/BeefreeSDK/npm-react/issues"},"dist":{"shasum":"2634431994f3ff87a80c928f1519205d6436764c","tarball":"https://registry.npmjs.org/@beefree.io/react-email-builder/-/react-email-builder-1.0.2.tgz","fileCount":6,"integrity":"sha512-EVhOUFLOctA+ZeLQBxNvr8rDMye1tuOLZUzKuoCA/E5aZjllccbW3bdHsQcLaXUMcFWY9sq4+tUKBGz1jXWj3Q==","signatures":[{"sig":"MEUCIQDwSMUoANaWTnlrwCG0ll7+Jr5NQH+GS2l8rE07NQHFEwIgLm1/nL8F5YD4vsopG0XVpSCv+wCYCpysTuB1uQQOcRI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":68838},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.es.js","engines":{"npm":">=9.0.0","node":">=18.0.0"},"gitHead":"47d1aabfc5d54a2dcbf8bdf973f6920e1a2cff5c","scripts":{"lint":"eslint ./src --ext ts","test":"yarn pretest && jest --watch","build":"rollup -c","clean":"rimraf dist","start":"rollup -c -w","prepare":"husky","pretest":"yarn prepare && yarn install","release":"standard-version","test:ci":"jest --runInBand --bail","prebuild":"yarn clean","prestart":"yarn clean","prerelease":"git pull && yarn prebuild && yarn test:ci && yarn build","postrelease":"git push --follow-tags --no-verify","release:beta":"yarn prerelease && standard-version --prerelease beta && yarn postrelease","release:alpha":"yarn prerelease && standard-version --prerelease alpha && yarn postrelease","release:unstable":"yarn prerelease && standard-version --prerelease $(git branch --show-current | sed 's/\\//-/g') && yarn postrelease"},"_npmUser":{"name":"mailupinc.2012","email":"dev@beefree.io"},"repository":{"url":"git+https://github.com/BeefreeSDK/npm-react.git","type":"git"},"_npmVersion":"10.9.4","description":"React components and hooks for the Beefree SDK — drag-and-drop email, page, and popup builder with collaborative editing","directories":{},"lint-staged":{"*.{ts,tsx}":"eslint"},"sideEffects":false,"_nodeVersion":"22.22.0","dependencies":{"@beefree.io/sdk":"11.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"yarn@4.5.3","devDependencies":{"jest":"^30.0.5","husky":"^9.1.7","react":"^19.1.1","dotenv":"^17.3.1","eslint":"^9.34.0","rimraf":"^6.0.1","rollup":"^4.47.1","globals":"^16.3.0","ts-jest":"^29.4.1","ts-node":"^10.9.2","react-dom":"^19.1.1","typescript":"^5.9.2","@babel/core":"^7.28.3","@types/jest":"^30.0.0","lint-staged":"^16.1.5","@types/react":"^19.1.12","@babel/runtime":"^7.28.3","@types/react-dom":"^19.2.3","standard-version":"^9.5.0","rollup-plugin-dts":"^6.2.3","@babel/preset-react":"^7.27.1","@rollup/plugin-json":"^6.1.0","eslint-plugin-react":"^7.37.5","rollup-plugin-serve":"^3.0.0","@rollup/plugin-babel":"^6.0.4","@testing-library/dom":"^10.4.1","eslint-plugin-import":"^2.32.0","@rollup/plugin-terser":"^0.4.4","@rollup/plugin-replace":"^6.0.2","@testing-library/react":"^16.3.0","jest-environment-jsdom":"^30.2.0","@rollup/plugin-commonjs":"^28.0.6","@babel/preset-typescript":"^7.27.1","@stylistic/eslint-plugin":"^5.2.3","rollup-plugin-livereload":"^2.0.5","@testing-library/jest-dom":"^6.9.1","@typescript-eslint/parser":"^8.41.0","eslint-plugin-react-hooks":"^5.2.0","@rollup/plugin-node-resolve":"^16.0.1","@babel/plugin-transform-runtime":"^7.28.3","@commitlint/config-conventional":"^20.0.0","@typescript-eslint/eslint-plugin":"^8.41.0"},"peerDependencies":{"react":">=17","react-dom":">=17"},"_npmOperationalInternal":{"tmp":"tmp/react-email-builder_1.0.2_1772035811177_0.7368041439903494","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@beefree.io/react-email-builder","version":"1.0.3","keywords":["react","beefree","beefree-sdk","email-builder","email-template","email-template-builder","email-design","email-editor","html-email","responsive-email","newsletter","page-builder","landing-page-builder","popup-builder","drag-and-drop","drag-drop-editor","wysiwyg","visual-editor","no-code","low-code","react-component","react-hooks","collaborative-editing","real-time-collaboration"],"author":{"url":"https://www.beefree.io","name":"Beefree","email":"dev@beefree.io"},"license":"Apache-2.0","_id":"@beefree.io/react-email-builder@1.0.3","maintainers":[{"name":"gaggero","email":"davide.gaggero@beefree.io"},{"name":"robmar","email":"rmarchet@gmail.com"},{"name":"pinkynrg","email":"biggyapple@gmail.com"},{"name":"davide.ponti","email":"davide.ponti@beefree.io"},{"name":"clarissabarbieri","email":"clarissa.barbieri@growens.io"},{"name":"mailupinc.2012","email":"dev@beefree.io"},{"name":"sferrario","email":"simone.ferrario@beefree.io"}],"homepage":"https://github.com/BeefreeSDK/npm-react#readme","bugs":{"url":"https://github.com/BeefreeSDK/npm-react/issues"},"dist":{"shasum":"eff35006874f4d91526d673f0cfb94d7c26e93e9","tarball":"https://registry.npmjs.org/@beefree.io/react-email-builder/-/react-email-builder-1.0.3.tgz","fileCount":6,"integrity":"sha512-RfZ9JMu4iaPxCa+LePM4e9s3ds9wsO201mtFdc6fah5cOQL55TIV6HkCJEEJ6pKxt8zOEwfl4k3Z84IxAyHVwA==","signatures":[{"sig":"MEUCIQCTkR8uTfTYRc9EMt6jUhBvWfi4rB1I/RaKmbyeqidtAwIgRPJS8pDVkkOsH82x33Lu7Ta54xgXmfEz4AsVjwL/4Qo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69180},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.es.js","engines":{"npm":">=9.0.0","node":">=18.0.0"},"gitHead":"c732e8c71abfb59c5da79aff852b3891c1138d9e","scripts":{"lint":"eslint ./src --ext ts","test":"yarn pretest && jest --watch","build":"rollup -c","clean":"rimraf dist","start":"rollup -c -w","prepare":"husky","pretest":"yarn prepare && yarn install","release":"standard-version","test:ci":"jest --runInBand --bail","prebuild":"yarn clean","prestart":"yarn clean","prerelease":"git pull && yarn prebuild && yarn test:ci && yarn build","postrelease":"git push --follow-tags --no-verify","release:beta":"yarn prerelease && standard-version --prerelease beta && yarn postrelease","release:alpha":"yarn prerelease && standard-version --prerelease alpha && yarn postrelease","release:unstable":"yarn prerelease && standard-version --prerelease $(git branch --show-current | sed 's/\\//-/g') && yarn postrelease"},"_npmUser":{"name":"mailupinc.2012","email":"dev@beefree.io"},"repository":{"url":"git+https://github.com/BeefreeSDK/npm-react.git","type":"git"},"_npmVersion":"10.9.4","description":"React components and hooks for the Beefree SDK — drag-and-drop email, page, and popup builder with collaborative editing","directories":{},"lint-staged":{"*.{ts,tsx}":"eslint"},"sideEffects":false,"_nodeVersion":"22.22.0","dependencies":{"@beefree.io/sdk":"11.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"yarn@4.5.3","devDependencies":{"jest":"^30.0.5","husky":"^9.1.7","react":"^19.1.1","dotenv":"^17.3.1","eslint":"^9.34.0","rimraf":"^6.0.1","rollup":"^4.47.1","globals":"^16.3.0","ts-jest":"^29.4.1","ts-node":"^10.9.2","react-dom":"^19.1.1","typescript":"^5.9.2","@babel/core":"^7.28.3","@types/jest":"^30.0.0","lint-staged":"^16.1.5","@types/react":"^19.1.12","@babel/runtime":"^7.28.3","@types/react-dom":"^19.2.3","standard-version":"^9.5.0","rollup-plugin-dts":"^6.2.3","@babel/preset-react":"^7.27.1","@rollup/plugin-json":"^6.1.0","eslint-plugin-react":"^7.37.5","rollup-plugin-serve":"^3.0.0","@rollup/plugin-babel":"^6.0.4","@testing-library/dom":"^10.4.1","eslint-plugin-import":"^2.32.0","@rollup/plugin-terser":"^0.4.4","@rollup/plugin-replace":"^6.0.2","@testing-library/react":"^16.3.0","jest-environment-jsdom":"^30.2.0","@rollup/plugin-commonjs":"^28.0.6","@babel/preset-typescript":"^7.27.1","@stylistic/eslint-plugin":"^5.2.3","rollup-plugin-livereload":"^2.0.5","@testing-library/jest-dom":"^6.9.1","@typescript-eslint/parser":"^8.41.0","eslint-plugin-react-hooks":"^5.2.0","@rollup/plugin-node-resolve":"^16.0.1","@babel/plugin-transform-runtime":"^7.28.3","@commitlint/config-conventional":"^20.0.0","@typescript-eslint/eslint-plugin":"^8.41.0"},"peerDependencies":{"react":">=17","react-dom":">=17"},"_npmOperationalInternal":{"tmp":"tmp/react-email-builder_1.0.3_1772113147662_0.533685456230979","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@beefree.io/react-email-builder","version":"1.0.4","description":"React components and hooks for the Beefree SDK — drag-and-drop email, page, and popup builder with collaborative editing","repository":{"type":"git","url":"git+https://github.com/BeefreeSDK/npm-react.git"},"bugs":{"url":"https://github.com/BeefreeSDK/npm-react/issues"},"homepage":"https://github.com/BeefreeSDK/npm-react#readme","author":{"name":"Beefree","email":"dev@beefree.io","url":"https://www.beefree.io"},"license":"Apache-2.0","main":"dist/index.js","module":"dist/index.es.js","types":"dist/index.d.ts","sideEffects":false,"keywords":["react","beefree","beefree-sdk","email-builder","email-template","email-template-builder","email-design","email-editor","html-email","responsive-email","newsletter","page-builder","landing-page-builder","popup-builder","drag-and-drop","drag-drop-editor","wysiwyg","visual-editor","no-code","low-code","react-component","react-hooks","collaborative-editing","real-time-collaboration"],"engines":{"node":">=18.0.0","npm":">=9.0.0"},"scripts":{"build":"rollup -c","start":"rollup -c -w","clean":"rimraf dist","prepare":"husky","prebuild":"yarn clean","prestart":"yarn clean","prerelease":"git pull && yarn prebuild && yarn test:ci && yarn build","lint":"eslint ./src --ext ts","test":"jest --watch","test:ci":"jest --runInBand --bail","coverage":"jest --runInBand --coverage","guard:main-branch":"test \"$(git rev-parse --abbrev-ref HEAD)\" = \"main\" || (echo 'Error: releases must be published from the main branch.' && exit 1)","release":"yarn guard:main-branch && yarn prerelease && standard-version && git push --follow-tags --no-verify","release:alpha":"yarn prerelease && standard-version --prerelease alpha && git push --follow-tags --no-verify","release:beta":"yarn prerelease && standard-version --prerelease beta && git push --follow-tags --no-verify","release:unstable":"yarn prerelease && standard-version --prerelease $(git branch --show-current | sed 's/\\//-/g') && git push --follow-tags --no-verify"},"lint-staged":{"*.{ts,tsx}":"eslint"},"dependencies":{"@beefree.io/sdk":"11.2.1"},"devDependencies":{"@babel/core":"^7.28.3","@babel/plugin-transform-runtime":"^7.28.3","@babel/preset-react":"^7.27.1","@babel/preset-typescript":"^7.27.1","@babel/runtime":"^7.28.3","@commitlint/config-conventional":"^20.0.0","@rollup/plugin-babel":"^6.0.4","@rollup/plugin-commonjs":"^28.0.6","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^16.0.1","@rollup/plugin-replace":"^6.0.2","@rollup/plugin-terser":"^0.4.4","@stylistic/eslint-plugin":"^5.2.3","@testing-library/dom":"^10.4.1","@testing-library/jest-dom":"^6.9.1","@testing-library/react":"^16.3.0","@types/jest":"^30.0.0","@types/react":"^19.1.12","@types/react-dom":"^19.2.3","@typescript-eslint/eslint-plugin":"^8.41.0","@typescript-eslint/parser":"^8.41.0","dotenv":"^17.3.1","eslint":"^9.34.0","eslint-plugin-import":"^2.32.0","eslint-plugin-react":"^7.37.5","eslint-plugin-react-hooks":"^5.2.0","globals":"^16.3.0","husky":"^9.1.7","jest":"^30.0.5","jest-environment-jsdom":"^30.2.0","lint-staged":"^16.1.5","react":"^19.1.1","react-dom":"^19.1.1","rimraf":"^6.0.1","rollup":"^4.47.1","rollup-plugin-dts":"^6.2.3","rollup-plugin-livereload":"^2.0.5","rollup-plugin-serve":"^3.0.0","standard-version":"^9.5.0","ts-jest":"^29.4.1","ts-node":"^10.9.2","typescript":"^5.9.2"},"peerDependencies":{"react":">=17","react-dom":">=17"},"packageManager":"yarn@4.5.3","publishConfig":{"access":"public"},"_id":"@beefree.io/react-email-builder@1.0.4","gitHead":"55644562976262b9ca75865752460f3f6492344a","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-rjEBSehDtsyKe4kiG93kh87oIDn3k1KWUpRpUbJO9OAGdO1AwHx9NmZcXB0p5LBVC/x6RNIpk4Me5qW09/jELA==","shasum":"148a55e12869f8cf5be46271904e5d182b71b662","tarball":"https://registry.npmjs.org/@beefree.io/react-email-builder/-/react-email-builder-1.0.4.tgz","fileCount":6,"unpackedSize":72545,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICXVs4xZ6DCVrqx3eeupCdmvpbO2l/AIOnzc9ApBnKvoAiB5itUDRhv9DBPG+Y/OpeAbejiqqq0m5blTheKs+wSgVA=="}]},"_npmUser":{"name":"mailupinc.2012","email":"dev@beefree.io"},"directories":{},"maintainers":[{"name":"gaggero","email":"davide.gaggero@beefree.io"},{"name":"robmar","email":"rmarchet@gmail.com"},{"name":"pinkynrg","email":"biggyapple@gmail.com"},{"name":"davide.ponti","email":"davide.ponti@beefree.io"},{"name":"clarissabarbieri","email":"clarissa.barbieri@growens.io"},{"name":"mailupinc.2012","email":"dev@beefree.io"},{"name":"marco.bianchi","email":"marco.bianchi@beefree.io"},{"name":"sferrario","email":"simone.ferrario@beefree.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/react-email-builder_1.0.4_1780608357080_0.9178289483638276"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-25T16:10:11.067Z","modified":"2026-06-04T21:25:57.518Z","1.0.2":"2026-02-25T16:10:11.320Z","1.0.3":"2026-02-26T13:39:07.792Z","1.0.4":"2026-06-04T21:25:57.259Z"},"bugs":{"url":"https://github.com/BeefreeSDK/npm-react/issues"},"author":{"name":"Beefree","email":"dev@beefree.io","url":"https://www.beefree.io"},"license":"Apache-2.0","homepage":"https://github.com/BeefreeSDK/npm-react#readme","keywords":["react","beefree","beefree-sdk","email-builder","email-template","email-template-builder","email-design","email-editor","html-email","responsive-email","newsletter","page-builder","landing-page-builder","popup-builder","drag-and-drop","drag-drop-editor","wysiwyg","visual-editor","no-code","low-code","react-component","react-hooks","collaborative-editing","real-time-collaboration"],"repository":{"type":"git","url":"git+https://github.com/BeefreeSDK/npm-react.git"},"description":"React components and hooks for the Beefree SDK — drag-and-drop email, page, and popup builder with collaborative editing","maintainers":[{"name":"gaggero","email":"davide.gaggero@beefree.io"},{"name":"robmar","email":"rmarchet@gmail.com"},{"name":"pinkynrg","email":"biggyapple@gmail.com"},{"name":"davide.ponti","email":"davide.ponti@beefree.io"},{"name":"clarissabarbieri","email":"clarissa.barbieri@growens.io"},{"name":"mailupinc.2012","email":"dev@beefree.io"},{"name":"marco.bianchi","email":"marco.bianchi@beefree.io"},{"name":"sferrario","email":"simone.ferrario@beefree.io"}],"readme":"# Beefree SDK React Component\n\n[![npm version](https://badge.fury.io/js/%40beefree.io%2Freact-email-builder.svg)](https://www.npmjs.com/package/@beefree.io/react-email-builder)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![CI](https://github.com/BeefreeSDK/npm-react/workflows/CI/badge.svg)](https://github.com/BeefreeSDK/npm-react/actions)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.9.2-blue)](https://www.typescriptlang.org/)\n[![React](https://img.shields.io/badge/React-19.1.1-blue)](https://react.dev/)\n\nA React wrapper component for the [Beefree SDK](https://www.beefree.io/), making it easy to integrate the Beefree email/page builder into your React applications.\n\n![Beefree SDK React Builder](docs/react-email-builder-example.png)\n\n## Table of Contents\n\n- [What is Beefree SDK?](#what-is-beefree-sdk)\n- [Overview](#overview)\n- [Compatibility](#compatibility)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [API Reference](#api-reference)\n- [Hooks](#hooks)\n- [Best Practices](#best-practices)\n- [Advanced Usage](#advanced-usage)\n- [Examples](#examples)\n- [FAQ](#faq)\n- [Development](#development)\n- [Other Frameworks](#other-frameworks)\n- [License](#license)\n\n## What is Beefree SDK?\n\n[Beefree SDK](https://www.beefree.io/) is a drag-and-drop visual content builder that lets your users design professional emails, landing pages, and popups — without writing code. It powers thousands of SaaS applications worldwide, offering a white-label, embeddable editing experience with real-time collaborative editing, responsive design output, and extensive customization options.\n\nThis React package provides a `Builder` component and a `useBuilder` hook that handle SDK initialization, lifecycle management, and configuration updates — giving you a React-friendly API to integrate the full Beefree editing experience into your application.\n\n## Overview\n\n### Features\n\n- 🎯 **Simple React Integration** - Drop-in component with minimal setup\n- 🪝 **React Hooks Support** - `useBuilder` hook for programmatic control\n- 🔄 **Dynamic Configuration** - Update builder configuration on the fly\n- 👥 **Collaborative Editing** - Support for shared/collaborative sessions\n- 📦 **TypeScript Support** - Full TypeScript definitions included\n- 🎨 **Customizable** - Full access to Beefree SDK configuration options\n\n## Compatibility\n\n| Requirement | Version                                           |\n| ----------- | ------------------------------------------------- |\n| React       | 17, 18, or 19                                     |\n| Node.js     | >= 18.0.0                                         |\n| TypeScript  | >= 4.7 (optional, but recommended)                |\n| Browsers    | Chrome, Firefox, Safari, Edge (latest 2 versions) |\n\n## Installation\n\n```bash\nnpm install @beefree.io/react-email-builder\n# or\nyarn add @beefree.io/react-email-builder\n```\n\n## Quick Start\n\n### 1. Get your credentials\n\nSign up at [developers.beefree.io](https://developers.beefree.io) to get your `client_id` and `client_secret`.\n\n### 2. Set up token generation on your backend\n\nYour backend server should exchange credentials for a short-lived token (see [Security: Server-Side Token Generation](#-security-server-side-token-generation) below for details):\n\n```javascript\n// Example: Node.js/Express backend endpoint\napp.post(\"/api/beefree/token\", async (req, res) => {\n  const response = await fetch(\"https://auth.getbee.io/loginV2\", {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application/json\" },\n    body: JSON.stringify({\n      client_id: process.env.BEEFREE_CLIENT_ID,\n      client_secret: process.env.BEEFREE_CLIENT_SECRET,\n      grant_type: \"password\",\n    }),\n  });\n  res.json(await response.json());\n});\n```\n\n### 3. Integrate the builder in your React app\n\n```tsx\nimport { useState, useEffect } from \"react\";\nimport { Builder, IToken, useBuilder } from \"@beefree.io/react-email-builder\";\n\nfunction EmailEditor() {\n  const [token, setToken] = useState<IToken | null>(null);\n\n  const { save, preview } = useBuilder({\n    uid: \"user-123\",\n    container: \"bee-container\",\n    language: \"en-US\",\n  });\n\n  useEffect(() => {\n    fetch(\"/api/beefree/token\", { method: \"POST\" })\n      .then((res) => res.json())\n      .then(setToken);\n  }, []);\n\n  if (!token) return <div>Loading builder...</div>;\n\n  return (\n    <div>\n      <div>\n        <button onClick={() => preview()}>Preview</button>\n        <button onClick={() => save()}>Save</button>\n      </div>\n      <Builder\n        id=\"bee-container\"\n        token={token}\n        template={{ comments: {}, page: {} }}\n        onSave={(json, html) => console.log(\"Saved:\", { json, html })}\n        onError={(err) => console.error(\"Builder error:\", err)}\n      />\n    </div>\n  );\n}\n```\n\n## API Reference\n\n### `Builder` Component\n\n#### Props\n\n| Prop                       | Type                                    | Required | Description                                                     |\n| -------------------------- | --------------------------------------- | -------- | --------------------------------------------------------------- |\n| `id`                       | `string`                                | Yes      | The container ID (must match the `container` from `useBuilder`) |\n| `token`                    | `IToken`                                | Yes      | Authentication token from Beefree API                           |\n| `template`                 | `IEntityContentJson`                    | Yes      | Initial template/content to load                                |\n| `shared`                   | `boolean`                               | No       | Enable collaborative editing session                            |\n| `sessionId`                | `string`                                | No       | Session ID to join (for collaborative editing)                  |\n| `width`                    | `React.CSSProperties['width']`          | No       | Container width (default: '100%')                               |\n| `height`                   | `React.CSSProperties['height']`         | No       | Container height (default: '800px')                             |\n| `loaderUrl`                | `string`                                | No       | Custom loader URL for the Beefree SDK                           |\n| `onLoad`                   | `() => void`                            | No       | Callback when builder is fully loaded and ready                 |\n| `onSave`                   | `(json, html) => void`                  | No       | Callback when content is saved                                  |\n| `onChange`                 | `(json, metadata) => void`              | No       | Callback when content changes                                   |\n| `onError`                  | `(error: BeePluginError) => void`       | No       | Error callback handler                                          |\n| `onWarning`                | `(warning: BeePluginError) => void`     | No       | Warning callback handler                                        |\n| `onSaveRow`                | `(row: string) => void`                 | No       | Callback when a row is saved                                    |\n| `onRemoteChange`           | `(data) => void`                        | No       | Callback for collaborative editing remote changes               |\n| `onSessionStarted`         | `(data: { sessionId: string }) => void` | No       | Callback when collaborative session starts                      |\n| `onTemplateLanguageChange` | `(language) => void`                    | No       | Callback when template language changes                         |\n\n#### Basic Configuration\n\n```tsx\nuseBuilder({\n  uid: \"user-123\",\n  container: \"bee-container\",\n\n  // Customization\n  language: \"en-US\",\n  specialLinks: [\n    { type: \"unsubscribe\", label: \"Unsubscribe\", link: \"[unsubscribe]\" },\n  ],\n\n  // Content management\n  contentDialog: {\n    saveRow: {\n      label: \"Save Row\",\n      handler: (resolve) => resolve({ name: \"My Row\" }),\n    },\n  },\n});\n\nreturn (\n  <Builder\n    token={token}\n    template={{\n      comments: {},\n      page: {},\n    }}\n    onSave={(jsonFile, htmlFile) => {\n      console.log(\"Saved:\", { jsonFile, htmlFile });\n    }}\n  />\n);\n```\n\n## Hooks\n\n### `useBuilder`\n\nThe `useBuilder` hook provides programmatic control over the builder instance and allows you to dynamically update configuration properties (non-callback properties like `uid`, `language`, etc.).\n\n```tsx\nimport { Builder, useBuilder } from \"@beefree.io/react-email-builder\";\n\nfunction MyComponent() {\n  // Initialize useBuilder with config including container ID\n  const initialConfig = {\n    container: \"bee-editor\", // This is the ID that links hook and component\n    uid: \"user-123\",\n    language: \"en-US\",\n    // ...more configs\n  };\n\n  const { updateConfig, load, save, saveAsTemplate } =\n    useBuilder(initialConfig);\n\n  // Update configuration dynamically\n  const changeLanguage = (lang: string) => {\n    updateConfig({ language: lang });\n  };\n\n  const changeUser = (userId: string) => {\n    updateConfig({ uid: userId });\n  };\n\n  const handleSave = async () => {\n    const result = await save();\n    console.log(\"Saved:\", result);\n  };\n\n  return (\n    <div>\n      <button onClick={() => changeLanguage(\"it-IT\")}>Switch to Italian</button>\n      <button onClick={() => changeUser(\"user-456\")}>Change User</button>\n      <button onClick={handleSave}>Save</button>\n\n      <Builder\n        id=\"bee-editor\"\n        token={token}\n        template={template}\n        // Define callbacks directly in the component\n        onSave={(json, html) => {\n          console.log(\"Content saved:\", json, html);\n        }}\n        onChange={(json, metadata) => {\n          console.log(\"Content changed\");\n        }}\n        onLoad={() => {\n          console.log(\"Builder is ready!\");\n        }}\n      />\n    </div>\n  );\n}\n```\n\n## Best Practices\n\n### 🔒 Security: Server-Side Token Generation\n\n**⚠️ CRITICAL:** Never expose your Beefree API credentials in frontend code!\n\n**❌ Bad (Insecure):**\n\n```tsx\n// DON'T DO THIS!\nconst token = await fetch(\"https://auth.beefree.io/token\", {\n  method: \"POST\",\n  body: JSON.stringify({\n    client_id: \"your-client-id\", // ❌ Exposed!\n    client_secret: \"your-secret\", // ❌ Exposed!\n  }),\n});\n```\n\n**✅ Good (Secure):**\n\n1. **Backend API endpoint** (Node.js/Express example):\n\n```javascript\n// backend/routes/auth.js\napp.post(\"/api/beefree/token\", async (req, res) => {\n  const response = await fetch(\"https://auth.beefree.io/token\", {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application/json\" },\n    body: JSON.stringify({\n      client_id: process.env.BEEFREE_CLIENT_ID,\n      client_secret: process.env.BEEFREE_CLIENT_SECRET,\n      uid: req.user.id, // Your user's ID\n    }),\n  });\n\n  const token = await response.json();\n  res.json(token);\n});\n```\n\n2. **Frontend:**\n\n```tsx\n// frontend/App.tsx\nconst fetchToken = async () => {\n  const response = await fetch(\"/api/beefree/token\", {\n    credentials: \"include\", // Include session cookies\n  });\n  return response.json();\n};\n```\n\n### 📝 Configuration Management\n\nKeep your configuration in `useMemo` to prevent unnecessary re-renders:\n\n```tsx\nconst config = useMemo(\n  () => ({\n    uid: user.id,\n    container: \"bee-container\",\n    onSave: handleSave,\n    // ... other config\n  }),\n  [user.id, handleSave],\n);\n```\n\n### 🎯 Unique Container IDs\n\nWhen using multiple builders on the same page, ensure unique `container` IDs:\n\n```tsx\nconst config1 = useBuilder({ container: \"builder-1\", ...otherProperties });\nconst config2 = useBuilder({ container: \"builder-2\", ...otherProperties });\n```\n\n### 🔄 Collaborative Editing\n\nFor collaborative sessions, share the `sessionId` between users:\n\n```tsx\nfunction CollaborativeEditor() {\n  const [sessionId, setSessionId] = useState<string | null>(null);\n\n  return (\n    <>\n      {/* Host creates the session */}\n      <Builder\n        shared={true}\n        onSessionStarted={({ sessionId }) => setSessionId(sessionId)}\n        {...otherProps}\n      />\n\n      {/* Guest joins with sessionId */}\n      {sessionId && (\n        <Builder shared={true} sessionId={sessionId} {...otherProps} />\n      )}\n    </>\n  );\n}\n```\n\n## Advanced Usage\n\n### Custom Content Dialogs\n\n```tsx\nconst config = {\n  contentDialog: {\n    saveRow: {\n      label: \"Save to Library\",\n      handler: async (resolve) => {\n        // Show your custom UI, then resolve\n        const rowName = await showCustomDialog();\n        resolve({ name: rowName });\n      },\n    },\n    addOn: {\n      handler: async (resolve) => {\n        const content = await fetchCustomContent();\n        resolve(content);\n      },\n    },\n  },\n};\n```\n\n### External Content Sources\n\n```tsx\nconst config = {\n  rowsConfiguration: {\n    externalContentURLs: [\n      {\n        name: \"My Saved Rows\",\n        handle: \"saved-rows\",\n        isLocal: true,\n      },\n    ],\n  },\n  hooks: {\n    getRows: {\n      handler: async (resolve, reject, args) => {\n        if (args.handle === \"saved-rows\") {\n          const rows = await fetchSavedRows();\n          resolve(rows);\n        } else {\n          reject(\"Handle not found\");\n        }\n      },\n    },\n  },\n};\n```\n\n### Mentions/Merge Tags\n\n```tsx\nconst config = {\n  hooks: {\n    getMentions: {\n      handler: async (resolve) => {\n        const mentions = [\n          { username: \"FirstName\", value: \"{{firstName}}\", uid: \"fn\" },\n          { username: \"LastName\", value: \"{{lastName}}\", uid: \"ln\" },\n        ];\n        resolve(mentions);\n      },\n    },\n  },\n};\n```\n\n## Examples\n\nThe [`/example`](example/) directory contains a fully working application that demonstrates:\n\n- Token authentication flow\n- Collaborative editing with template preservation\n- Save/preview actions and downloads from builder callbacks (`Save` -> `.html`, `Save as Template` -> `.json`)\n- Multi-language UI switching (header + example control labels outside the builder)\n- Sample/blank template toggle with local blank template fallback\n- Different builder modes (email, page, popup, file manager) via config\n- Per-instance control bars in co-editing mode\n- Keyboard-accessible split divider with ARIA attributes\n- Reusable toast notification system\n\n**Quick start:**\n\n```bash\ncp .env.sample .env   # Fill in your Beefree credentials\nyarn install\nyarn start            # Opens at http://localhost:3000\n```\n\n## FAQ\n\n### How do I authenticate with the Beefree SDK?\n\nAuthentication requires a `client_id` and `client_secret`, which you get by signing up at [developers.beefree.io](https://developers.beefree.io). These credentials should **never** be exposed in frontend code. Instead, create a backend endpoint that exchanges them for a short-lived token and pass that token to the `Builder` component. See [Security: Server-Side Token Generation](#-security-server-side-token-generation) for a complete example.\n\n### Can I use this with Next.js, Remix, or Vite?\n\nYes. This package works with any React-based framework. The `Builder` component renders a client-side iframe, so in Next.js you should use it inside a `'use client'` component. For Vite, it works out of the box. For Remix, use a `ClientOnly` wrapper or lazy-load the component.\n\n### Does it support collaborative editing?\n\nYes. Set `shared={true}` on the `Builder` component to create a collaborative session. The `onSessionStarted` callback provides a `sessionId` that other users can use to join the same session. See [Collaborative Editing](#-collaborative-editing) for a full example.\n\n### What email clients are supported?\n\nThe Beefree SDK generates responsive HTML that is compatible with all major email clients, including Gmail, Outlook (desktop and web), Apple Mail, Yahoo Mail, and mobile email apps. The output follows email HTML best practices with inline CSS and table-based layouts for maximum compatibility.\n\n### Can I customize the builder UI?\n\nYes. The Beefree SDK supports extensive UI customization including custom content dialogs, external content sources, merge tags, special links, and more. See [Advanced Usage](#advanced-usage) and the [Beefree SDK Documentation](https://docs.beefree.io/) for the full range of customization options.\n\n### How do I load an existing template?\n\nPass your template JSON to the `template` prop of the `Builder` component. You can also use the `load` method from the `useBuilder` hook to programmatically load a template at any time after initialization.\n\n## Development\n\n### Prerequisites\n\n- Node.js >= 18 (see `.nvmrc`)\n- Yarn\n\n### Setup\n\n```bash\n# Install dependencies\nyarn install\n\n# Start the example dev server\nyarn start\n\n# Run tests\nyarn test\n\n# Run tests once (CI)\nyarn test:ci\n\n# Lint\nyarn lint\n\n# Build library\nyarn build\n```\n\n### Building\n\n```bash\nyarn build\n```\n\nThe library build uses **Rollup** and generates CJS, ESM, and DTS outputs.\n\nOutputs:\n\n- `dist/index.js` - CommonJS bundle\n- `dist/index.es.js` - ES module bundle\n- `dist/index.d.ts` - TypeScript definitions\n\n### Project Structure\n\n```\nsrc/                      # Library source\n  Builder.tsx             # React component (Builder)\n  hooks/                  # React hooks (useBuilder, useRegistry)\n  types.ts                # TypeScript types\n  index.ts                # Public API exports\n  __tests__/              # Test files\n\nexample/                  # Example application (Rollup dev server)\n  App.tsx                 # Root component with toast system\n  BeefreeExample.tsx      # Demo component with co-editing\n  beefree-token.ts        # Token service (demo only)\n  environment.ts          # Environment config\n  i18n/                   # Localization files (22 languages)\n  templates/              # Local template files\n```\n\n### Environment Variables\n\nCopy `.env.sample` to `.env` and fill in your Beefree SDK credentials:\n\n```\nEMAIL_BUILDER_CLIENT_ID=your-client-id\nEMAIL_BUILDER_CLIENT_SECRET=your-client-secret\n# EMAIL_BUILDER_USER_ID=your-user-id\n\nPAGE_BUILDER_CLIENT_ID=your-client-id\nPAGE_BUILDER_CLIENT_SECRET=your-client-secret\n# PAGE_BUILDER_USER_ID=your-user-id\n\nPOPUP_BUILDER_CLIENT_ID=your-client-id\nPOPUP_BUILDER_CLIENT_SECRET=your-client-secret\n# POPUP_BUILDER_USER_ID=your-user-id\n\nFILE_MANAGER_CLIENT_ID=your-client-id\nFILE_MANAGER_CLIENT_SECRET=your-client-secret\n# FILE_MANAGER_USER_ID=your-user-id\n```\n\n## Troubleshooting\n\n### Builder not loading\n\n1. Verify token is valid and not expired\n2. Check console for errors\n3. Ensure `container` ID is unique on the page\n\n## Other Frameworks\n\nBeefree SDK wrappers are available for the following frameworks:\n\n| Framework | Package                             | Repository                                                                              |\n| --------- | ----------------------------------- | --------------------------------------------------------------------------------------- |\n| Angular   | `@beefree.io/angular-email-builder` | [BeefreeSDK/angular-email-builder](https://github.com/BeefreeSDK/angular-email-builder) |\n| Vue       | `@beefree.io/vue-email-builder`     | [BeefreeSDK/vue-email-builder](https://github.com/BeefreeSDK/vue-email-builder)         |\n\n## License\n\n[Apache-2.0 License](LICENSE)\n\n## Support\n\nFor issues related to:\n\n- **This React wrapper**: Open an issue on this repository\n- **Beefree SDK**: Visit [Beefree Developer Documentation](https://docs.beefree.io/)\n- **Account/billing**: Contact [Beefree Support](https://www.beefree.io/support/)\n\n## Resources\n\n- [Beefree SDK Documentation](https://docs.beefree.io/)\n- [Beefree API Reference](https://docs.beefree.io/beefree-sdk/apis)\n- [Examples and Guides](https://github.com/BeefreeSDK/beefree-sdk-examples)\n","readmeFilename":"README.md"}