Skip to main content

stacks-mail

Use when creating mail classes in app/Mail/ - defining email content and templates, using the template() function with STX or HTML templates, variable interpolation, email layouts, or the app-level mail sending pattern. For the email framework itself (drivers, Mail singleton, EmailSDK, inbox management), see stacks-email.

来源信息

仓库
stacksjs/stacks
最近来源活动
2026年9月29日 05:55
检测到的 SKILL.md 语言
英语
星标
631
分支
20

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
stacks-mail
description
Use when creating mail classes in app/Mail/ - defining email content and templates, using the template() function with STX or HTML templates, variable interpolation, email layouts, or the app-level mail sending pattern. For the email framework itself (drivers, Mail singleton, EmailSDK, inbox management), see stacks-email.
license
MIT
compatibility
Bun >= 1.3.0, TypeScript
allowed-tools
Read Edit Write Bash Grep Glob
# Stacks Mail Classes Application-level email definitions in `app/Mail/`. ## Key Paths - Application mail: `app/Mail/` - Email templates: `resources/emails/` (or `storage/framework/defaults/resources/emails/`) - Email layouts: `storage/framework/defaults/resources/emails/layouts/` ## Creating a Mail Class ```typescript // app/Mail/WelcomeEmail.ts import { mail, template } from '@stacksjs/email' import { config } from '@stacksjs/config' interface WelcomeEmailOptions { to: string name: string } export async function sendWelcomeEmail({ to, name }: WelcomeEmailOptions) { const { html, text } = await template('welcome', { variables: { name, appName: config.app.name }, layout: 'default' }) await mail.send({ from: { name: config.app.name, address: config.email.from.address }, to, subject: `Welcome to ${config.app.name}!`, html, text }) } ``` ## Template Rendering ```typescript import { template, renderHtml, templateExists, listTemplates } from '@stacksjs/email' // From template file (welcome.stx or welcome.html) const { html, text } = await template('welcome', { variables: { name: 'John', url: 'https://app.com/verify' }, layout: 'default', // wrap in layout (or false to skip) subject: 'Welcome' }) // From raw HTML const { html, text } = renderHtml('<h1>Hello {{ name }}</h1>', { name: 'John' }) // Check templates templateExists('welcome') // boolean listTemplates() // string[] ``` Variable syntax: `{{ variableName }}` (double braces with spaces). ## Example: Subscription Confirmation ```typescript // app/Mail/SubscriptionConfirmation.ts import { mail, template } from '@stacksjs/email' import { url } from '@stacksjs/router' import { config } from '@stacksjs/config' export async function sendSubscriptionConfirmation({ to, subscriberUuid }: Options) { const { html, text } = await template('subscription-confirmation', { variables: { unsubscribeUrl: url('email.unsubscribe', { token: subscriberUuid }), appName: config.app.name } }) await mail.send({ from: { name: config.app.name, address: config.email.from.address }, to, subject: 'Confirm your subscription', html, text }) } ``` ## Using Mail in Actions/Events ```typescript // In an action import { sendWelcomeEmail } from '../../app/Mail/WelcomeEmail' export default { name: 'SendWelcomeEmail', async handle(event: { email: string, name: string }) { await sendWelcomeEmail({ to: event.email, name: event.name }) return { success: true } } } ``` ## The base design: email components STX templates build on a bundled component library (`defaults/resources/components/Email`), which every bundled template uses and which gives an app a finished look with a few props: ```html <EmailLayout title="Your license key" preheader="Shown after the subject in the inbox" brand="Uplink" brandUrl="https://uplink.example" accent="#f59e0b" footer="You are getting this because you bought Uplink." > <EmailText size="heading">You have Uplink Monthly.</EmailText> <EmailText>Here is your license key.</EmailText> <EmailCode>UPLK-7RKR-Z2BJ-V6QV-4PUH</EmailCode> <EmailButton href="https://uplink.example/activate" bg="#f59e0b" color="#18181b">Activate</EmailButton> <EmailDivider /> <EmailText size="sm">Small print.</EmailText> </EmailLayout> ``` - `<EmailLayout>`: a muted page with one bordered card (a border, not a shadow: Gmail strips shadows), an optional brand header and footer, a hidden `preheader`, and `@media` rules for dark mode and phones on the class hooks the other components carry. Clients that ignore `@media` keep the inline light design. - `<EmailText size="heading|lg|md|sm">`, `<EmailButton>`, `<EmailDivider>`, `<EmailSection>`, `<EmailImage>`, `<EmailLink>`. - `<EmailCode>`: a key or one-time code, large and monospace, selectable in one tap, wrapping at hyphens on a phone. A colour passed as a prop is the template's own choice: that element gets no dark-mode hook. Two stx traps when writing a component or template: never put the literal text of a style tag inside a `<script server>` comment (the parser takes it for one), and write head CSS as a raw string (`{!! css !!}`) rather than a style element, which stx lifts out as component CSS. ## Template Locations - STX templates: `.stx` files processed by STX engine - HTML templates: `.html` files with `{{ }}` variable interpolation - Layouts: base HTML wrapping templates (header, footer, styles) ## Gotchas - Mail classes are plain functions, not classes — no inheritance needed - Templates support both `.stx` (reactive) and `.html` (static) formats - Variable interpolation uses `{{ }}` — not `${}` - `text` output is auto-generated from HTML via `htmlToText()` - Layouts wrap the template content with shared structure (header/footer) - For the email driver system (SES, SendGrid, etc.), see the `stacks-email` skill
在 GitHub 查看