npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@snugdesk/email-widget

v0.3.3

Published

Self-contained email widget for Angular Apps - Powered by Snugdesk

Readme

Snugdesk - Email Widget for Angular

A production-ready Angular library that embeds a complete email client inside your web application. The widget handles authentication, mailbox discovery, conversation threading, rich-text composing, templates with placeholders, signatures, attachments, real-time updates, and light/dark theming out of the box — in one component tag.

To purchase licenses or to get implementation assistance, reach out to:

SNUG Technologies Pvt Ltd
📧 [email protected]


✅ Requirements

  • Angular 21.0.0+ (matches the published peer dependency range)
  • @snugdesk/core 0.2.39+
  • Angular Material 21.0.0+ and CKEditor 5 (ckeditor5 43+, @ckeditor/ckeditor5-angular 9+)
  • A licensed Snugdesk tenant with access to the Email channel, with at least one mailbox configured

📦 Installation

Install the core runtime first (all Snugdesk widgets depend on it), then add the email widget and its editor peers.

npm install @snugdesk/core
npm install @snugdesk/email-widget
npm install @angular/material @angular/cdk
npm install ckeditor5 @ckeditor/ckeditor5-angular

Other runtime dependencies are bundled (moment-timezone, ngx-skeleton-loader, …).


🛠 Workspace Configuration (required)

The AWS SDK for JavaScript (v3) expects Node-style globals (global, process) to exist. Add the following once in your host application:

  1. Create src/custom-polyfills.ts

    // src/custom-polyfills.ts
    (window as any).global = window;
    (window as any).process = { env: { DEBUG: undefined } };

    Keep additional polyfills above if your app already uses this file.

  2. Register the polyfill file in angular.json

    {
      "projects": {
        "your-app": {
          "architect": {
            "build": {
              "options": {
                "polyfills": [
                  "zone.js",
                  "src/custom-polyfills.ts"
                ]
              }
            },
            "test": {
              "options": {
                "polyfills": [
                  "zone.js",
                  "zone.js/testing",
                  "src/custom-polyfills.ts"
                ]
              }
            }
          }
        }
      }
    }
  3. Let TypeScript know about the polyfill file

    Add the file to the files array in both tsconfig.app.json and tsconfig.spec.json:

    {
      "files": [
        "src/custom-polyfills.ts"
      ]
    }
  4. Raise the build budgets

    The rich-text editor and cloud SDK make the initial bundle larger than the Angular defaults. In the production configuration of angular.json:

    "budgets": [
      { "type": "initial", "maximumWarning": "4MB", "maximumError": "8MB" }
    ]

These changes ensure the widget (and its client libraries) run reliably in both builds and tests.


⚙️ Angular Setup

Standalone-bootstrapped apps

The widget component is not an Angular standalone component — it is exported by EmailWidgetModule. In a standalone-bootstrapped app you make it available by importing the module into whichever component renders the widget (standalone components can import NgModules).

  1. Provide animations and HttpClient at bootstrap (main.ts)

    import { bootstrapApplication } from '@angular/platform-browser';
    import { provideAnimations } from '@angular/platform-browser/animations';
    import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
    import { AppComponent } from './app/app.component';
    
    bootstrapApplication(AppComponent, {
      providers: [
        provideAnimations(),
        provideHttpClient(withInterceptorsFromDi()),
      ]
    });
  2. Import EmailWidgetModule in the consuming standalone component

    import { Component } from '@angular/core';
    import { EmailWidgetModule } from '@snugdesk/email-widget';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [EmailWidgetModule],
      templateUrl: './app.component.html',
    })
    export class AppComponent {}

    Without this import the <snugdesk-email-widget> element will not be recognised.

NgModule-based apps

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { EmailWidgetModule } from '@snugdesk/email-widget';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, HttpClientModule, EmailWidgetModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

🔐 Authentication Workflow

The widget takes a session token, establishes a session with SnugdeskAuthenticationService from @snugdesk/core, and then discovers the tenant, the signed-in user, the mailboxes, and the message templates on its own. token is the only credential you pass.

Step 1 — Create an integration credential (once, as a tenant administrator)

POST /tenants/{tenantId}/api-credentials
Authorization: Bearer <your Snugdesk session token>

The response returns the credential exactly once. Store it in your backend's secret store — never in browser code, since anything the page can read, so can its visitors.

Step 2 — Issue a session token from your server, per agent session

POST /auth/library
Authorization: Bearer <keyId>.<secret>
{ "userId": "<agent user id>" }

This returns a short-lived sessionToken.

Step 3 — Pass that token to the widget

import { Component } from '@angular/core';

@Component({
  selector: 'my-component',
  templateUrl: './my-component.html'
})
export class InboxShellComponent {
  token = 'session-token-issued-by-your-backend';
}
<snugdesk-email-widget [token]="token"></snugdesk-email-widget>

Refresh the token from your backend before it expires, the same way you issued it.

Inputs

  • token (required) – Snugdesk session token from POST /auth/library. The widget calls authenticate(...) with it and derives the tenant and user from the session.
  • mode (optional)'Standalone' or 'Embedded'. Defaults to 'Standalone'. See Widget Modes.
  • theme (optional)'light' or 'dark'. Defaults to 'light'.
  • entityId (required in Embedded mode) – Scopes the inbox to a single contact or record, so only that entity's email threads are listed.
  • entityEmail (optional) – In Embedded mode, pre-fills the To field when the agent composes a new email.
  • tenantId, userId (deprecated) – Still accepted so existing markup keeps compiling, but ignored: both are read from the authenticated session. Safe to remove.

The widget shows a loading state until the session resolves, and an authentication message if it does not. Give its container a real height — the widget fills 100% of the space you allocate.


🧭 Widget Modes

The widget supports two modes: Standalone and Embedded. Use the mode input to choose how the UI behaves.

Standalone mode (default)

  • A full-page, two-panel inbox: conversation list on the left, thread or composer on the right.
  • Lists every email conversation for the session's tenant.
  • Automatically switches to the drill-down layout on phones and narrow screens.
<snugdesk-email-widget [token]="token"></snugdesk-email-widget>

Embedded mode

  • A single-column, drill-down layout designed for a side panel next to a CRM record, ticket, or contact page.
  • Requires entityId; pass entityEmail to pre-fill new emails to that contact.
<snugdesk-email-widget
  [token]="token"
  mode="Embedded"
  theme="dark"
  [entityId]="contact.id"
  [entityEmail]="contact.email">
</snugdesk-email-widget>

🎨 Assets & Styling

The library ships a single theme stylesheet that provides the Angular Material base theme, CKEditor 5 styles, the Open Sans font, Material Icons, the widget layout, and all colour variables. Import it once in your global stylesheet:

/* src/styles.css */
@import "@snugdesk/email-widget/src/lib/styles/email-widget-theme.css";

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
}

Brand colours

Override any of the widget's CSS variables in your own :root block after the import to match your product's brand:

:root {
  --app-color: #ff6633;          /* primary accent */
  --app-color-dark: #ff5805;     /* hover / active accent */
  --app-color-light: #fe8c66;

  --background-color: #ffffff;
  --border-color: #c9c9c9;
  --text-color: #666;
  --text-color-dark: #333;

  --text-font-family: "Open Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}

Dark mode

Dark mode ships with the theme — set theme="dark" on the component and the entire widget, including the composer and dialogs, repaints to a dark palette. Incoming emails are always rendered in their light styling so third-party marketing mail never renders half-darkened.


✨ Feature Highlights

Inbox

  • Two-panel inbox with conversation list, threaded reader, and composer
  • Real-time updates — new and updated conversations appear at the top of the list without a refresh
  • Infinite-scroll history with skeleton loading states
  • Instant search across subject, sender name, and email address — matches in the loaded list appear as you type, and the server is queried for older conversations that have not been loaded yet
  • Advanced filters: sender (with address auto-suggestions), subject, and a date range — within the last day, 3 days, week, 2 weeks, month, or on a specific date
  • Gmail-style sender avatars, relative timestamps, and message previews
  • Contact-scoped mode that shows only one record's email history

Reading

  • Full conversation threading, with the latest message expanded and older ones collapsed to a snippet
  • Faithful, safely-sanitised rendering of HTML emails, including marketing mail and Office-pasted content
  • Plain-text emails rendered with automatic link detection
  • Attachment gallery with file-type icons, image thumbnails, and one-click download
  • Built-in preview for images and PDFs, without leaving the widget

Composing

  • Rich-text editor with bold, italic, underline, strikethrough, lists, indentation, font size, text and highlight colours, alignment, links, images, and tables
  • Reply, Reply All, and Forward — inline at the bottom of the thread, with recipients, subject, and quoted history pre-filled
  • Chip-based To / Cc / Bcc fields that accept comma, semicolon, Enter, or Tab
  • Send-as mailbox picker when the tenant has more than one email address configured
  • Per-mailbox signatures, inserted automatically and swapped when the sender changes
  • Drag-in images, inline pasting, and image resizing inside the message body
  • Email-safe HTML output, so messages render correctly in Outlook, Gmail, and Apple Mail
  • Reliable resend: retrying a failed send delivers the same email rather than a duplicate

Templates

  • Browse and search the tenant's approved message templates
  • {{placeholder}} fields filled inline, with defaults and a live preview before insertion
  • Subject and body applied together, without disturbing the signature

Attachments

  • Up to 10 files and 25 MB per email
  • Large attachments upload directly to secure cloud storage, so big files send as reliably as small ones
  • Clear file size feedback and per-file removal before sending

Presentation

  • Standalone and Embedded modes
  • Light and dark themes, plus a configurable accent colour
  • Fully responsive down to phone widths, with a drill-down list → thread flow

📜 Release Notes

0.2.6 – 0.2.8 — Aug 2026

  • Revamped inbox UI across the conversation list, thread header, and composer.
  • Advanced search. Search now reaches conversations that have not been loaded into the list yet, with filters for sender, subject, and date range, plus sender auto-suggestions.
  • Token-only authentication. The widget derives the tenant and user from the session token; the tenantId and userId inputs are ignored.
  • Fixed a scrolling issue in the conversation list.
  • Trimmed the published package contents.

0.2.5 — Aug 2026

  • Angular 21 support across the widget and its Material and editor peers.
  • Reliable resend — if a send fails on a flaky connection, pressing Send again delivers the same email instead of a second copy.

0.2.3 – 0.2.4 — May 2026

  • Fully responsive UI. The inbox collapses to a drill-down list → thread flow on tablets and phones, with a Back to list action.
  • Dark theme across the list, thread, composer, template picker, and attachment preview.
  • Layout and spacing polish throughout the conversation list and thread header.

0.2.1 – 0.2.2 — May 2026

  • Embedded mode. Scope the inbox to a single contact or record with entityId, and pre-fill new emails with entityEmail — ideal for a CRM side panel.
  • Switching records resets the panel cleanly instead of carrying the previous thread over.

0.2.0 — Mar 2026

  • Published as a standalone library, independent of the Snugdesk application.
  • CKEditor 5 composer replacing the earlier editor: tables, image resizing, font colours, and paste-from-Office support.
  • Large attachments — files beyond the inline limit upload directly to secure cloud storage, lifting the practical ceiling to 25 MB per email.
  • Attachment preview dialog for images and PDFs.

0.1.0 – 0.1.3 — Mar 2026

  • First public releases of the email client: conversation list, threaded reader, composer, reply/reply-all/forward, and real-time updates.
  • Template enhancements — inline placeholder filling with defaults and a live preview.
  • Fixed link rendering inside email bodies, plus assorted layout fixes.

🛠 Troubleshooting & Tips

  • Nothing renders / the widget is invisible. The widget fills its container — make sure the parent element has an explicit height (the demo uses height: 100% on html, body).
  • <snugdesk-email-widget> is not a known element. Import EmailWidgetModule into the component that renders it, not only into main.ts.
  • "Authentication failed" instead of the inbox. The token is missing, expired, or was issued for a different tenant — re-issue it from your backend via POST /auth/library.
  • Unstyled or icon-less UI. Confirm the theme stylesheet import in your global styles.css — it carries the fonts, Material theme, and editor styles.
  • Build fails on bundle size. Raise the initial budget as shown in Workspace Configuration.
  • No sender address in the composer. At least one active mailbox must be configured for the tenant's Email channel in Snugdesk.
  • Upgrade the widget in lockstep with your Angular major version to stay within the supported peer dependency range (>=21.0.0).

📬 Support

Need help with deployment, theming, or backend setup?

SNUG Technologies Pvt Ltd
📧 [email protected]

Include your tenant name, Angular version, and a summary of the issue so the support team can assist quickly.