This article provides a comprehensive guide to customizing Appwrite's default email templates and translation strings for production environments.This article provides a comprehensive guide to customizing Appwrite's default email templates and translation strings for production environments.

How to Customize Appwrite Email Templates in Production

When running Appwrite in production (especially from Digital Ocean Marketplace or other pre-built installations), you might want to customize email templates to match your brand. This guide shows you how to do it properly using volume mounts to ensure your changes persist across updates.

\

Understanding Appwrite Email System

Appwrite’s email system consists of two main components:

  1. Template Files (.tpl): HTML structure of emails located in /usr/src/code/app/config/locale/templates/
  2. Translation Files (.json): Text content for different languages in /usr/src/code/app/config/locale/translations/

Available email templates include:

  • email-magic-url.tpl – Passwordless login emails

  • email-inner-base.tpl – Password recovery emails

  • email-otp.tpl – One-time password emails

  • email-mfa-challenge.tpl – Multi-factor authentication

  • email-session-alert.tpl – New session notifications

    \

The Problem with Direct Editing

When using pre-built Appwrite images (like from Digital Ocean Marketplace), the files exist inside Docker containers. If you edit them directly in the container, your changes will be lost when you:

  • Update Appwrite to a new version

  • Recreate containers

  • Scale your deployment

    \

The Solution: Volume Mounts

Volume mounts let you replace container files with your own custom versions that persist on the host filesystem.

\

Step-by-Step Implementation

Step 1: SSH into Your Server

ssh root@your-server-ip cd ~/appwrite # or wherever your docker-compose.yml is located

\

Step 2: Extract Original Files from Container

Since the files are inside the Docker image, we need to copy them out first:

# Create directories for custom files mkdir -p custom-templates mkdir -p custom-translations # Copy all template files from container docker cp appwrite:/usr/src/code/app/config/locale/templates/. ./custom-templates/ # Copy all translation files from container docker cp appwrite:/usr/src/code/app/config/locale/translations/. ./custom-translations/

\ Important: You must copy ALL translation files, not just the ones you want to edit. When you mount a directory, it replaces the entire directory in the container.

\ And you should end up like the following:

\

Step 3: Customize Your Files

Now edit the files you want to customize:

# Edit the English translations vim custom-translations/en.json

\ You insert button, then when finished, insert again, escape then :wq to write and close. Example customization for magic URL email:

{ "emails.magicSession.subject": "Sign In to {{project}}", "emails.magicSession.hello": "Welcome back, {{user}}!", "emails.magicSession.buttonText": "Access My Account", "emails.magicSession.signature": "The {{project}} Team", "emails.magicSession.optionButton": "Click below to securely sign in to your {{b}}{{project}}{{/b}} account. This link expires in 1 hour." }

\

\ Or edit template structure:

vim custom-templates/email-magic-url.tpl

\

Step 4: Update docker-compose.yml

Add volume mounts to your docker-compose.yml under the appwrite service:

appwrite: image: appwrite/appwrite:1.8.0 container_name: appwrite restart: unless-stopped volumes: # Add these two lines for custom email templates - ./custom-templates:/usr/src/code/app/config/locale/templates:ro - ./custom-translations:/usr/src/code/app/config/locale/translations:ro # ... other existing volumes ... - appwrite-uploads:/storage/uploads:rw - appwrite-cache:/storage/cache:rw

The :ro flag makes them read-only for security.

\

Step 5: Apply Changes

# Recreate the appwrite container with new volumes docker compose up -d appwrite # Restart the mail worker to reload translations docker restart appwrite-worker-mails

\

Step 6: Test Your Changes

Trigger a test email through the API:

curl --location 'https://your-domain.com/v1/account/sessions/magic-url' \ --header 'Content-Type: application/json' \ --header 'X-Appwrite-Project: your-project-id' \ --data '{ "userId": "unique()", "email": "[email protected]", "url": "https://your-domain.com/auth" }'

\ Check your email to see the customized template! Here is the email I received, where you can see the new updates:

Understanding Translation Variables

Translation files use placeholders that get replaced with dynamic values:

  • {{project}} – Your project name
  • {{user}} – User’s name or email
  • {{b}}...{{/b}} – Bold text markers
  • {{redirect}} – The action URL
  • {{agentClient}} – Browser/client info
  • {{agentDevice}} – Device type
  • {{agentOs}} – Operating system
  • {{phrase}} – Security phrase for verification

Common Email Templates Reference

Magic URL Login

  • Templateemail-magic-url.tpl
  • Translationsemails.magicSession.*
  • Triggered by: Creating a magic URL session via API

Password Recovery

  • Templateemail-inner-base.tpl
  • Translationsemails.recovery.*
  • Triggered by: Password reset request

Email Verification (OTP)

  • Templateemail-otp.tpl
  • Translationsemails.verification.*
  • Triggered by: Email verification flow

Troubleshooting

Changes Not Reflecting

Problem: You updated the files, but emails still show old content.

Solution: Translations are cached in memory. Always restart both containers:

docker restart appwrite sleep 5 docker restart appwrite-worker-mails # If that still doesn’t work, do a full restart: docker compose down docker compose up -d

\

Error 500 After Changes

Problem: Server returns 500 error after modifying translation files.

Solution: This usually means JSON syntax error. Validate your JSON:

cat custom-translations/en.json | python3 -m json.tool

Common mistakes:

  • Missing commas between properties
  • Extra comma after last property
  • Using single quotes instead of double quotes
  • Unescaped special characters

Missing Translation File Error

Problem: Error saying translation file not found.

Solution: Ensure you copied ALL translation files, not just the ones you modified:

# Re-copy all files docker cp appwrite:/usr/src/code/app/config/locale/translations/. ./custom-translations/

Changes Lost After Update

Problem: Updated Appwrite and customizations disappeared.

Solution: This shouldn’t happen with volume mounts. Verify your docker-compose.yml still has the volume mounts after the update.

Development vs Production

Local Development

For local development with the full Appwrite source code:

  1. Edit files directly in your local repository
  2. Files are already mounted via ./app:/usr/src/code/app
  3. Changes are live – just restart containers
  4. Test with MailCatcher at http://localhost:9503

Production Deployment

For production:

  1. Use the volume mount approach described above
  2. Keep your custom files in version control
  3. Consider creating a custom Docker image for larger customizations
  4. Always test in staging before applying to production

Best Practices

  1. Version Control: Keep your custom-templates and custom-translations directories in git
  2. Backup: Backup these directories before major updates
  3. Testing: Always test email templates in a staging environment first
  4. Documentation: Document what you’ve customized for your team
  5. Minimal Changes: Only customize what’s necessary – makes updates easier
  6. Multi-language: If you support multiple languages, update all relevant translation files

\

Disclaimer: The articles reposted on this site are sourced from public platforms and are provided for informational purposes only. They do not necessarily reflect the views of MEXC. All rights remain with the original authors. If you believe any content infringes on third-party rights, please contact [email protected] for removal. MEXC makes no guarantees regarding the accuracy, completeness, or timeliness of the content and is not responsible for any actions taken based on the information provided. The content does not constitute financial, legal, or other professional advice, nor should it be considered a recommendation or endorsement by MEXC.

You May Also Like

Sunmi Cuts Clutter and Boosts Speed with New All-in-One Mobile Terminal & Scanner-Printer

Sunmi Cuts Clutter and Boosts Speed with New All-in-One Mobile Terminal & Scanner-Printer

SINGAPORE, Jan. 16, 2026 /PRNewswire/ — Business Challenge: Stores today face dual pressures: the need for faster, more flexible customer service beyond fixed counters
Share
AI Journal2026/01/16 20:31
Cloud mining is gaining popularity around the world. LgMining’s efficient cloud mining platform helps you easily deploy digital assets and lead a new wave of crypto wealth.

Cloud mining is gaining popularity around the world. LgMining’s efficient cloud mining platform helps you easily deploy digital assets and lead a new wave of crypto wealth.

The post Cloud mining is gaining popularity around the world. LgMining’s efficient cloud mining platform helps you easily deploy digital assets and lead a new wave of crypto wealth. appeared on BitcoinEthereumNews.com. SPONSORED POST* As the cryptocurrency market continues its recovery, Ethereum has once again become the center of attention for investors. Recently, the well-known crypto mining platform LgMining predicted that Ethereum may surpass its previous all-time high and surge past $5,000. In light of this rare market opportunity, choosing a high-efficiency, secure, and low-cost mining platform has become the top priority for many investors. With its cutting-edge hardware, intelligent technology, and low-cost renewable energy advantages, LgMining Cloud Mining is rapidly emerging as a leader in the cloud mining industry. Ethereum: The Driving Force of the Crypto Market Ethereum is not only the second-largest cryptocurrency by market capitalization but also the backbone of the blockchain smart contract ecosystem. From DeFi (Decentralized Finance) to NFTs (Non-Fungible Tokens) and the broader Web3.0 infrastructure, most innovations are built on Ethereum. This widespread utility gives Ethereum tremendous growth potential. With the upcoming scalability upgrades, the Ethereum network is expected to offer improved performance and transaction speed—likely triggering a fresh wave of market enthusiasm. According to the LgMining research team, Ethereum’s share among institutional and retail investors continues to grow. Combined with shifting monetary policies and global economic uncertainties, Ethereum is expected to break past its previous high of over $4,000 and aim for $5,000 or more in the coming months. LgMining Cloud Mining: Unlocking a Low-Barrier Path to Wealth Traditional crypto mining often requires expensive mining rigs, stable electricity, and complex maintenance—making it inaccessible for the average person. LgMining Cloud Mining breaks down these barriers, allowing anyone to easily participate in mining Ethereum and Bitcoin without owning hardware. LgMining builds its robust and efficient mining infrastructure around three core advantages: 1. High-End Equipment LgMining uses top-tier mining hardware with exceptional computing power and reliability. The platform’s ASIC and GPU miners are carefully selected and tested to…
Share
BitcoinEthereumNews2025/09/18 03:04
State Street Corporation (NYSE: STT) Reports Fourth-Quarter and Full-Year 2025 Financial Results

State Street Corporation (NYSE: STT) Reports Fourth-Quarter and Full-Year 2025 Financial Results

BOSTON–(BUSINESS WIRE)–State Street Corporation (NYSE: STT) reported its fourth-quarter and full-year 2025 financial results today. The news release, presentation
Share
AI Journal2026/01/16 20:46