builder

package
v0.0.15 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 11, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

README

Email Template Builder

A beautiful, minimalist email template builder for AuthSome, inspired by email-builder-js.

Features

  • 🎨 Visual Drag & Drop Editor - Build emails visually without writing HTML
  • 📱 Mobile Responsive - All templates are mobile-friendly by default
  • 🧱 Block-Based - Compose emails from reusable blocks
  • 👁️ Live Preview - See changes in real-time
  • 💾 JSON Storage - Templates stored as clean JSON configuration
  • 🎯 Variable Support - Use template variables like {{.UserName}}
  • 📦 Sample Templates - Pre-built templates to get started quickly
  • 🔧 Extensible - Easy to add custom blocks

Architecture

The builder is composed of several key components:

1. Block Types (types.go)

Defines all available block types and their data structures:

  • EmailLayout - Root container with global styles
  • Text - Paragraph text with formatting
  • Heading - Section headings (h1-h6)
  • Button - Call-to-action buttons
  • Image - Pictures and logos
  • Divider - Horizontal separators
  • Spacer - Vertical spacing
  • Container - Group blocks together
  • Columns - Multi-column layouts
  • Avatar - Profile pictures
  • HTML - Custom HTML code
2. Renderer (renderer.go)

Converts JSON documents to HTML email:

doc := NewDocument()
renderer := NewRenderer(doc)
html, err := renderer.RenderToHTML()

The renderer uses gomponents to generate email-safe HTML that works across all email clients.

3. Templates (templates.go)

Pre-built sample templates:

  • Welcome Email - Greet new users
  • OTP Code - One-time password verification
  • Password Reset - Secure password reset
  • Invitation - Organization invitations
  • Notification - General purpose notifications
4. UI (ui.go)

Visual builder interface with:

  • Left Sidebar - Block palette and sample templates
  • Center Canvas - Design, preview, and code views
  • Right Sidebar - Properties panel for selected blocks
5. Dashboard Integration (dashboard.go)

Integrates the builder into the AuthSome dashboard:

  • Builder routes
  • Template management
  • Preview generation
  • Sample template loading

Usage

Creating a New Template
// Create a new empty document
doc := builder.NewDocument()

// Add blocks
blockID, _ := doc.AddBlock(builder.BlockTypeHeading, map[string]interface{}{
    "style": map[string]interface{}{
        "textAlign": "center",
        "color": "#1a1a1a",
    },
    "props": map[string]interface{}{
        "text": "Welcome!",
        "level": "h1",
    },
}, doc.Root)

// Render to HTML
renderer := builder.NewRenderer(doc)
html, _ := renderer.RenderToHTML()
Using Sample Templates
// Load a sample template
doc, err := builder.GetSampleTemplate("welcome")

// Customize it
// ... modify blocks ...

// Render with variables
html, err := builder.RenderTemplate(doc, map[string]interface{}{
    "AppName": "My App",
    "UserName": "John Doe",
    "DashboardURL": "https://example.com/dashboard",
})
Integrating with Dashboard
// In your plugin initialization
builderHandler := builder.NewDashboardHandler(notificationService)
routes := builderHandler.RegisterRoutes()

// Register routes with dashboard
for _, route := range routes {
    dashboardPlugin.RegisterRoute(route)
}

Block Structure

Each block in the document has this structure:

{
  "type": "BlockType",
  "data": {
    "style": {
      "color": "#333",
      "fontSize": 16,
      "padding": {
        "top": 16,
        "right": 24,
        "bottom": 16,
        "left": 24
      }
    },
    "props": {
      // Block-specific properties
    },
    "childrenIds": [] // For container blocks
  }
}

Email Client Compatibility

All blocks are tested and compatible with:

  • ✅ Gmail (Desktop & Mobile)
  • ✅ Apple Mail (Desktop & Mobile)
  • ✅ Outlook (2016+, Office 365, Web)
  • ✅ Yahoo! Mail
  • ✅ Thunderbird
  • ✅ Mobile clients (iOS Mail, Android Gmail)

Template Variables

The builder supports Go template variables:

Hello {{.UserName}},

Welcome to {{.AppName}}!

{{if .HasPremium}}
You have premium access!
{{end}}

Variables are rendered using Go's text/template engine in the notification service.

Extending the Builder

Adding a Custom Block
  1. Define the block type in types.go:
const BlockTypeCustom BlockType = "Custom"

type CustomBlockData struct {
    Style Style              `json:"style"`
    Props CustomBlockProps   `json:"props"`
}

type CustomBlockProps struct {
    CustomField string `json:"customField"`
}
  1. Add renderer in renderer.go:
func (r *Renderer) renderCustom(block Block) g.Node {
    data := block.Data
    props := getMap(data, "props")
    
    customField := getString(props, "customField", "")
    
    return Div(
        g.Text(customField),
    )
}
  1. Update the UI block palette in ui.go

  2. Add default data in getDefaultBlockData()

Best Practices

Design Guidelines
  1. Keep it Simple - Use clear hierarchy and whitespace
  2. Mobile First - Test on mobile devices
  3. Readable Typography - Use 14-16px for body text
  4. Clear CTAs - Make buttons obvious and actionable
  5. Brand Consistency - Use consistent colors and fonts
Technical Guidelines
  1. Use Tables for Layout - Email clients require table-based layouts
  2. Inline Styles - The renderer uses inline styles for compatibility
  3. Test Thoroughly - Test across different email clients
  4. Keep Images Small - Optimize images for fast loading
  5. Alt Text - Always provide alt text for images

Performance

  • Lightweight - Minimal JavaScript, no external dependencies
  • Fast Rendering - Gomponents generates HTML efficiently
  • Small Payloads - JSON documents are compact
  • Cacheable - Templates can be cached once rendered

Future Enhancements

  • Undo/Redo functionality
  • Copy/paste blocks
  • Block templates library
  • A/B testing support
  • Dark mode support
  • Export to other formats (MJML, React Email)
  • Advanced layout blocks (grids, carousels)
  • Custom CSS support
  • Template marketplace

Credits

Inspired by:

Built with:

License

Part of AuthSome - see main project LICENSE

Documentation

Index

Constants

This section is empty.

Variables

View Source
var SampleTemplates = map[string]*Document{}

SampleTemplates provides pre-built email templates.

Functions

func BuilderButton

func BuilderButton(basePath string, appID string) g.Node

BuilderButton returns a button component to launch the builder.

func BuilderIntegrationCard

func BuilderIntegrationCard() g.Node

BuilderIntegrationCard renders an info card about the builder.

func ExampleComplexLayout

func ExampleComplexLayout()

ExampleComplexLayout shows how to create a complex layout with columns.

func ExampleCreateTemplate

func ExampleCreateTemplate()

ExampleCreateTemplate shows how to create a template from scratch.

func ExampleModifyTemplate

func ExampleModifyTemplate()

ExampleModifyTemplate shows how to modify an existing template.

func ExampleSerialization

func ExampleSerialization()

ExampleSerialization shows how to save and load documents.

func ExampleUseSampleTemplate

func ExampleUseSampleTemplate()

ExampleUseSampleTemplate shows how to use a sample template.

func ExampleValidation

func ExampleValidation()

ExampleValidation shows how to validate a document.

func ListSampleTemplates

func ListSampleTemplates() []string

ListSampleTemplates returns list of available sample templates.

func RenderTemplate

func RenderTemplate(doc *Document, variables map[string]any) (string, error)

RenderTemplate is a helper to render a template to HTML.

func RunAllExamples

func RunAllExamples()

RunAllExamples runs all example functions.

func SampleTemplatesCompact

func SampleTemplatesCompact(basePath string, currentApp *app.App) g.Node

SampleTemplatesCompact renders a compact version for sidebars/modals.

func SampleTemplatesGallery

func SampleTemplatesGallery(basePath string, currentApp *app.App) g.Node

SampleTemplatesGallery renders a gallery of sample templates.

func TemplatePreviewCard

func TemplatePreviewCard(template *Document, name, description, category string) g.Node

TemplatePreviewCard renders a preview card for a template.

func TemplateSelector

func TemplateSelector(basePath string, currentApp *app.App) g.Node

TemplateSelector renders a template selection component for the create modal.

Types

type AvatarBlockData

type AvatarBlockData struct {
	Style BlockStyle       `json:"style"`
	Props AvatarBlockProps `json:"props"`
}

AvatarBlockData represents avatar block configuration.

type AvatarBlockProps

type AvatarBlockProps struct {
	ImageURL string `json:"imageUrl"`
	Alt      string `json:"alt"`
	Size     int    `json:"size"`
	Shape    string `json:"shape"` // circle, square, rounded
}

type Block

type Block struct {
	Type BlockType      `json:"type"`
	Data map[string]any `json:"data"`
}

Block represents a single block in the email.

type BlockStyle

type BlockStyle struct {
	BackgroundColor string   `json:"backgroundColor,omitempty"`
	Color           string   `json:"color,omitempty"`
	FontFamily      string   `json:"fontFamily,omitempty"`
	FontSize        int      `json:"fontSize,omitempty"`
	FontWeight      string   `json:"fontWeight,omitempty"`
	TextAlign       string   `json:"textAlign,omitempty"`
	Padding         *Padding `json:"padding,omitempty"`
}

BlockStyle represents common style properties for blocks.

type BlockType

type BlockType string

BlockType represents the type of email block.

const (
	BlockTypeEmailLayout BlockType = "EmailLayout"
	BlockTypeText        BlockType = "Text"
	BlockTypeHeading     BlockType = "Heading"
	BlockTypeButton      BlockType = "Button"
	BlockTypeImage       BlockType = "Image"
	BlockTypeDivider     BlockType = "Divider"
	BlockTypeSpacer      BlockType = "Spacer"
	BlockTypeContainer   BlockType = "Container"
	BlockTypeColumns     BlockType = "Columns"
	BlockTypeColumn      BlockType = "Column"
	BlockTypeHTML        BlockType = "HTML"
	BlockTypeAvatar      BlockType = "Avatar"
)

type BuilderUI

type BuilderUI struct {
	// contains filtered or unexported fields
}

BuilderUI renders the visual email builder interface.

func NewBuilderUI

func NewBuilderUI(doc *Document, previewURL, saveURL string) *BuilderUI

NewBuilderUI creates a new builder UI instance.

func NewBuilderUIWithAutosave

func NewBuilderUIWithAutosave(doc *Document, previewURL, saveURL, backURL, templateID string) *BuilderUI

NewBuilderUIWithAutosave creates a new builder UI instance with autosave enabled.

func (*BuilderUI) Render

func (b *BuilderUI) Render() g.Node

Render renders the complete builder interface.

type ButtonBlockData

type ButtonBlockData struct {
	Style BlockStyle       `json:"style"`
	Props ButtonBlockProps `json:"props"`
}

ButtonBlockData represents button block configuration.

type ButtonBlockProps

type ButtonBlockProps struct {
	Text         string `json:"text"`
	URL          string `json:"url"`
	ButtonColor  string `json:"buttonColor"`
	TextColor    string `json:"textColor"`
	BorderRadius int    `json:"borderRadius"`
	FullWidth    bool   `json:"fullWidth"`
}

type ColumnBlockData

type ColumnBlockData struct {
	Style       BlockStyle       `json:"style"`
	Props       ColumnBlockProps `json:"props"`
	ChildrenIDs []string         `json:"childrenIds"`
}

ColumnBlockData represents a single column in columns block.

type ColumnBlockProps

type ColumnBlockProps struct {
	Width string `json:"width,omitempty"` // Can be percentage or auto
}

type ColumnsBlockData

type ColumnsBlockData struct {
	Style       BlockStyle        `json:"style"`
	Props       ColumnsBlockProps `json:"props"`
	ChildrenIDs []string          `json:"childrenIds"` // Column IDs
}

ColumnsBlockData represents columns block configuration.

type ColumnsBlockProps

type ColumnsBlockProps struct {
	ColumnsCount int `json:"columnsCount"`
	ColumnsGap   int `json:"columnsGap"`
}

type ContainerBlockData

type ContainerBlockData struct {
	Style       BlockStyle          `json:"style"`
	Props       ContainerBlockProps `json:"props"`
	ChildrenIDs []string            `json:"childrenIds"`
}

ContainerBlockData represents container block configuration.

type ContainerBlockProps

type ContainerBlockProps struct {
	BackgroundColor string `json:"backgroundColor,omitempty"`
}

type DividerBlockData

type DividerBlockData struct {
	Style BlockStyle        `json:"style"`
	Props DividerBlockProps `json:"props"`
}

DividerBlockData represents divider block configuration.

type DividerBlockProps

type DividerBlockProps struct {
	LineColor  string `json:"lineColor"`
	LineHeight int    `json:"lineHeight"`
}

type Document

type Document struct {
	Root   string           `json:"root"`
	Blocks map[string]Block `json:"blocks"`
}

Document represents the email builder document structure.

func FromJSON

func FromJSON(jsonStr string) (*Document, error)

FromJSON creates a document from JSON string.

func GetSampleTemplate

func GetSampleTemplate(name string) (*Document, error)

GetSampleTemplate returns a sample template by name.

func NewDocument

func NewDocument() *Document

NewDocument creates a new empty email document.

func (*Document) AddBlock

func (d *Document) AddBlock(blockType BlockType, data map[string]any, parentID string) (string, error)

AddBlock adds a block to the document and returns its ID.

func (*Document) RemoveBlock

func (d *Document) RemoveBlock(blockID string) error

RemoveBlock removes a block from the document.

func (*Document) ToJSON

func (d *Document) ToJSON() (string, error)

ToJSON converts the document to JSON string.

func (*Document) Validate

func (d *Document) Validate() error

Validate validates the document structure.

type EmailLayoutData

type EmailLayoutData struct {
	BackdropColor string   `json:"backdropColor"`
	CanvasColor   string   `json:"canvasColor"`
	TextColor     string   `json:"textColor"`
	LinkColor     string   `json:"linkColor"`
	FontFamily    string   `json:"fontFamily"`
	ChildrenIDs   []string `json:"childrenIds"`
}

EmailLayoutData represents the root email layout configuration.

type HTMLBlockData

type HTMLBlockData struct {
	Style BlockStyle     `json:"style"`
	Props HTMLBlockProps `json:"props"`
}

HTMLBlockData represents raw HTML block configuration.

type HTMLBlockProps

type HTMLBlockProps struct {
	HTML string `json:"html"`
}

type HeadingBlockData

type HeadingBlockData struct {
	Style BlockStyle        `json:"style"`
	Props HeadingBlockProps `json:"props"`
}

HeadingBlockData represents heading block configuration.

type HeadingBlockProps

type HeadingBlockProps struct {
	Text  string `json:"text"`
	Level string `json:"level"` // h1, h2, h3, h4, h5, h6
}

type ImageBlockData

type ImageBlockData struct {
	Style BlockStyle      `json:"style"`
	Props ImageBlockProps `json:"props"`
}

ImageBlockData represents image block configuration.

type ImageBlockProps

type ImageBlockProps struct {
	URL              string `json:"url"`
	Alt              string `json:"alt"`
	LinkURL          string `json:"linkUrl,omitempty"`
	Width            string `json:"width"`
	Height           string `json:"height,omitempty"`
	ContentAlignment string `json:"contentAlignment"` // left, center, right
}

type Padding

type Padding struct {
	Top    int `json:"top"`
	Right  int `json:"right"`
	Bottom int `json:"bottom"`
	Left   int `json:"left"`
}

Padding represents padding configuration.

type Renderer

type Renderer struct {
	// contains filtered or unexported fields
}

Renderer converts email builder documents to HTML.

func NewRenderer

func NewRenderer(document *Document) *Renderer

NewRenderer creates a new renderer for the given document.

func (*Renderer) Render

func (r *Renderer) Render() (g.Node, error)

Render renders the document to gomponents Node.

func (*Renderer) RenderToHTML

func (r *Renderer) RenderToHTML() (string, error)

RenderToHTML renders the document to HTML string.

type SpacerBlockData

type SpacerBlockData struct {
	Style BlockStyle       `json:"style"`
	Props SpacerBlockProps `json:"props"`
}

SpacerBlockData represents spacer block configuration.

type SpacerBlockProps

type SpacerBlockProps struct {
	Height int `json:"height"`
}

type TemplateInfo

type TemplateInfo struct {
	Name        string
	DisplayName string
	Description string
	Category    string
}

TemplateInfo holds metadata about sample templates.

func GetAllTemplateInfo

func GetAllTemplateInfo() []TemplateInfo

GetAllTemplateInfo returns info about all available templates.

type TextBlockData

type TextBlockData struct {
	Style BlockStyle     `json:"style"`
	Props TextBlockProps `json:"props"`
}

TextBlockData represents text block configuration.

type TextBlockProps

type TextBlockProps struct {
	Text string `json:"text"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL