English
Migration from BeeFree
The @templatical/import-beefree package converts BeeFree (BEE) JSON templates into Templatical's TemplateContent format.
WARNING
This package is in active development. Some block types and advanced features may not be fully supported yet. Test your converted templates before using them in production.
Installation
bash
npm install @templatical/import-beefreebash
pnpm add @templatical/import-beefreebash
yarn add @templatical/import-beefreebash
bun add @templatical/import-beefreeWithout a build step (CDN)
You can also load it from a CDN:
html
<script type="module">
import { convertBeeFreeTemplate } from 'https://cdn.jsdelivr.net/npm/@templatical/import-beefree/+esm';
// ...then convert as shown in Usage below
</script>Usage
ts
import { convertBeeFreeTemplate } from '@templatical/import-beefree';
// Load your BeeFree template JSON
const res = await fetch('/api/beefree-templates/123');
const beefreeJson = await res.json();
// Convert to Templatical format
const { content, report } = convertBeeFreeTemplate(beefreeJson);
// Use in the editor
const editor = await init({
container: '#editor',
content,
});
// Check the conversion report for any issues
console.log(report);The function returns an ImportResult with:
content— the convertedTemplateContentready for the editorreport— a conversion report with the status of each block (converted,approximated,html-fallback, orskipped)
| Status | Meaning |
|---|---|
converted | Mapped to a Templatical block with no loss of fidelity. |
approximated | Mapped, with a clamp or flatten — note states what changed. |
html-fallback | No block equivalent — an unknown module type, forms included. Output is an HtmlBlock; see Block Mapping for its content. |
skipped | No output. This converter does not emit it: every module produces a block. |
The JSON BeeFree's editor persists (page.rows) is the input. A compiled HTML export is a different envelope — use @templatical/import-html.
Block Mapping
BeeFree block types map to Templatical equivalents:
| BeeFree Module | Templatical Block | Status |
|---|---|---|
| Text | paragraph | Converted |
| Paragraph | paragraph | Converted |
| Heading | title | Converted |
| List | paragraph | Converted |
| Image | image | Converted |
| Button | button | Converted |
| Divider | divider | Converted (approximated when a partial-width divider is aligned left or right) |
| Spacer | spacer | Converted |
| Social | social | Converted |
| Html | html | Converted |
| Menu | menu | Approximated (styles may differ) |
| Video | video | Converted |
| Table | table | Converted |
Unknown module types — forms included — are converted to HTML blocks as a fallback, reported html-fallback. The block's content is the module's descriptor.text.html, descriptor.html.html or descriptor.heading.text, the first one set. With none of them, it is a <!-- Unsupported BeeFree module: <type> --> comment and renders nothing.
Image width
| BeeFree image | ImageBlock.width | Status |
|---|---|---|
computedStyle.class includes autowidth | "full" | Converted |
computedStyle.width narrower than the image's room | the px number, rounded | Converted |
computedStyle.width as wide as the room or wider | "full" | Converted |
no computedStyle | image.width, by the same rule | Converted |
| no width at all | "full" | Converted |
image.width and image.height are the image file's size, and computedStyle.width is the width BeeFree shows it at. The image's room is its column's content width less the image's left and right padding. image.height is not imported, so the image keeps the file's aspect ratio at the width it is shown at. An image with no text-align takes its alignment from computedStyle.class (left, center or right).
Divider width
BeeFree width | DividerBlock.width | Status |
|---|---|---|
missing, or 100% | "full" | Converted |
a percentage under 100%, such as 50% | the same percentage to two decimals, "50%" | Converted |
below 0% or above 100% | clamped to "0%" or "full" | Approximated |
| px, narrower than its column's content width | the px number | Converted |
| px, as wide as its column's content width or wider | "full" | Converted |
| a negative px width | 0 | Approximated |
| any other value | "full" | Approximated |
A column's content width is its share of settings.width, by the section's column layout, less the divider's left and right padding. A row of four or more columns is flattened, and its modules span the whole settings.width.
Templatical centres every divider. A partial-width divider that BeeFree aligns left or right (computedStyle.align) is approximated, and its note names the alignment.
Column Layout Conversion
BeeFree organizes content into rows with columns. These map to Templatical's SectionBlock with the appropriate ColumnLayout:
| BeeFree Columns | Templatical Layout |
|---|---|
| 1 column (100%) | '1' |
| 2 equal columns | '2' |
| 3 equal columns | '3' |
| 2 columns (~33/66) | '1-2' |
| 2 columns (~66/33) | '2-1' |
Column widths that don't match a standard ratio are mapped to the closest available layout.
Template Settings
Global template settings are converted where possible:
- Width --
page.body.content.computedStyle.messageWidthmaps tosettings.width, withpage.body.content.style.widthas the fallback and 600 when neither is set - Background color --
page.body.content.style.background-colormaps tosettings.backgroundColor, withpage.body.container.style.background-coloras the fallback and#ffffffwhen neither is set. A row'scontent.style.background-colorbecomes its section'sbackgroundColor; a single-column row with one is wrapped in a one-column section so the color survives. A row'scontainer.stylecolor — the full-width band behind the row — is not read, so it's dropped. - Background images -- A row's
content.stylebackground-imagebecomes its section'sbackgroundImage, withbackground-size,background-positionandbackground-repeat(CSS's initial values where unset), and wraps a single-column row in a section as a color does. Thecontainer.styleband's image shows only while the content area has neither an image nor a color: then the section paints it at the content width; otherwise it's dropped. A size that fills a side (100%, or a px width at least the email's) becomescoverand any other length or percentageauto; a percentage position snaps to the nearest of left, center and right (top, center and bottom);repeat-xandrepeat-ybecomerepeat.report.warningsnames every band image and every value with no exact keyword. - Text color --
page.body.content.style.colormaps tosettings.textColor,#1a1a1awhen it is unset. Text, paragraph, list, heading, menu and table modules with no color of their own follow it. - Links --
page.body.content.computedStyle.linkColormaps tosettings.linkColor.settings.linkUnderlineistrue: BeeFree sets underlines per link, in each link's markup. - Font family -- The default font family carries over to
settings.fontFamily. The whole stack carries over, so its fallbacks survive; a stack that is exactly a built-in font's own (Arial, sans-serif) is stored as the bare name. A module whosefont-familyisinherit,initial,unsetorrevertsets no font of its own and takessettings.fontFamily.
Known Limitations
- Custom fonts -- BeeFree custom font declarations are not automatically imported. Add them manually via the
fontsconfig option. - Conditional display -- BeeFree dynamic content rules do not have a direct equivalent and are dropped during conversion.
- Icons -- BeeFree custom icon uploads are not migrated. Standard social platform icons are mapped by name.
- Forms -- BeeFree form modules have no Templatical equivalent. Each becomes an
html-fallbackHTML block, and the form's fields and submit action are not reproduced. - Per-block link colors -- A text module's own link color (
computedStyle.linkColor) is dropped; its links takesettings.linkColor. - Advanced styling -- Some granular BeeFree style properties (e.g., per-column padding overrides) may not be fully preserved.
Verifying Converted Templates
After conversion, review the output in the editor to check for:
- Missing images (re-upload or update URLs if needed)
- Font rendering (add custom fonts to the editor config)
- Column proportions (adjust layouts if the automatic mapping doesn't match)
- Spacing and padding (fine-tune in the block settings panel)