Agent skill
supabase-email-templates
Generate and deploy Supabase Auth email templates with hosted logos for reliable display; use when email images aren't displaying, updating email content/styling, or deploying template changes
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/supabase-email-templates
SKILL.md
Supabase Email Templates Skill
Manage Supabase Auth email templates with hosted logos for reliable display across all email clients.
When to Use This Skill
Use this skill when:
- Email images are not displaying in received emails
- Need to update email template content or styling
- Adding new email templates to the system
- Updating the Ballee logo in emails
- Debugging email rendering issues
- Deploying template changes to production/staging
DO NOT use for:
- Transactional emails sent via Resend (use email-templates package directly)
- Custom notification emails (use notification system)
- SMTP configuration (use Supabase Dashboard)
Quick Commands
# Generate templates locally (creates HTML from React Email)
pnpm email:templates:generate
# Deploy templates to production
pnpm email:templates:deploy
# Deploy to staging
pnpm email:templates:deploy --staging
# Verify current production templates
pnpm email:templates:deploy --verify
# Full workflow (generate + deploy)
pnpm email:templates:update
Image Handling Best Practice
Why Hosted Images (Not Base64)
Base64-encoded images are blocked by Gmail and Outlook (majority of email clients). Research shows:
| Method | Gmail | Outlook | Apple Mail | Email Size |
|---|---|---|---|---|
| Hosted (recommended) | Works | Works | Works | Small |
| Base64 | Blocked | Blocked | Works | +30% bloat |
| CID embedded | Fails | Works | Works | Increases |
Solution: Use hosted images on flow.ballee.app:
- Works in all email clients when user allows images
- Small email size, fast delivery
- Good alt text provides fallback when images blocked
- Used by Amazon, GitHub, PayPal, Twitter
Logo Configuration
Logo hosted at: https://flow.ballee.app/images/ballee-logo-email.png
Source file: apps/web/public/images/ballee-logo-email.png (120x120px PNG)
Defined in: packages/email-templates/src/components/logo.tsx
export const DEFAULT_LOGO_URL =
'https://flow.ballee.app/images/ballee-logo-email.png';
Templates Managed
| Template | Supabase API Field | Local File |
|---|---|---|
| Confirm Signup | mailer_templates_confirmation_content |
confirm-signup.html |
| Invite User | mailer_templates_invite_content |
invite-user.html |
| Magic Link | mailer_templates_magic_link_content |
magic-link.html |
| Change Email | mailer_templates_email_change_content |
change-email-address.html |
| Reset Password | mailer_templates_recovery_content |
reset-password.html |
| Reauthentication | mailer_templates_reauthentication_content |
reauthentication.html |
Architecture
packages/email-templates/src/
├── components/
│ ├── logo.tsx # Shared logo component (hosted URL)
│ └── wrapper.tsx # Email wrapper (includes logo by default)
├── emails/
│ ├── auth-base.email.tsx # Base template for auth emails
│ ├── confirm-signup.email.tsx
│ ├── invite-user.email.tsx
│ └── ... # Other email templates
└── lib/
└── colors.ts # Brand colors
scripts/
├── generate-supabase-templates.tsx # Generates HTML from React Email
└── update-supabase-email-templates.sh # Deploys to Supabase via API
supabase-email-templates/ # Generated HTML files (gitignored)
├── confirm-signup.html
├── invite-user.html
└── ...
Logo Management
To Update the Logo
- Create new logo as PNG (recommended: 120x120px)
- Replace the file:
bash
# Replace the logo file cp new-logo.png apps/web/public/images/ballee-logo-email.png - Deploy to production (logo is served from
flow.ballee.app) - Regenerate templates (optional, only if logo URL changes):
bash
pnpm email:templates:update
To Change Logo URL
If hosting location changes, update packages/email-templates/src/components/logo.tsx:
export const DEFAULT_LOGO_URL =
'https://new-domain.com/path/to/logo.png';
Then regenerate and deploy templates.
API Details
Supabase Management API
Endpoint: https://api.supabase.com/v1/projects/{project_ref}/config/auth
Method: PATCH
Authentication: Bearer token from 1Password (uipc6jse6q32hu3nyfh6qmssoq)
Project References:
- Production:
csjruhqyqzzqxnfeyiaf - Staging:
hxpcknyqswetsqmqmeep
Troubleshooting
Images Not Displaying
Symptom: Email received but logo shows broken image or placeholder
Possible Causes:
- User has image blocking enabled (normal behavior)
- Logo file not deployed to production server
- Logo URL incorrect in templates
Solution:
# 1. Verify logo file exists on production
curl -I https://flow.ballee.app/images/ballee-logo-email.png
# 2. Verify templates use correct URL
pnpm email:templates:deploy --verify
# 3. If needed, regenerate and deploy
pnpm email:templates:update
Template Variables Not Rendering
Symptom: Email shows {{ .Email }} instead of actual email address
Cause: URL-encoded template variables
Solution: The generation script automatically fixes these. Regenerate:
pnpm email:templates:generate
1Password Token Issues
Symptom: "Could not retrieve Supabase access token"
Solution:
# Login to 1Password CLI
op signin
# Verify token exists
op item get uipc6jse6q32hu3nyfh6qmssoq --fields password --reveal
API Update Fails
Symptom: "Error updating templates" with API response
Common Causes:
- Invalid HTML in templates - regenerate
- Token expired - re-authenticate with
op signin - Rate limiting - wait and retry
Local Development
For local development, email templates are configured in apps/web/supabase/config.toml:
[auth.email.template.recovery]
subject = "Reset your password - Ballee"
content_path = "./supabase/templates/reset-password.html"
Local templates use file paths and are loaded when Supabase starts. Changes require:
pnpm supabase:web:stop && pnpm supabase:web:start
Related Files
| File | Purpose |
|---|---|
packages/email-templates/src/components/logo.tsx |
Shared logo component |
packages/email-templates/src/components/wrapper.tsx |
Email wrapper with logo |
packages/email-templates/src/emails/auth-base.email.tsx |
Base template for auth emails |
apps/web/public/images/ballee-logo-email.png |
Logo image file (120x120px) |
scripts/generate-supabase-templates.tsx |
Template generator script |
scripts/update-supabase-email-templates.sh |
Production deployment script |
Workflow Example
Scenario: User reports logo not showing in password reset email
# 1. Verify logo file is accessible
curl -I https://flow.ballee.app/images/ballee-logo-email.png
# Should return HTTP 200
# 2. Verify current templates
pnpm email:templates:deploy --verify
# Output shows: ✅ recovery: hosted image - src="https://flow.ballee.app/..."
# 3. If templates correct, explain to user that email clients may block images
# by default. They need to click "Display images" or add sender to safe list.
# 4. If templates incorrect, regenerate and deploy
pnpm email:templates:update
Didn't find tool you were looking for?