Skip to content

Commit a2aaa66

Browse files
committed
cleanup
1 parent 3bd5950 commit a2aaa66

18 files changed

+359
-167
lines changed

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module.exports = {
2222
'no-underscore-dangle': 'off',
2323
'node/no-unsupported-features/es-builtins': 'off',
2424
'unicorn/prefer-spread': 'off',
25+
'prefer-const': 'error',
2526
},
2627
ignorePatterns: ['*.mjs', '*.cjs'],
2728
}

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# CHANGELOG
22

3+
**v0.1.0-alpha.3:**
4+
- `README.md` cleanup (listing of components)
5+
- `Image` component now requires only `src`; the other params are optional
6+
- `ViewInBrowser` component has changed: text is optional
7+
- npm updates
8+
39
**v0.1.0-alpha.2:**
410
- Introduced `CHANGELOG.md`
511
- npm updates

README.md

+203-14
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
[Templateless](https://templateless.com) lets you generate and send transactional emails quickly and easily so you can focus on building your product.
2626

27+
It's perfect for SaaS, web apps, mobile apps, scripts and anywhere you have to send email programmatically.
28+
2729
## ✨ Features
2830

2931
- 👋 **Anti drag-and-drop by design** — emails are a part of your code
@@ -48,14 +50,24 @@ Or npm:
4850
npm install --save templateless-js
4951
```
5052

53+
## 🔑 Get Your API Key
54+
55+
You'll need an API key for the example below ⬇️
56+
57+
[![Get Your API Key](https://img.shields.io/badge/Get_Your_API_Key-free-blue?style=for-the-badge)](https://app.templateless.com/)
58+
59+
- 3,000 emails per month
60+
- All popular email provider integrations
61+
- Start sending right away
62+
5163
## 👩‍💻 Quick example
5264

5365
This is all it takes to send a signup confirmation email:
5466

5567
```javascript
5668
import { Content, Email, EmailAddress, Templateless } from 'templateless-js'
5769

58-
;(async () => {
70+
const sendEmail = async () => {
5971
const content = Content
6072
.builder()
6173
.text('Hi, please **confirm your email**:')
@@ -73,27 +85,204 @@ import { Content, Email, EmailAddress, Templateless } from 'templateless-js'
7385
const result = await templateless.send(email)
7486

7587
console.log(result)
76-
})()
88+
}
89+
90+
sendEmail()
7791
```
7892

79-
> **Note**
80-
> 🚧 **This SDK is not stable yet.** The API might change as more features are added. Please pay attention to the [CHANGELOG](CHANGELOG.md) for breaking changes.
93+
There are more C# examples in the [examples](examples) folder ✨
94+
95+
> [!NOTE]
96+
> 🚧 **The SDK is not stable yet.** This API might change as more features are added. Please watch the repo for the changes in the [CHANGELOG](CHANGELOG.md).
97+
98+
## 🔳 Components
99+
100+
Emails are crafted programmatically by making function calls. There's no dealing with HTML or drag-and-drop builders.
101+
102+
All of the following components can be mixed and matched to create dynamic emails:
81103

82-
Examples:
104+
<details>
105+
<summary>Text / Markdown</summary>
83106

84-
1. Get your **free API key** here: <https://app.templateless.com>
85-
1. There are more JavaScript examples in the [examples](examples) folder
107+
Text component allow you to insert a paragraph. Each paragraph supports basic markdown:
86108

87-
```bash
88-
TEMPLATELESS_API_KEY=<Your API Key> \
89-
TEMPLATELESS_EMAIL_ADDRESS=<Your Own Email Address> \
90-
node examples/simple
109+
- Bold text: `**bold text**`
110+
- Italic text: `_italic text_`
111+
- Link: `[link text](https://example.com)`
112+
- Also a link: `<https://example.com>`
113+
- Headers (h1-h6):
114+
115+
- `# Big Header`
116+
- `###### Small Header`
117+
118+
- Unordered list:
119+
120+
```md
121+
- item one
122+
- item two
123+
- item three
91124
```
92125

126+
- Ordered list:
127+
128+
```md
129+
1. item one
130+
1. item two
131+
1. item three
132+
```
133+
134+
```javascript
135+
Content.builder()
136+
.text("## Thank you for signing up")
137+
.text("Please **verify your email** by [clicking here](https://example.com/confirm?token=XYZ)")
138+
.build()
139+
```
140+
141+
</details>
142+
<details><summary>Link</summary>
143+
144+
Link component adds an anchor tag. This is the same as a text component with the link written in markdown:
145+
146+
```javascript
147+
Content.builder()
148+
.link("Confirm Email", "https://example.com/confirm?token=XYZ") // or...
149+
.text("[Confirm Email](https://example.com/confirm?token=XYZ)")
150+
.build()
151+
```
152+
153+
</details>
154+
<details><summary>Button</summary>
155+
156+
Button can also be used as a call to action. Button color is set via your dashboard's app color.
157+
158+
```javascript
159+
Content.builder()
160+
.button("Confirm Email", "https://example.com/confirm?token=XYZ")
161+
.build()
162+
```
163+
164+
</details>
165+
<details><summary>Image</summary>
166+
167+
Image component will link to an image within your email. Keep in mind that a lot of email clients will prevent images from being loaded automatically for privacy reasons.
168+
169+
```javascript
170+
Content.builder()
171+
.image(
172+
"https://placekitten.com/300/200", // where the image is hosted
173+
"https://example.com", // [optional] link url, if you want it to be clickable
174+
300, // [optional] width
175+
200, // [optional] height
176+
"Alt text" // [optional] alternate text
177+
)
178+
.build()
179+
```
180+
181+
Only the `src` parameter is required; everything else is optional.
182+
183+
**If you have "Image Optimization" turned on:**
184+
185+
1. Your images will be cached and distributed by our CDN for faster loading. The cache does not expire. If you'd like to re-cache, simply append a query parameter to the end of your image url.
186+
1. Images will be converted into formats that are widely supported by email clients. The following image formats will be processed automatically:
187+
188+
- Jpeg
189+
- Png
190+
- Gif
191+
- WebP
192+
- Tiff
193+
- Ico
194+
- Bmp
195+
- Svg
196+
197+
1. Maximum image size is 5MB for free accounts and 20MB for paid accounts.
198+
1. You can specify `width` and/or `height` if you'd like (they are optional). Keep in mind that images will be scaled down to fit within the email theme, if they're too large.
199+
200+
</details>
201+
<details><summary>One-Time Password</summary>
202+
203+
OTP component is designed for showing temporary passwords and reset codes.
204+
205+
```javascript
206+
Content.builder()
207+
.text("Here's your **temporary login code**:")
208+
.otp("XY78-2BT0-YFNB-ALW9")
209+
.build()
210+
```
211+
212+
</details>
213+
<details><summary>Social Icons</summary>
214+
215+
You can easily add social icons with links by simply specifying the username. Usually, this component is placed in the footer of the email.
216+
217+
These are all the supported platforms:
218+
219+
```javascript
220+
Content.builder()
221+
.socials([
222+
new SocialItem(Service.Website, 'https://example.com'),
223+
new SocialItem(Service.Email, '[email protected]'),
224+
new SocialItem(Service.Phone, '123-456-7890'), // `tel:` link
225+
new SocialItem(Service.Facebook, 'ExampleApp'),
226+
new SocialItem(Service.YouTube, 'ChannelID'),
227+
new SocialItem(Service.Twitter, 'ExampleApp'),
228+
new SocialItem(Service.X, 'ExampleApp'),
229+
new SocialItem(Service.GitHub, 'ExampleApp'),
230+
new SocialItem(Service.Instagram, 'ExampleApp'),
231+
new SocialItem(Service.LinkedIn, 'ExampleApp'),
232+
new SocialItem(Service.Slack, 'Org'),
233+
new SocialItem(Service.Discord, 'ExampleApp'),
234+
new SocialItem(Service.TikTok, 'ExampleApp'),
235+
new SocialItem(Service.Snapchat, 'ExampleApp'),
236+
new SocialItem(Service.Threads, 'ExampleApp'),
237+
new SocialItem(Service.Telegram, 'ExampleApp'),
238+
])
239+
.build()
240+
```
241+
242+
</details>
243+
<details><summary>View in Browser</summary>
244+
245+
If you'd like your recipients to be able to read the email in a browser, you can add the "view in browser" component that will automatically generate a link. Usually, this is placed in the header or footer of the email.
246+
247+
You can optionally provide the text for the link. If none is provided, default is used: "View in browser"
248+
249+
**This will make the email public to anyone that has access to the link.**
250+
251+
```javascript
252+
Content.builder()
253+
.viewInBrowser("Read Email in Browser")
254+
.build()
255+
```
256+
257+
</details>
258+
259+
---
260+
261+
Components can be placed in the header, body and footer of the email. Header and footer styling is usually a bit different from the body (for example the text is smaller).
262+
263+
```javascript
264+
const header = Header.builder() // header of the email
265+
.text("Smaller text")
266+
.build()
267+
268+
const content = Content.builder() // body of the email
269+
.text("Normal text")
270+
.build()
271+
```
272+
273+
Currently there are 2 themes to choose from: `Theme.Unstyled` and `Theme.Simple`
274+
275+
```javascript
276+
const content = Content.builder()
277+
.theme(Theme.Simple)
278+
.text("Hello world")
279+
.build()
280+
```
281+
93282
## 🤝 Contributing
94283

95-
- Contributions are more than welcome <3
96-
- Please **star this repo** for more visibility
284+
- Contributions are more than welcome
285+
- Please **star this repo** for more visibility <3
97286

98287
## 📫 Get in touch
99288

@@ -103,7 +292,7 @@ Examples:
103292

104293
- For feature requests, please [start a discussion](https://github.com/templateless/templateless-javascript/discussions)
105294
- Found a bug? [Open an issue!](https://github.com/templateless/templateless-javascript/issues)
106-
- We are also on Twitter: [@Templateless](https://twitter.com/templateless)
295+
- Say hi [@Templateless](https://twitter.com/templateless) 👋
107296

108297
## 🍻 License
109298

dist/bundle.cjs.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/bundle.esm.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/bundle.umd.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/collection.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ declare class CollectionBuilder {
1313
otp(text: string): this;
1414
socials(data: SocialItem[]): this;
1515
text(text: string): this;
16-
viewInBrowser(text: string): this;
16+
viewInBrowser(text?: string): this;
1717
build(): Collection;
1818
private push;
1919
}

dist/components/image.d.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { ComponentId } from '../common';
22
export declare class Image implements Component {
33
id: ComponentId;
44
src: string;
5-
alt: string;
6-
width: number;
7-
height: number;
8-
url: string;
9-
constructor(src: string, alt: string, width: number, height: number, url: string);
5+
alt?: string;
6+
width?: number;
7+
height?: number;
8+
url?: string;
9+
constructor(src: string, alt?: string, width?: number, height?: number, url?: string);
1010
}
1111
interface Component {
1212
}

dist/components/viewInBrowser.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { ComponentId } from '../common';
22
export declare class ViewInBrowser implements Component {
33
id: ComponentId;
4-
text: string;
5-
constructor(text: string);
4+
text?: string;
5+
constructor(text?: string);
66
}
77
interface Component {
88
}

dist/content.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ declare class ContentBuilder {
2828
otp(text: string): this;
2929
socials(data: SocialItem[]): this;
3030
text(text: string): this;
31-
viewInBrowser(text: string): this;
31+
viewInBrowser(text?: string): this;
3232
build(): Content;
3333
private push;
3434
}

examples/confirm_email/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import {
1111
} from 'templateless-js'
1212

1313
const sendEmail = async () => {
14-
let api_key = process.env.TEMPLATELESS_API_KEY
14+
const api_key = process.env.TEMPLATELESS_API_KEY
1515
if (!api_key) {
1616
console.error('Set TEMPLATELESS_API_KEY to your Templateless API key')
1717
return
1818
}
1919

20-
let email_address = process.env.TEMPLATELESS_EMAIL_ADDRESS
20+
const email_address = process.env.TEMPLATELESS_EMAIL_ADDRESS
2121
if (!email_address) {
2222
console.error('Set TEMPLATELESS_EMAIL_ADDRESS to your own email address')
2323
return

examples/simple/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import 'dotenv/config'
22
import { Content, Email, EmailAddress, Templateless } from 'templateless-js'
33

44
const sendEmail = async () => {
5-
let api_key = process.env.TEMPLATELESS_API_KEY
5+
const api_key = process.env.TEMPLATELESS_API_KEY
66
if (!api_key) {
77
console.error('Set TEMPLATELESS_API_KEY to your Templateless API key')
88
return
99
}
1010

11-
let email_address = process.env.TEMPLATELESS_EMAIL_ADDRESS
11+
const email_address = process.env.TEMPLATELESS_EMAIL_ADDRESS
1212
if (!email_address) {
1313
console.error('Set TEMPLATELESS_EMAIL_ADDRESS to your own email address')
1414
return

0 commit comments

Comments
 (0)