{"id":26279281,"url":"https://github.com/steveninety/svelte-email-tailwind","last_synced_at":"2025-07-26T12:12:58.998Z","repository":{"id":206797410,"uuid":"717703921","full_name":"steveninety/svelte-email-tailwind","owner":"steveninety","description":"Code, preview and test-send email templates with Svelte and Tailwind classes and render them to HTML or plain text.","archived":false,"fork":false,"pushed_at":"2025-06-22T10:20:09.000Z","size":877,"stargazers_count":61,"open_issues_count":4,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-24T22:37:07.038Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Svelte","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/steveninety.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-11-12T10:13:59.000Z","updated_at":"2025-07-20T21:54:05.000Z","dependencies_parsed_at":"2023-11-14T08:41:59.190Z","dependency_job_id":"80daeb89-9b2c-4b61-b277-1833bba790ec","html_url":"https://github.com/steveninety/svelte-email-tailwind","commit_stats":null,"previous_names":["steveninety/svelte-email-tailwind"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/steveninety/svelte-email-tailwind","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steveninety%2Fsvelte-email-tailwind","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steveninety%2Fsvelte-email-tailwind/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steveninety%2Fsvelte-email-tailwind/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steveninety%2Fsvelte-email-tailwind/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/steveninety","download_url":"https://codeload.github.com/steveninety/svelte-email-tailwind/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steveninety%2Fsvelte-email-tailwind/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267164394,"owners_count":24045820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-26T02:00:08.937Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-14T14:01:14.490Z","updated_at":"2025-07-26T12:12:58.928Z","avatar_url":"https://github.com/steveninety.png","language":"Svelte","funding_links":[],"categories":["Svelte"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\u003cstrong\u003eSvelte Email Tailwind\u003c/strong\u003e\u003c/div\u003e\n\u003cdiv align=\"center\"\u003eDevelop emails easily in Svelte using Tailwind.\u003c/div\u003e\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n\u003ca href=\"https://github.com/steveninety/svelte-email-tailwind\"\u003eDocumentation / GitHub\u003c/a\u003e \n\u003c/div\u003e\n\n# Introduction\n\nSVELTE 5 COMPATIBLE since version 2.0.0!\n\n`svelte-email-tailwind` enables you to code, preview and test-send email templates with Svelte and Tailwind classes and render them to HTML or plain text.\n\n- This package adds a Tailwind post-processor to the original [svelte-email](https://github.com/carstenlebek/svelte-email) package.\n- Tailwind classes are converted to inline styles on built-time using a Vite plugin.\n- In earlier versions, this process took place every time an email was sent (not very efficient).\n- This package also provides a Svelte preview component, including utility functions for the server (SvelteKit only).\n\n# Installation\n\nInstall the package to your existing Svelte + Vite or SvelteKit project:\n\n```bash title=\"npm\"\nnpm install svelte-email-tailwind\n```\n\n```bash title=\"pnpm\"\npnpm install svelte-email-tailwind\n```\n\n# Getting started\n\n## 1. Configure Vite\n\nImport the svelteEmailTailwind Vite plugin, and pass it into the config's `plugins` array.\n\n`vite.config.ts`\n\n```ts\nimport { sveltekit } from '@sveltejs/kit/vite';\nimport type { UserConfig } from 'vite';\nimport svelteEmailTailwind from 'svelte-email-tailwind/vite';\n\nconst config: UserConfig = {\n\tplugins: [\n\t\tsveltekit(),\n\t\tsvelteEmailTailwind() // processes .svelte files inside the default '/src/lib/emails' folder\n\t]\n};\n\nexport default config;\n```\n\nOptional configurations:\n\n- Provide a Tailwind config;\n- Provide a custom path to your email folder.\n\n```js\nimport { sveltekit } from '@sveltejs/kit/vite';\nimport type { UserConfig } from 'vite';\nimport type { TailwindConfig } from 'tw-to-css';\nimport svelteEmailTailwind from 'svelte-email-tailwind/vite';\n\nconst emailTwConfig: TailwindConfig = {\n\ttheme: {\n\t\tscreens: {\n\t\t\tmd: { max: '767px' },\n\t\t\tsm: { max: '475px' }\n\t\t},\n\t\textend: {\n\t\t\tcolors: {\n\t\t\t\tbrand: 'rgb(255, 62, 0)'\n\t\t\t}\n\t\t}\n\t}\n};\n\nconst config: UserConfig = {\n\tplugins: [\n\t\tsveltekit(),\n\t\tsvelteEmailTailwind({\n\t\t\ttailwindConfig: emailTwConfig,\n\t\t\tpathToEmailFolder: '/src/lib/components/emails' // defaults to '/src/lib/emails'\n\t\t})\n\t]\n};\n\nexport default config;\n```\n\n## 2. Create an email using Svelte\n\n`src/lib/emails/Hello.svelte`\n\n```svelte\n\u003cscript\u003e\n\timport { Button, Hr, Html, Text, Head } from 'svelte-email-tailwind';\n\n\texport let name = 'World';\n\u003c/script\u003e\n\n\u003cHtml lang=\"en\"\u003e\n\t\u003cHead /\u003e\n\t\u003cText class=\"md:text-[18px] text-[24px]\"\u003e\n\t\tHello, {name}!\n\t\u003c/Text\u003e\n\t\u003cHr /\u003e\n\t\u003cButton href=\"https://svelte.dev\"\u003eVisit Svelte\u003c/Button\u003e\n\u003c/Html\u003e\n```\n\n## 3. Render \u0026 send an email\n\nThis example uses [Resend](https://resend.com/docs/send-with-nodejs) to send the email. You can use any other email service provider (Nodemailer, SendGrid, Postmark, AWS SES...).\n\n`src/routes/emails/hello/+server.ts`\n\n```ts\nimport { render } from 'svelte/server';\n// import { renderAsPlainText } from 'svelte-email-tailwind';\nimport type { ComponentProps } from 'svelte';\nimport type HelloProps from 'src/lib/emails/Hello.svelte';\nimport Hello from 'src/lib/emails/Hello.svelte';\nimport { PRIVATE_RESEND_API_KEY } from '$env/static/private';\nimport { Resend } from 'resend';\n\nconst componentProps: ComponentProps\u003cHelloProps\u003e = {\n\tname: 'Steven'\n};\n\nconst { html } = render(Hello, { props: componentProps });\n// Alternatively, render your email as plain text:\n// const plainText = renderAsPlainText(html);\n\nconst resend = new Resend(PRIVATE_RESEND_API_KEY);\n\n// Send the email using your provider of choice.\nresend.emails.send({\n\tfrom: 'you@example.com',\n\tto: 'user@gmail.com',\n\tsubject: 'Hello',\n\thtml: html\n\t// Or send your plain text:\n\t// html: plainText\n});\n```\n\n# Previewing \u0026 test-sending emails in development (SvelteKit)\n\nUsing a designated route, you can preview all your dynamically retrieved email components.\nThis means you'll be able to preview your emails with the exact markup that eventually lands an inbox (unless of course, the email provider manipulates it behind the scenes).\n\n![svelte-email-tailwind-preview-interface](https://raw.githubusercontent.com/steveninety/svelte-email-tailwind/main/static/interface.jpg)\n\nTo get started...\n\n## 1. Configure a route\n\nImport the PreviewInterface component and pass in the server data as a prop. Customize the email address.\n\n`src/routes/email-previews/+page.svelte`\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n\timport PreviewInterface from 'svelte-email-tailwind/preview/PreviewInterface.svelte';\n\texport let data;\n\u003c/script\u003e\n\n\u003cPreviewInterface {data} email=\"name@example.com\" /\u003e\n```\n\n## 2. Configure the server for this route\n\nReturn the email component file list from SvelteKit's `load` function using the `emailList` function.\nIn SvelteKit's `form actions`, pass in `createEmail` (loads files from the server), and `sendEmail` (sends test-emails).\n\n`src/routes/email-previews/+page.server.ts`\n\n```ts\nimport { createEmail, emailList, sendEmail } from 'svelte-email-tailwind/preview';\nimport { PRIVATE_RESEND_API_KEY } from '$env/static/private';\n\nexport async function load() {\n\t// return the list of email components\n\treturn emailList();\n}\n\nexport const actions = {\n\t// Pass in the two actions. Provide your Resend API key.\n\t...createEmail,\n\t...sendEmail({ resendApiKey: PRIVATE_RESEND_API_KEY })\n};\n```\n\nOptional configurations:\n\n- Provide a custom path to your email components;\n- Provide a custom function to send the email using a different provider.\n\n```ts\nimport {\n\tcreateEmail,\n\temailList,\n\tsendEmail,\n\tSendEmailFunction\n} from 'svelte-email-tailwind/preview';\nimport nodemailer from 'nodemailer';\n\nexport async function load() {\n\t// Customize the path to your email components.\n\treturn emailList({ path: '/src/lib/components/emails' });\n}\n\n// Make sure your custom 'send email' function is of type 'SendEmailFunction'.\nconst sendUsingNodemailer: typeof SendEmailFunction = async ({ from, to, subject, html }) =\u003e {\n\tconst transporter = nodemailer.createTransport({\n\t\thost: 'smtp.ethereal.email',\n\t\tport: 587,\n\t\tsecure: false,\n\t\tauth: {\n\t\t\tuser: 'my_user',\n\t\t\tpass: 'my_password'\n\t\t}\n\t});\n\n\tconst sent = await transporter.sendMail({ from, to, subject, html });\n\n\tif (sent.error) {\n\t\treturn { success: false, error: sent.error };\n\t} else {\n\t\treturn { success: true };\n\t}\n};\n\nexport const actions = {\n\t...createEmail,\n\t// Pass in your custom 'send email' function.\n\t...sendEmail({ customSendEmailFunction: sendUsingNodemailer })\n};\n```\n\n## 3. Start developing your emails via the route you've chosen.\n\nExample: http://localhost:5173/email-previews\n\n# Components\n\nA set of standard components to help you build amazing emails without having to deal with the mess of creating table-based layouts and maintaining archaic markup.\n\n- HTML\n- Head\n- Heading\n- Button\n- Link\n- Img\n- Hr\n- Text\n- Container\n- Preview\n- Body\n- Column\n- Section\n- Row\n- Custom\n\n# HEADS UP! (Limitations \u0026 Syntax requirements)\n\n## Limitations \u0026 Syntax requirements\n\n- Always include the `\u003cHead /\u003e` component.\n- For now, class attribute/prop interpolation/variable references will not work (this won't work: `class={someTwClassName}`, `class={`${someTwClassName} w-full`}`, this will work: `class=\"w-full\"`).\n- When using arbitrary Tailwind classes that use multiple values, separate them using underscores (example: p-[0_30px_12px_5px]).\n- In Svelte email components, stick to the designated components if you use Tailwind classes. If you need custom HTML, use the `\u003cCustom /\u003e` component and the \"as\" property to define the tag. This component defaults to a `\u003cdiv/\u003e`. Tailwind classes on regular html nodes will not be processed.\n- There are ultra-rare cases where the text inside your email component results in syntax errors under the hood. This could happen when you're using code characters such as brackets, or certain strings that break the Vite script. This would require you to change up your text content.\n\n## Ignore \"node_invalid_placement_ssr\" warnings\n\n`node_invalid_placement_ssr: `\u003chtml\u003e` (src/lib/components/Html.svelte:12:0) needs a valid parent element\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.`\n\nYou can ignore these warnings, because Svelte thinks you're building for the web and doesn't know you're building emails - so the warnings are not applicable.\n\n# Author\n\n- Steven Polak\n\n## Author of the original Svelte Email package\n\n- Carsten Lebek ([@carstenlebek](https://twitter.com/carstenlebek1))\n\n### Authors of the original project [react-email](https://github.com/resendlabs/react-email)\n\n- Bu Kinoshita ([@bukinoshita](https://twitter.com/bukinoshita))\n- Zeno Rocha ([@zenorocha](https://twitter.com/zenorocha))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteveninety%2Fsvelte-email-tailwind","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsteveninety%2Fsvelte-email-tailwind","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteveninety%2Fsvelte-email-tailwind/lists"}