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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@uraniadev/emailer

v0.0.8

Published

An email boilerplate in Svelte5 Tailwindcss and Tw-to-CSS, inspired by @react/email

Downloads

311

Readme

Email Component Library

This is a library for creating structured and styled HTML emails, intended as a transitional resource. Designed for convenience, it allows developers to build and customize emails quickly while encouraging best practices by illustrating the internal composition of emails through self-contained components. Inspired by Resend's @react-email.

This library takes a similar approach to the one applied by pilcrow's to The Copenhagen Book: this library is intended as a learning tool and a starting point. As developers become comfortable with the email structure and utilities provided, they are encouraged to transition toward standalone solutions.


Installation

To install the package, run:

npm install @uraniadev/emailer

Quick Start

This library provides a set of unstyled, modular email components (e.g., Button, Container, Heading) built with Svelte and styled with Tailwind CSS. Components use inline styling through tw-to-css to ensure email compatibility.

Example Usage

Create an email using the provided components:

<!-- src/lib/email.svelte -->
<script>
  import {
    Button,
    Container,
    Heading,
    Image,
    Paragraph
  } from "@uraniadev/emailer";
</script>

<Container>
  <Image src="https://example.org/image-url.jpg" />
  <Heading level={2}>Lorem ipsum dolor sit</Heading>
  <Paragraph>
    Lorem ipsum dolor sit amet consectetur adipisicing elit.
    Maiores veritatis earum, perspiciatis pariatur exercitationem
    illum eligendi amet,deserunt provident ipsum dolore!
    Voluptas mollitia earum temporibus, hic consequatur
    aperiam recusandae.
  </Paragraph>
  <Button href="https://www.example.com">Deserunt</Button>
</Container>

Then render this email in your server-side script:

import Emailer from "@uraniadev/emailer";
import Email from "./email.svelte";

const emailer = new Emailer();

const html = emailer.render(Email, {/* props */});
sendMail(html); // Use your preferred email-sending method

Utility Function: Inline Styling with tw-to-css

This library includes an inline utility that merges Tailwind styles with tw-to-css to create compatible inline styles for emails:

import { inline } from "@uraniadev/emailer";

<p style={inline("text-lg text-pink-500 font-bold")}>
  This is a formatted text
</p>;
// inline() inherith shadcn cn an apply tw-to-css inline:

import type { ClassValue } from "clsx";

import clsx from "clsx";
import { twMerge } from "tailwind-merge";
import { twi } from "tw-to-css";

export function inline(...inputs: ClassValue[]) {
  return twi(twMerge(clsx(inputs)));
}

Components

Button

A link-styled button that accepts class and href attributes. *

<Button class="bg-blue-500 text-white" href="https://example.com">Click Me</Button>

Card

A general-purpose card component for grouping content sections.

<Card class="shadow-lg">This is a card</Card>

Container

A wrapper to align email content and provide consistent padding.

<Container class="max-w-lg">Content goes here</Container>

Heading

A responsive heading element allowing level-based customization.

<Heading level={2}>This is a Heading</Heading>

Image

An image wrapper with optional classes.

<Image src="https://example.com/image.jpg" alt="Image description" />

Paragraph

For general text blocks, styled for readability.

<Paragraph>This is a paragraph of text</Paragraph>

Preview

This is a text snippet that appears under the subject line in the inbox but is hidden from the main email content when it’s opened. *

<Preview content="The preview text of the image, to customize it from the actual mail" />

Repeatable

Generates repeated content, such as lists, from an array. itemsSnippet can be use to stylize the repeated item

<Repeatable items={[1, 2, 3]}>
    {#snippet itemsSnippet(item)}
    <Container>
        <Paragraph>{item.name}</Paragraph>
    </Container>
    {/snippet}
</Repeatable>

API: Emailer Class

Emailer is the primary class used to render emails, taking in a Svelte component and outputting an HTML template. It can be customized by passing configuration options for props, lang, dir, and style.

class Emailer {
  render<T extends Component<any>>(
    component: T,
    props?: ComponentProps<T>,
    config?: HTMLConfig,
  ): string;
}

HTML Boilerplate

The htmlBoilerplate function in the Emailer class generates the complete HTML structure for email content, applying essential styles and configuration for better rendering across email clients. This function wraps the main content (children) in an HTML template, ensuring consistency and compatibility.

Properties

  • props: A set of default styling properties for the html, body, and container elements, configurable via the HTMLConfig type. Each property is an array of style strings, providing styles like background color, text color, and padding.
  • dir: Defines text direction, with the default set to "ltr" (left-to-right). This can be adjusted based on the email's language requirements.
  • lang: Specifies the language of the email content, set to "en" by default for English.
  • style: A global style string that applies custom styling to the entire HTML document, offering flexibility to embed CSS directly within the <style> tag.

Usage in render function

The Emailer.render() method uses htmlBoilerplate to wrap the rendered body of a Svelte component (provided in render as component). The function also accepts:

  • head: Optional custom content or metadata for the <head> section.
  • config: An optional HTMLConfig object to override the default properties, styles, direction, or language settings.

Together, these properties and htmlBoilerplate facilitate the creation of highly customizable, visually consistent email templates with minimal setup.

htmlBoilerplate = (children: string, head?: string, options?: HTMLConfig) => {
  const { props, dir, lang, style } = options ||
    { props: this.props, dir: this.dir, lang: this.lang, style: this.style };
  return `<!doctype html>
    <html ${props?.html.join(" ")} dir=${dir} lang=${lang}>
    <head>
      <style>*{box-sizing:border-box;text-decoration:none;border:0;padding:0;margin:0;}${style}</style>
      ${head || this.head}
    </head>
    <body ${props?.body.join(" ")}>
      <table ${props?.container.join(" ")}>
        <tbody><tr><td>${children}</td></tr></tbody>
      </table>
    <body>
    </html>`;
};

Library Purpose and Long-Term View

The library is structured as an auto-deprecating toolkit for email composition, encouraging developers to understand and apply best practices for maintainable email templates in production. The following approaches are suggested:

  • Component Composition: Understand how each component, such as Container, Button, and Heading, is composed and utilize them to build reusable templates.
  • Self-Managed Rendering: Implement Emailer on your server, simplifying future template updates and adhering to scalable, maintainable practices.

Drawing inspiration from resources like The Copenhagen Book, this library advocates for transparency in development practices and empowers developers to confidently transition to self-maintained code structures.

References and Resources

The following references provide further information on creating HTML emails:


Note: This library is intended as a learning tool and a starting point. As developers become comfortable with the email structure and utilities provided, they are encouraged to transition toward standalone solutions.