13 KiB
Gitea Mail Templates
Polished, drop-in email template themes for self-hosted Gitea.
Latest Release: v28.0.0
Philosophy
Most self-hosted Gitea instances use the default plain email templates. This project provides ready-to-deploy, visually polished alternatives — each designed for a specific community or audience, so you can pick the one that feels right for your users.
The source on main uses locked official Gitea inputs and a reusable control framework. Gitea supplies mail values, notification logic and translations; shared controls organize headers, buttons, fallback URLs and footers, while themes define styling. Official files are downloaded during development/CI, not maintained in this repository. This refactor is unreleased and uses v28.0.0 as its baseline. Source clones must build installable templates first; release archives contain ready-to-copy files. Check the compatibility matrix before choosing a published archive.
Style Gallery
The gallery shows the themes currently included in this repository; new themes can be added as separate directories under themes/.
Gallery images show the current shared-framework source build, not historical release archives. Original theme palettes, typography, header treatment and button/fallback controls are preserved. See the local preview and capture instructions.
Local preview gallery — generate the preview data as described below, then open it in a browser for an interactive style switcher with desktop/mobile viewports and view mode (Modern, Source).
Installation
Quick Start
For a source clone, build from the committed gitea.lock.json first (Go 1.24+; first build downloads locked inputs if the cache is absent). A missing lock is an error; the tool never selects the latest Gitea automatically:
cd tools
go run . build all
cd ..
Choose a style, then copy its generated mail/ directory into your Gitea custom templates path. A release archive uses themes/<name>/mail/ instead of build/themes/<name>/mail/:
# Locate your Gitea custom directory
# (set by GITEA_CUSTOM; defaults shown below)
# Copy templates (example: Horizon style)
mkdir -p /var/lib/gitea/custom/templates/mail
cp -r build/themes/horizon/mail/. /var/lib/gitea/custom/templates/mail/
# Restart Gitea
systemctl restart gitea
Custom Directory Location
The paths below are common deployment examples, not universal defaults. Confirm your instance's configured custom path before copying files.
| Platform | Example Custom Path |
|---|---|
| Linux (binary) | /var/lib/gitea/custom |
| Linux (Docker) | /data/gitea |
| Windows | C:\gitea\custom |
Switching Styles
Back up your current mail overrides before switching styles. Remove files installed by the previous theme (listed in its build.json), then install the new theme's complete output. This matters when switching from framed to shared: stale per-email overrides would continue using the previous layout. Preserve unrelated custom templates.
cp -r build/themes/terminal/mail/. /var/lib/gitea/custom/templates/mail/
systemctl restart gitea
Confirming It Works
The admin test email does not use custom mail templates. To verify your templates are active, trigger a real email notification. The quickest way is the password reset flow: log out, click "Forgot password" on the login page, and check the reset email — it will render with your custom styles.
Preview
Static preview works without a server after generation; the development server supports live reload. A source clone must generate the manifest and per-language bundles first. The refactor packages all official languages in future archives. Existing v28.0.0 and earlier archives retain their original contents.
Official Inputs (upstream)
Run from tools/: go run . upstream prepare downloads an absent cache using the existing lock; go run . upstream verify checks an existing cache offline; go run . upstream sync --tag vX.Y.Z explicitly replaces the version and generates the lock. All support --root <repository-root> after the subcommand (default ..).
Without the root lock, preparation, verification, build and preview fail. Restore the tracked lock for a normal clone; intentional initialization can use go run . upstream sync --tag v28.0.0. Sync requires network access, accepts stable Gitea 28+ tags, and does not update documentation or publish releases. Damaged/mismatched caches require inspection and recovery, not an automatic repair. See the full command and recovery guide.
Static Preview
From a source clone, generate the preview data once, then open the HTML file in a browser:
cd tools
go run . preview all
cd ..
# Open preview/index.html in a browser; no server is needed.
Dev Server (Live Reload)
Start a pure Go development server that watches theme resources, shared framework, lock/cache and fixtures, auto-rebuilds, and pushes live updates via SSE:
cd tools
go run . dev
# Open http://127.0.0.1:3456 in a browser.
| Capability | Static | Dev |
|---|---|---|
| Go template rendering | [YES] | [YES] |
| Theme/template/language switching | [YES] | [YES] |
| Live reload on save | [NO] | [YES] |
Features
- Theme switcher — browse all available visual styles
- Template switcher — mail types discovered from the official snapshot (currently 11)
- Language switcher — all official locale files (28 in the v28.0.0 snapshot), loaded on demand
- View mode — Modern (rendered preview), Source (raw HTML)
- Viewport toggle — Desktop 1386×780 / Mobile 390×780
- Parameter panel — mock data per email type
- Keyboard shortcuts —
←→tab between Theme/Template/Language/View,↑↓select within,d/mviewport
Directory Structure
gitea-mail-templates/
├── gitea.lock.json # Generated version/commit/checksums, no vendored upstream source
├── framework/ # Reusable mail controls and structural layout presets
├── themes/ # theme.json and theme.css per style; no mail logic
├── build/upstream/ # Downloaded official inputs and license; ignored
├── build/themes/ # Generated installable overrides; ignored
│ └── <name>/mail/ # Generated files for each source theme
├── preview/ # Live preview SPA
│ ├── index.html # Theme/template/language/view/viewport switcher
│ ├── rendered.js # Generated manifest; ignored
│ └── rendered/ # Generated per-language JS bundles; ignored
├── tools/ # Modular CLI tooling
│ ├── tools.go # Main entry point
│ ├── cli/ # CLI commands (upstream, build, preview, dev, list, create, delete)
│ ├── config/ # Config types and templates_config.json loading
│ ├── data/ # Preview metadata and mock contexts
│ ├── upstream/ # Snapshot sync and offline verification
│ ├── builder/ # Official-context alignment and framework/theme generation
│ ├── preview/ # Rendering, locale adapter and dev server
│ └── go.mod
├── docs/ # Bilingual documentation (English + Simplified Chinese)
├── AGENTS.md # AI agent guidance
├── CONTRIBUTING.md
├── LICENSE
├── README.md
└── .gitignore
Template Types
These are the official v28.0.0 entrypoints, not individually maintained theme sources. Framework-backed framed themes generate them using one alignment layer and shared controls. Optional shared mode overrides only the two base partials without adding controls.
| File | Email Trigger |
|---|---|
mail/user/auth/activate.tmpl |
Account activation |
mail/user/auth/activate_email.tmpl |
Email address verification |
mail/user/auth/register_notify.tmpl |
New registration notification |
mail/user/auth/reset_passwd.tmpl |
Password reset |
mail/org/team_invite.tmpl |
Team invitation |
mail/repo/collaborator.tmpl |
Repository collaborator added |
mail/repo/transfer.tmpl |
Repository ownership transfer |
mail/repo/release.tmpl |
New release published |
mail/repo/actions/workflow_run.tmpl |
Actions workflow run |
mail/repo/issue/assigned.tmpl |
Issue / Pull Request assigned |
mail/repo/issue/default.tmpl |
Issue / Pull Request updates |
Compatibility
- Latest tested: Gitea 28.0.0
- Latest release: v28.0.0
- For other Gitea versions, check the per-version compatibility matrix before choosing an archive; [PENDING] rows have no verified recommendation. The matching v1.27.2 tag has a known push-notification defect.
- Upstream Gitea 28.1.0: [PENDING]
- New source architecture targets Gitea 28+ and verifies the pinned snapshot offline; see COMPATIBILITY.md for source status and release-specific limitations
- Uses only built-in Gitea template functions and official translation keys
- No custom template functions or locale patches required
Design Principles
- Official mail values — Preserve notification data, conditions, subjects and functional link targets.
- Shared controls, separate themes — One framework owns content alignment and reusable controls; themes own CSS and retain original designs.
- Responsive — Current framed themes use 600px cards with 390px mobile previews; test target email clients before deployment.
- Locale-aware — Official catalogs supply all text; missing keys follow Gitea's English fallback.
- Reproducible — A lightweight lock pins immutable downloads; verified cached builds work offline and install files remain generated.
Gitea v28.0.0 contains a known Polish invitation placeholder defect. Preview reports [UPSTREAM-WARN] and preserves official behavior. Details and validation commands are in CONTRIBUTING.md.
Documentation
Contributing
See CONTRIBUTING.md for guidelines. A Simplified Chinese translation is available in docs/.
License
MIT — see LICENSE and third-party notices. Generated archives retain the official Gitea license and snapshot provenance.
Not affiliated with the Gitea project. Gitea is a community-managed lightweight code hosting solution written in Go.









