Matthieu MALVACHE 43ba0aef8a fix(print): empty page when email viewer carries an enter animation
The print rules introduced with the print-layout change left the
#email-viewer-container's utility animation (animate-in fade-in) in
place. Chrome samples keyframes when it snapshots the page for print,
so it frequently captured the opacity: 0 frame — the page came out
completely empty. Reproduced in a headless print run: the broken rule
set produces an 874-byte blank PDF; this fix produces an 18 KB PDF
with the full header, body text, and iframe content.

The replacement print block resets the viewer subtree's animation,
transition, transform, filter and opacity so no keyframe state leaks
through; switches #email-viewer-container to position: static and
resets the ancestor overflow chain via :has() so a long email prints
across multiple pages instead of being clipped to the first viewport;
and pulls @page margin up to 12mm so the content has breathable
page margins instead of colliding with Chrome's default headers.
2026-04-17 13:01:03 +02:00
2026-03-16 12:41:37 +01:00

JMAP Webmail

A modern, privacy-focused webmail client built with Next.js and the JMAP protocol.

Screenshots

Login

Login

Inbox

Inbox

Email Viewer

Email Viewer

Compose

Compose

Dark Mode

Dark Mode

Settings

Settings

Features

Core Email

  • Modern UI - Clean, minimalist three-pane layout
  • Email Threading - Gmail-style conversation view with inline expansion
  • Real-time Updates - Push notifications for new emails via EventSource
  • Attachments - Upload and download file attachments
  • Search - Full-text email search with pagination
  • Draft Auto-save - Never lose your work while composing

Identity & Privacy

  • Identity Management - Multiple email identities with custom signatures
  • Sub-Addressing - Generate tagged email addresses (user+tag@domain.com) for better organization
  • Newsletter Management - RFC 2369 one-click unsubscribe with security validation
  • Spam Reporting - Mark emails as spam with bidirectional handling and batch operations
  • External Content Blocking - Privacy protection with user-controlled image loading
  • Shared Folders - Multi-account access with proper ID namespacing

User Experience

  • Keyboard Shortcuts - Navigate efficiently with vim-style hotkeys (j/k, r, f, etc.)
  • Context Menus - Right-click for quick actions on emails
  • Drag & Drop - Move emails between folders with native HTML5 DnD
  • Color Tags - Organize emails with color labels
  • Dark Mode - Full dark theme with intelligent email color transformation for readability
  • i18n - English, French, Japanese, Spanish, Italian, German, Dutch, and Portuguese language support with auto-detection
  • Mobile Responsive - Adaptive single/multi-pane layout for all screen sizes

Tech Stack

  • Framework: Next.js 16 with Turbopack
  • Styling: Tailwind CSS v4
  • State: Zustand
  • Protocol: JMAP (RFC 8620)
  • i18n: next-intl

Getting Started

# Install dependencies
npm install

# Run development server
npm run dev

Open http://localhost:3000 and connect to your JMAP server.

Configuration

Create a .env.local file:

APP_NAME=Your Webmail
JMAP_SERVER_URL=https://your-jmap-server.com

Runtime vs Build-time Configuration

Variable Type Description
APP_NAME Runtime App name displayed in the UI
JMAP_SERVER_URL Runtime JMAP server URL (required)
NEXT_PUBLIC_APP_NAME Build-time Legacy fallback for app name
NEXT_PUBLIC_JMAP_SERVER_URL Build-time Legacy fallback for server URL

Runtime variables are read at request time, enabling post-build configuration (ideal for Docker).

Build-time variables are baked into the bundle and require a rebuild to change.

License

MIT

S
Description
Modern JMAP webmail client built for Stalwart Mail Server. Privacy-focused, responsive, with real-time updates.
Readme MIT
6.9 MiB
Languages
TypeScript 99.1%
CSS 0.7%
JavaScript 0.1%