Skip to main content
This guide covers the developer setup for email delivery in PropOps Web — including sending methods, template customisation, and environment configuration.

Choosing a sending method

PropOps Web supports two email sending methods. Each template can be configured independently.
You can mix both methods — use Brevo for customer-facing emails and local templates for internal notifications.

Setting up local email

Local email works immediately with no configuration. Templates are rendered from views/emails/ and sent via PHP mail().
1

Set your sender details

In your .env file:
2

Configure your branding

Set these so templates display your logo and colour:
3

Leave BREVO_API_KEY empty

When no Brevo key is set, PropOps Web automatically uses local templates:

Setting up Brevo

1

Create a Brevo account

Sign up at brevo.com if you don’t already have an account.
2

Generate an API key

In the Brevo dashboard, go to SMTP & API → API Keys and generate a new key.
3

Add to your environment

4

Verify your sender domain

In Brevo, go to Senders, Domains & Dedicated IPs and verify the domain you’re sending from. This improves deliverability and prevents emails being marked as spam.
5

Set template values to Brevo IDs

For any email you want to send via Brevo, change the template value from a name to the numeric Brevo template ID:

How template resolution works

Each email type is mapped to an EMAIL_TEMPLATE_* variable in .env. The value determines how PropOps Web sends that email:
Local templates use {"{{ params.COLUMN_NAME }}"} syntax — the same format Brevo uses — so migrating between local and Brevo is seamless.

Customising templates

Editing an existing template

All 47 pre-built templates live in views/emails/. Each template is a standalone HTML fragment that gets wrapped in layout.html.
1

Open the template file

Find the template in views/emails/ — for example welcome.html.
2

Edit the HTML

Templates are plain HTML. Use {"{{ params.VARIABLE_NAME }}"} placeholders for dynamic content. Check the existing template to see which variables are available.
3

Test locally

If you’re using Mailpit (via DDEV or Docker), emails will appear in the Mailpit inbox at http://localhost:8025 so you can preview your changes.

Creating a new template

1

Create the HTML file

Create a new .html file in views/emails/. The filename should match the template name you’ll use in .env — for example my_custom_email.html.
2

Add a subject line

Include a subject in an HTML comment at the top of the file:
You can use placeholders in the subject:
3

Write your template content

Add your HTML content. The template will be automatically wrapped in layout.html (logo, footer, styling). You only need to write the inner content:
4

Register in .env

Add a new EMAIL_TEMPLATE_* variable pointing to your template name:
5

Send from code

Use EmailService::sendTemplate() with the env key:

Editing the layout

The shared layout in views/emails/layout.html wraps every template. It contains:
  • The outer email structure (background, centring)
  • Your brand logo (centred)
  • The white content card
  • The footer with APP_URL and copyright
  • Dark mode styles
  • Responsive breakpoints
Edit layout.html to change the look of all emails at once. The placeholder {"{{ TEMPLATE_CONTENT }}"} is where each template’s content is injected.

Auto-injected variables

These variables are available in every template automatically:

Environment configuration

Core settings

Template mappings

Each email type has an EMAIL_TEMPLATE_* variable. Set it to a local template name or a Brevo template ID:
To switch any email to Brevo, replace the template name with the numeric Brevo template ID (e.g. EMAIL_TEMPLATE_WELCOME=30). To switch back to local, set it to the template name (e.g. EMAIL_TEMPLATE_WELCOME=welcome).

Troubleshooting

  • If using Brevo, check that BREVO_API_KEY is set correctly in your .env
  • If using local, check your server’s mail() function is working (php -r "mail('test@example.com','Test','Body');")
  • Verify the sender domain is confirmed in Brevo (if applicable)
  • Check the Email Log in Admin → Email Log for error messages
  • Ensure your sender domain has SPF, DKIM, and DMARC records configured
  • Verify the domain in Brevo’s sender settings
  • Use a professional sender address (avoid free email providers)
  • Check the template file exists in views/emails/ with the correct filename
  • Verify placeholder names match exactly (case-sensitive): {"{{ params.USER_NAME }}"} not {"{{ params.user_name }}"}
  • If the template falls back to the generic template, the specific file may be missing or misspelt
  • Use Mailpit to preview rendered HTML during development
  • To use a local template: set the env value to the template name (e.g. welcome)
  • To use Brevo: set the env value to the numeric Brevo template ID (e.g. 30)
  • You can mix both — each template is independent