Envelopr is a live-reloading development tool for building MJML email templates with instant preview. Write your MJML templates and see changes in real-time, with support for Go template syntax for dynamic content.
- π Live preview with hot reload
- π§© Two-stage template processing (Go templates + MJML)
- π Support for partials and nested directory structures
- π± Responsive preview with mobile/tablet/desktop views
- π¨ Static template variables via YAML configuration
curl -sSfL https://raw.githubusercontent.com/esdete2/envelopr/master/install.sh | shWith Go 1.23 or higher:
go install github.com/esdete2/envelopr@latest- First enter into your project:
cd /path/to/your_project- Create a default config file and directories:
envelopr init- Create your first template in
documents/welcome.mjml:
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text>Hello World!</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>- Start the development server:
envelopr watch- Open http://localhost:3600 in your browser
Envelopr uses a YAML configuration file (envelopr.yaml):
paths:
documents: documents # MJML templates directory
partials: partials # Reusable components
output: output # Compiled HTML output
mjml:
validationLevel: soft # strict/soft/skip
keepComments: false # Preserve HTML comments
beautify: true # Pretty print HTML
minify: false # Minify output
fonts: # Custom web fonts
Roboto: https://fonts.googleapis.com/css?family=Roboto
template:
variables: # Global variables
companyName: ACME Corp
supportEmail: support@acme.com
documents: # Template-specific variables
welcome:
name: John Doe
activationLink: https://example.com/activateEnvelopr uses Go's template language with additional features for email template development.
Basic Go template syntax is supported with variables from your config file:
# With config:
template:
variables:
name: John
showHeader: true
items:
- name: Product
price: $99
# In template:
<!-- Variables -->
<mj-text>Hello {{ .name }}</mj-text>
<!-- Conditionals -->
{{ if .showHeader }}
{{ template "header" . }}
{{ end}}
<!-- Loops -->
{{ range .items}}
<mj-text>Item: {{ .name }} - {{ .price }}</mj-text>
{{ end}}Template variables are defined in your envelopr.yaml configuration.
Use expression (or its shorter alias exp) to preserve Go template expressions in the output HTML:
<mj-button href="{{ expression ".profileUrl" }}">
Visit Profile
</mj-button>
<!-- Same using shorter syntax -->
<mj-button href="{{ exp ".profileUrl" }}">
Visit Profile
</mj-button>
<!-- Output HTML (both variants) -->
<a href="{{ .profileUrl }}">Visit Profile</a>Here's another example preserving loop and conditional expressions:
<mj-section>
<mj-column>
{{ exp "range .products" }}
<mj-text>{{ exp ".name" }}</mj-text>
{{ exp "if .onSale" }}
<mj-text color="red">Sale!</mj-text>
{{ exp "end" }}
{{ exp "end" }}
</mj-column>
</mj-section>
<!-- Output HTML -->
<div>
{{ range .products }}
<p>{{ .name }}</p>
{{ if .onSale }}
<p style="color: red">Sale!</p>
{{ end }}
{{ end }}
</div>This is useful when the final HTML needs to be processed by go templates again.
Create reusable components in the partials directory:
partials/layout.mjml:
<mjml>
<mj-head>
<mj-title>{{ .title }}</mj-title>
</mj-head>
<mj-body>
{{ template "header" . }}
{{ template "content" . }} <!-- Main content injection -->
{{ template "footer" . }}
</mj-body>
</mjml>partials/button.mjml:
<mj-button
href="{{.url}}"
background-color="#2563eb"
border-radius="6px"
>
{{ .label }}
</mj-button>Use them in your templates:
{{ template "layout" . }}
{{ define "content" }}
<mj-section>
<mj-column>
<mj-text>Welcome {{ .name }}!</mj-text>
{{ template "button" dict
"url" (exp ".campaignUrl")
"label" "Shop Now"
}}
</mj-column>
</mj-section>
{{ end }}# Initialize new project
envelopr init
# Compile templates
envelopr build
# Start development server
envelopr watch# Build with custom config file
envelopr build -c custom-config.yaml
# Watch with custom host and port
envelopr watch --host 127.0.0.1 --port 8080
# Initialize without interactive prompts
envelopr init -y
# Set log verbosity (1=error to 5=trace)
envelopr -v 4 watchFor a full list of commands and options, run envelopr --help.
Pull requests are welcome! Feel free to:
- Report bugs
- Suggest new features
- Submit pull requests
Apache-2.0 license - see LICENSE for details.