├── .eslintignore ├── .eslintrc.cjs ├── .github └── FUNDING.yml ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── package.json ├── pnpm-lock.yaml ├── src ├── app.d.ts ├── app.html ├── fonts │ ├── FiraCode-VF.woff │ ├── FiraCode-VF.woff2 │ ├── Inter-VF.italic-latin.woff2 │ └── Inter-VF.roman-latin.woff2 ├── img │ ├── svelte-horizontal.svg │ └── svelte-logo.svg ├── kit-docs │ └── .gitkeep ├── lib │ ├── _docs │ │ ├── Analytics.svelte │ │ ├── Card.svelte │ │ └── CardGroup.svelte │ ├── _examples │ │ ├── hello.svelte │ │ └── welcome.svelte │ ├── components │ │ ├── Body.svelte │ │ ├── Button.svelte │ │ ├── Column.svelte │ │ ├── Container.svelte │ │ ├── Head.svelte │ │ ├── Heading.svelte │ │ ├── Hr.svelte │ │ ├── Html.svelte │ │ ├── Img.svelte │ │ ├── Link.svelte │ │ ├── Preview.svelte │ │ ├── Section.svelte │ │ └── Text.svelte │ ├── index.ts │ ├── render.ts │ └── utils.ts └── routes │ ├── +layout.js │ ├── +layout.svelte │ ├── +page.js │ ├── +page.svelte │ ├── docs │ ├── +page.js │ ├── +page.svelte │ ├── [...1]overview │ │ └── [...1]svelte-email │ │ │ └── +page.md │ ├── [...2]getting-started │ │ ├── [...1]installation │ │ │ └── +page.md │ │ └── [...2]usage │ │ │ └── +page.md │ ├── [...3]components │ │ ├── [...10]link │ │ │ └── +page.md │ │ ├── [...11]preview │ │ │ └── +page.md │ │ ├── [...12]text │ │ │ └── +page.md │ │ ├── [...1]HTML │ │ │ └── +page.md │ │ ├── [...2]head │ │ │ └── +page.md │ │ ├── [...3]button │ │ │ └── +page.md │ │ ├── [...4]container │ │ │ └── +page.md │ │ ├── [...5]column │ │ │ └── +page.md │ │ ├── [...6]section │ │ │ └── +page.md │ │ ├── [...7]heading │ │ │ └── +page.md │ │ ├── [...8]hr │ │ │ └── +page.md │ │ └── [...9]image │ │ │ └── +page.md │ ├── [...4]utilities │ │ └── [...1]render │ │ │ └── +page.md │ ├── [...5]integrations │ │ ├── [...1]overview │ │ │ └── +page.md │ │ ├── [...2]nodemailer │ │ │ └── +page.md │ │ ├── [...3]sendgrid │ │ │ └── +page.md │ │ ├── [...4]postmark │ │ │ └── +page.md │ │ └── [...5]aws-ses │ │ │ └── +page.md │ └── [...6]examples │ │ ├── [...1]airbnb-review │ │ ├── +page.md │ │ ├── +page.server.ts │ │ └── Email.svelte │ │ └── [...1]apple-receipt │ │ ├── +page.md │ │ ├── +page.server.ts │ │ └── Email.svelte │ ├── kit-docs │ ├── [dir].sidebar │ │ └── +server.js │ └── [slug].meta │ │ └── +server.js │ └── sitemap.xml │ └── +server.js ├── static ├── airbnb-logo.png ├── airbnb-review-user.jpeg ├── apple-card-icon.png ├── apple-hbo-max-icon.jpeg ├── apple-logo.png ├── apple-wallet.png └── favicon.png ├── svelte.config.js ├── tsconfig.json └── vite.config.ts /.eslintignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | 10 | # Ignore files for PNPM, NPM and YARN 11 | pnpm-lock.yaml 12 | package-lock.json 13 | yarn.lock 14 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], 5 | plugins: ['svelte3', '@typescript-eslint'], 6 | ignorePatterns: ['*.cjs'], 7 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], 8 | settings: { 9 | 'svelte3/typescript': () => require('typescript') 10 | }, 11 | parserOptions: { 12 | sourceType: 'module', 13 | ecmaVersion: 2020 14 | }, 15 | env: { 16 | browser: true, 17 | es2017: true, 18 | node: true 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [carstenlebek] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: ['https://www.buymeacoffee.com/carstenlebek'] 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | vite.config.js.timestamp-* 10 | vite.config.ts.timestamp-* 11 | dist -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | 10 | # Ignore files for PNPM, NPM and YARN 11 | pnpm-lock.yaml 12 | package-lock.json 13 | yarn.lock 14 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "printWidth": 100, 6 | "plugins": ["prettier-plugin-svelte"], 7 | "pluginSearchDirs": ["."], 8 | "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] 9 | } 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @cmjoseph07/svelty-email 2 | 3 | ## 0.1.1 4 | 5 | - fix: Add default export for "." to resolve vitest issue 6 | 7 | ## 0.1.0 8 | 9 | - breaking: updates dep to Svelte 5 and updated `render.ts` to allow for Svelte 5 support 10 | 11 | ## 0.0.11 12 | 13 | - fix: Head component `http-equiv` attribute typo 14 | 15 | ## 0.0.10 16 | 17 | - fix: duplicate markdown produced from `Container.svelte` yank, removed duplicate code. 18 | 19 | ## 0.0.9 20 | 21 | - fix: better error message for 'Preview' component range error. ([#14](https://github.com/carstenlebek/svelte-email/issues/14)) 22 | - fix: remove default bg of #ffffff from 'Container' component and TS error for class. ([#32](https://github.com/carstenlebek/svelte-email/issues/32)) 23 | - fix: warning -- CardGroup has unused export property 'cols'. 24 | 25 | ## 0.0.8 26 | 27 | ### Patch Changes 28 | 29 | - fix: README.md to fix example and block quote warnings 30 | - fix: Airbnb example to reflect "Section" not being used as root element 31 | - fix: integration documentation pages incorrectly list the render function arguments with a "component" property, instead "template". 32 | 33 | ## 0.0.7 34 | 35 | ### Patch Changes 36 | 37 | - fix: warning -- '...no exports condition for svelte.' by adding required export conditions to package.json. ([#29](https://github.com/carstenlebek/svelte-email/issues/29)) 38 | - fix: warning -- '...A11y: cannot have role 'presentation'' by switching role to "row" ([#18](https://github.com/carstenlebek/svelte-email/issues/18)) 39 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Chris Joseph 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Svelt𝑦-Email

2 |
Community fork for Svelte-Email. Designing emails has never been easier.
3 |
4 |
5 | Documentation (Previous Author Site) 6 | · 7 | GitHub 8 |
9 | 10 | # Warning 11 | 12 | > [!WARNING] 13 | > Breaking change made for Svelte 5 support while lib is being re-written. Please use `0.0.11` for Svelte 4 apps. 14 | 15 | # Introduction 16 | 17 | > [!NOTE] 18 | > After seeing [react-email](https://github.com/resendlabs/react-email) Carsten decided to create a similar library for Svelte. `svelte-email` enables you to write and design email templates with svelte and render them to HTML or plain text. This is a community maintained fork to keep the project going as svelte continues to evolve under `svelty-email`. 19 | 20 | # Installation 21 | 22 | Install the package to your existing SvelteKit project: 23 | 24 | ```bash title="npm" 25 | npm install svelty-email 26 | ``` 27 | 28 | ```bash title="pnpm" 29 | pnpm install svelty-email 30 | ``` 31 | 32 | # Getting started 33 | 34 | ## 1. Create an email using Svelte 35 | 36 | `src/$lib/emails/Hello.svelte` 37 | 38 | ```html 39 | 44 | 45 | 46 | 47 | Hello, {name}! 48 | 49 |
50 | 51 | 52 | ``` 53 | 54 | ## 2. Send email 55 | 56 | This example uses [Nodemailer](https://nodemailer.com/about/) to send the email. You can use any other email service provider. 57 | 58 | `src/routes/emails/hello/+server.js` 59 | 60 | ```js 61 | import { render } from 'svelty-email'; 62 | import Hello from '$lib/emails/Hello.svelte'; 63 | import nodemailer from 'nodemailer'; 64 | 65 | const transporter = nodemailer.createTransport({ 66 | host: 'smtp.ethereal.email', 67 | port: 587, 68 | secure: false, 69 | auth: { 70 | user: 'my_user', 71 | pass: 'my_password' 72 | } 73 | }); 74 | 75 | const emailHtml = render({ 76 | template: Hello, 77 | props: { 78 | name: 'Svelte' 79 | } 80 | }); 81 | 82 | const options = { 83 | from: 'you@example.com', 84 | to: 'user@gmail.com', 85 | subject: 'hello world', 86 | html: emailHtml 87 | }; 88 | 89 | transporter.sendMail(options); 90 | ``` 91 | 92 | # Advanced Example REPL(s): 93 | 94 | > [!CAUTION] 95 | > Update: fix broken Airbnb example formatting in old docs, broken logos 96 | 97 | [Airbnb Example](https://www.sveltelab.dev/dk5ce45zckb7h9v?files=.%2Fsrc%2Froutes%2F%2Bpage.svelte%2C.%2Fsrc%2Froutes%2F%2Bpage.server.js%2C.%2Fsrc%2Flib%2Femails%2FAirbnbExp.svelte) 98 | 99 | # Documentation 100 | 101 | > [!WARNING] 102 | > Documentation page is from previous project, `svelte-email` will need to be replaced with `svelty-email` but examples are great. 103 | 104 | For more information, please visit the [documentation](https://svelte-email.vercel.app/). 105 | 106 | # Components 107 | 108 | A 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. 109 | 110 | - [HTML](https://svelte-email.vercel.app/docs/components/HTML) 111 | - [Head](https://svelte-email.vercel.app/docs/components/head) 112 | - [Heading](https://svelte-email.vercel.app/docs/components/heading) 113 | - [Button](https://svelte-email.vercel.app/docs/components/button) 114 | - [Link](https://svelte-email.vercel.app/docs/components/link) 115 | - [Image](https://svelte-email.vercel.app/docs/components/image) 116 | - [Divider](https://svelte-email.vercel.app/docs/components/hr) 117 | - [Paragraph](https://svelte-email.vercel.app/docs/components/paragraph) 118 | - [Container](https://svelte-email.vercel.app/docs/components/container) 119 | - [Preview](https://svelte-email.vercel.app/docs/components/preview) 120 | - [Body](https://svelte-email.vercel.app/docs/components/body) 121 | - [Column](https://svelte-email.vercel.app/docs/components/column) 122 | - [Section](https://svelte-email.vercel.app/docs/components/section) -- *Please do not use as 'root' element, can break styling* 123 | 124 | # Integrations 125 | 126 | Emails built with React Email can be converted into HTML and sent using any email service provider. Here are some examples: 127 | 128 | - [Nodemailer](https://github.com/resendlabs/react-email/tree/main/examples/nodemailer) 129 | - [SendGrid](https://github.com/resendlabs/react-email/tree/main/examples/sendgrid) 130 | - [Postmark](https://github.com/resendlabs/react-email/tree/main/examples/postmark) 131 | - [AWS SES](https://github.com/resendlabs/react-email/tree/main/examples/aws-ses) 132 | 133 | # Advanced Examples: 134 | 135 | 136 | 137 | ## Author 138 | 139 | - Chris Joseph 140 | 141 | ### Previous Author [svelte-email](https://github.com/carstenlebek/svelte-email) 142 | 143 | - Carsten Lebek ([@carstenlebek](https://twitter.com/carstenlebek1)) 144 | 145 | ### Authors of the original project [react-email](https://github.com/resendlabs/react-email) 146 | 147 | - Bu Kinoshita ([@bukinoshita](https://twitter.com/bukinoshita)) 148 | - Zeno Rocha ([@zenorocha](https://twitter.com/zenorocha)) 149 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelty-email", 3 | "version": "0.1.1", 4 | "description": "Build emails with Svelte", 5 | "author": { 6 | "name": "Chris Joseph" 7 | }, 8 | "contributors": [ 9 | "Carsten Lebek" 10 | ], 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/cmjoseph07/svelty-email" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/cmjoseph07/svelty-email/issues" 17 | }, 18 | "keywords": [ 19 | "svelte", 20 | "sveltekit", 21 | "email" 22 | ], 23 | "scripts": { 24 | "dev": "vite dev", 25 | "build": "svelte-kit sync && svelte-package", 26 | "package": "svelte-kit sync && svelte-package && publint", 27 | "docs:build": "svelte-kit sync && vite build", 28 | "prepublishOnly": "npm run package", 29 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 30 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 31 | "lint": "prettier --plugin-search-dir . --check . && eslint .", 32 | "format": "prettier --plugin-search-dir . --write ." 33 | }, 34 | "files": [ 35 | "dist", 36 | "package.json", 37 | "README.md" 38 | ], 39 | "svelte": "./dist/index.js", 40 | "main": "./dist/index.js", 41 | "exports": { 42 | ".": { 43 | "types": "./dist/index.d.ts", 44 | "svelte": "./dist/index.js", 45 | "default": "./dist/index.js" 46 | }, 47 | "./package.json": { 48 | "default": "./package.json" 49 | }, 50 | "./components/Body.svelte": { 51 | "types": "./dist/components/Body.svelte.d.ts", 52 | "svelte": "./dist/components/Body.svelte" 53 | }, 54 | "./components/Column.svelte": { 55 | "types": "./dist/components/Column.svelte.d.ts", 56 | "svelte": "./dist/components/Column.svelte" 57 | }, 58 | "./components/Container.svelte": { 59 | "types": "./dist/components/Container.svelte.d.ts", 60 | "svelte": "./dist/components/Container.svelte" 61 | }, 62 | "./components/Head.svelte": { 63 | "types": "./dist/components/Head.svelte.d.ts", 64 | "svelte": "./dist/components/Head.svelte" 65 | }, 66 | "./components/Heading.svelte": { 67 | "types": "./dist/components/Heading.svelte.d.ts", 68 | "svelte": "./dist/components/Heading.svelte" 69 | }, 70 | "./components/Hr.svelte": { 71 | "types": "./dist/components/Hr.svelte.d.ts", 72 | "svelte": "./dist/components/Hr.svelte" 73 | }, 74 | "./components/Html.svelte": { 75 | "types": "./dist/components/Html.svelte.d.ts", 76 | "svelte": "./dist/components/Html.svelte" 77 | }, 78 | "./components/Img.svelte": { 79 | "types": "./dist/components/Img.svelte.d.ts", 80 | "svelte": "./dist/components/Img.svelte" 81 | }, 82 | "./components/Link.svelte": { 83 | "types": "./dist/components/Link.svelte.d.ts", 84 | "svelte": "./dist/components/Link.svelte" 85 | }, 86 | "./components/Preview.svelte": { 87 | "types": "./dist/components/Preview.svelte.d.ts", 88 | "svelte": "./dist/components/Preview.svelte" 89 | }, 90 | "./components/Section.svelte": { 91 | "types": "./dist/components/Section.svelte.d.ts", 92 | "svelte": "./dist/components/Section.svelte" 93 | }, 94 | "./components/Text.svelte": { 95 | "types": "./dist/components/Text.svelte.d.ts", 96 | "svelte": "./dist/components/Text.svelte" 97 | }, 98 | "./render": { 99 | "types": "./dist/render.d.ts", 100 | "default": "./dist/render.js" 101 | }, 102 | "./utils": { 103 | "types": "./dist/utils.d.ts", 104 | "default": "./dist/utils.js" 105 | } 106 | }, 107 | "peerDependencies": { 108 | "@sveltejs/kit": "^1.5.0 || ^2.0.0" 109 | }, 110 | "devDependencies": { 111 | "@iconify-json/ri": "^1.1.4", 112 | "@sveltejs/adapter-auto": "^2.0.0", 113 | "@sveltejs/kit": "^1.5.0", 114 | "@sveltejs/package": "^2.2.5", 115 | "@svelteness/kit-docs": "^1.1.1", 116 | "@types/gtag.js": "^0.0.12", 117 | "@types/html-to-text": "^9.0.0", 118 | "@types/pretty": "^2.0.1", 119 | "@typescript-eslint/eslint-plugin": "^5.45.0", 120 | "@typescript-eslint/parser": "^5.45.0", 121 | "autoprefixer": "^10.4.13", 122 | "clsx": "^1.2.1", 123 | "csstype": "^3.1.1", 124 | "eslint": "^8.28.0", 125 | "eslint-config-prettier": "^8.5.0", 126 | "eslint-plugin-svelte3": "^4.0.0", 127 | "i": "^0.3.7", 128 | "npm": "^9.4.1", 129 | "postcss": "^8.4.21", 130 | "prettier": "^2.8.0", 131 | "prettier-plugin-svelte": "^2.8.1", 132 | "publint": "^0.2.7", 133 | "shiki": "^0.14.0", 134 | "svelte-check": "^3.0.1", 135 | "tailwindcss": "^3.2.4", 136 | "tslib": "^2.4.1", 137 | "typescript": "^4.9.3", 138 | "unplugin-icons": "^0.15.2", 139 | "vite": "^4.0.0" 140 | }, 141 | "type": "module", 142 | "dependencies": { 143 | "html-to-text": "^9.0.3", 144 | "pretty": "^2.0.0", 145 | "svelte": "^5.2.9" 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/app.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // See https://kit.svelte.dev/docs/types#the-app-namespace 5 | // for information about these interfaces 6 | declare namespace App { 7 | // interface Locals {} 8 | // interface Platform {} 9 | // interface Session {} 10 | // interface Stuff {} 11 | } 12 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 21 | 22 | %sveltekit.head% 23 | 24 | 25 |
%sveltekit.body%
26 | 27 | 28 | -------------------------------------------------------------------------------- /src/fonts/FiraCode-VF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/src/fonts/FiraCode-VF.woff -------------------------------------------------------------------------------- /src/fonts/FiraCode-VF.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/src/fonts/FiraCode-VF.woff2 -------------------------------------------------------------------------------- /src/fonts/Inter-VF.italic-latin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/src/fonts/Inter-VF.italic-latin.woff2 -------------------------------------------------------------------------------- /src/fonts/Inter-VF.roman-latin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/src/fonts/Inter-VF.roman-latin.woff2 -------------------------------------------------------------------------------- /src/img/svelte-horizontal.svg: -------------------------------------------------------------------------------- 1 | svelte-horizontal 2 | -------------------------------------------------------------------------------- /src/img/svelte-logo.svg: -------------------------------------------------------------------------------- 1 | svelte-logo -------------------------------------------------------------------------------- /src/kit-docs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/src/kit-docs/.gitkeep -------------------------------------------------------------------------------- /src/lib/_docs/Analytics.svelte: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 19 | 29 | 30 | -------------------------------------------------------------------------------- /src/lib/_docs/Card.svelte: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | {#if $$slots['icon']} 23 |
24 | 25 |
26 | {/if} 27 |

28 | {title} 29 | {#if href} 30 | -> 31 | {/if} 32 |

33 | {#if description} 34 | 35 |

{description}

36 |
37 | {/if} 38 |
39 | 40 | 75 | -------------------------------------------------------------------------------- /src/lib/_docs/CardGroup.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 | 7 |
8 | 9 | 22 | -------------------------------------------------------------------------------- /src/lib/_examples/hello.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | Hello, {name}! 10 | 11 |
12 | 13 | -------------------------------------------------------------------------------- /src/lib/_examples/welcome.svelte: -------------------------------------------------------------------------------- 1 | 54 | 55 | 56 | 57 | 58 |
59 | 60 | Svelte logo 66 | {firstName}, welcome to svelte-email 67 | 68 | A Svelte component library for building responsive emails 69 | 70 |
71 | 74 |
75 | Happy coding! 76 |
77 | 78 | Carsten Lebek 79 | 80 |
81 |
82 | -------------------------------------------------------------------------------- /src/lib/components/Body.svelte: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/lib/components/Button.svelte: -------------------------------------------------------------------------------- 1 | 59 | 60 | 61 | 62 | {@html ``} 63 | 64 | 65 | 66 | 67 | 68 | {@html ``} 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/lib/components/Column.svelte: -------------------------------------------------------------------------------- 1 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/lib/components/Container.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 |
24 | {@html ``} 27 |
28 |
29 | 30 |
31 |
32 | {@html ``} 35 |
36 | -------------------------------------------------------------------------------- /src/lib/components/Head.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/lib/components/Heading.svelte: -------------------------------------------------------------------------------- 1 | 26 | 27 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/lib/components/Hr.svelte: -------------------------------------------------------------------------------- 1 | 24 | 25 |
26 | -------------------------------------------------------------------------------- /src/lib/components/Html.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/lib/components/Img.svelte: -------------------------------------------------------------------------------- 1 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/lib/components/Link.svelte: -------------------------------------------------------------------------------- 1 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/lib/components/Preview.svelte: -------------------------------------------------------------------------------- 1 | 21 | 22 |
34 | {preview} 35 |
36 | {renderWhiteSpace(preview)} 37 |
38 |
39 | -------------------------------------------------------------------------------- /src/lib/components/Section.svelte: -------------------------------------------------------------------------------- 1 | 28 | 29 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/lib/components/Text.svelte: -------------------------------------------------------------------------------- 1 | 24 | 25 |

26 | 27 |

28 | -------------------------------------------------------------------------------- /src/lib/index.ts: -------------------------------------------------------------------------------- 1 | import Body from './components/Body.svelte'; 2 | import Button from './components/Button.svelte'; 3 | import Column from './components/Column.svelte'; 4 | import Container from './components/Container.svelte'; 5 | import Head from './components/Head.svelte'; 6 | import Heading from './components/Heading.svelte'; 7 | import Hr from './components/Hr.svelte'; 8 | import Html from './components/Html.svelte'; 9 | import Img from './components/Img.svelte'; 10 | import Link from './components/Link.svelte'; 11 | import Preview from './components/Preview.svelte'; 12 | import Section from './components/Section.svelte'; 13 | import Text from './components/Text.svelte'; 14 | 15 | import { render } from './render'; 16 | 17 | import { styleToString } from './utils'; 18 | 19 | export { 20 | Body, 21 | Button, 22 | Column, 23 | Container, 24 | Head, 25 | Heading, 26 | Hr, 27 | Html, 28 | Img, 29 | Link, 30 | Preview, 31 | Section, 32 | Text, 33 | render, 34 | styleToString 35 | }; 36 | -------------------------------------------------------------------------------- /src/lib/render.ts: -------------------------------------------------------------------------------- 1 | import { convert } from 'html-to-text'; 2 | import type { ComponentProps, Component, SvelteComponent } from 'svelte'; 3 | import { render as renderServer } from 'svelte/server'; 4 | 5 | export const render = async < 6 | Comp extends SvelteComponent | Component, 7 | Props extends ComponentProps = ComponentProps, 8 | >( 9 | component: Comp, 10 | props?: Props, 11 | ) => { 12 | const rendered = renderServer(component as any, { 13 | props, 14 | }); 15 | 16 | const doctype = 17 | ''; 18 | 19 | const html = `${doctype}${rendered.body}`; 20 | 21 | const text = renderAsPlainText(rendered.body); 22 | 23 | return { 24 | html, 25 | text, 26 | }; 27 | }; 28 | 29 | const renderAsPlainText = (markup: string) => { 30 | return convert(markup, { 31 | selectors: [ 32 | { selector: 'img', format: 'skip' }, 33 | { selector: '#__svelte-email-preview', format: 'skip' } 34 | ] 35 | }); 36 | }; 37 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | export const copyTextToClipboard = async (text: string) => { 2 | try { 3 | await navigator.clipboard.writeText(text); 4 | } catch { 5 | throw new Error('Not able to copy'); 6 | } 7 | }; 8 | 9 | export const pxToPt = (px: string): number | null => 10 | isNaN(Number(px)) ? null : (parseInt(px, 10) * 3) / 4; 11 | 12 | export interface Margin { 13 | m?: string; 14 | mx?: string; 15 | my?: string; 16 | mt?: string; 17 | mr?: string; 18 | mb?: string; 19 | ml?: string; 20 | } 21 | 22 | export const withMargin = (props: Margin) => 23 | [ 24 | withSpace(props.m, ['margin']), 25 | withSpace(props.mx, ['marginLeft', 'marginRight']), 26 | withSpace(props.my, ['marginTop', 'marginBottom']), 27 | withSpace(props.mt, ['marginTop']), 28 | withSpace(props.mr, ['marginRight']), 29 | withSpace(props.mb, ['marginBottom']), 30 | withSpace(props.ml, ['marginLeft']) 31 | ].filter((s) => Object.keys(s).length)[0]; 32 | 33 | const withSpace = (value: string | undefined, properties: string[]) => { 34 | return properties.reduce((styles, property) => { 35 | if (value) { 36 | return { ...styles, [property]: `${value}px` }; 37 | } 38 | return styles; 39 | }, {}); 40 | }; 41 | 42 | // https://stackoverflow.com/a/61410824 43 | 44 | export const styleToString = (style: Record) => { 45 | return Object.keys(style).reduce( 46 | (acc, key) => 47 | acc + 48 | key 49 | .split(/(?=[A-Z])/) 50 | .join('-') 51 | .toLowerCase() + 52 | ':' + 53 | style[key] + 54 | ';', 55 | '' 56 | ); 57 | }; 58 | 59 | export const unreachable = ( 60 | condition: never, 61 | message = `Entered unreachable code. Received '${condition}'.` 62 | ): never => { 63 | throw new TypeError(message); 64 | }; 65 | -------------------------------------------------------------------------------- /src/routes/+layout.js: -------------------------------------------------------------------------------- 1 | import { createKitDocsLoader } from '@svelteness/kit-docs'; 2 | 3 | export const prerender = true; 4 | 5 | export const load = createKitDocsLoader({ 6 | sidebar: { 7 | '/': null, 8 | '/docs': '/docs', 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /src/routes/+layout.svelte: -------------------------------------------------------------------------------- 1 | 43 | 44 | 45 | {#key $page.url.pathname} 46 | {#if title} 47 | {title} 48 | {/if} 49 | {#if description} 50 | 51 | {/if} 52 | {/key} 53 | 54 | 55 | 56 |
57 | 58 | 59 | 60 | 68 | 69 |
70 | 71 | 72 |
73 | 74 | 75 |
76 |
77 | 78 | 108 | -------------------------------------------------------------------------------- /src/routes/+page.js: -------------------------------------------------------------------------------- 1 | import { redirect } from '@sveltejs/kit'; 2 | 3 | export const prerender = true; 4 | 5 | /** @type {import('@sveltejs/kit').PageLoad} */ 6 | export async function load() { 7 | throw redirect(307, `/docs`); 8 | } 9 | -------------------------------------------------------------------------------- /src/routes/+page.svelte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/src/routes/+page.svelte -------------------------------------------------------------------------------- /src/routes/docs/+page.js: -------------------------------------------------------------------------------- 1 | import { redirect } from '@sveltejs/kit'; 2 | 3 | export const prerender = true; 4 | 5 | export async function load() { 6 | throw redirect(307, `/docs/overview/svelte-email`); 7 | } 8 | -------------------------------------------------------------------------------- /src/routes/docs/+page.svelte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/src/routes/docs/+page.svelte -------------------------------------------------------------------------------- /src/routes/docs/[...1]overview/[...1]svelte-email/+page.md: -------------------------------------------------------------------------------- 1 | # Svelte Email 2 | 3 | Build and send emails using Svelte and TypeScript. 4 | 5 | ### Why 6 | 7 | 8 | > We believe that email is an extremely important medium for people to communicate. However, we need to stop developing emails like 2010, and rethink how email can be done in 2022 and beyond. Email development needs a revamp. A renovation. Modernized for the way we build web apps today. 9 | 10 | [React Email](https://github.com/resendlabs/react-email) 11 | 12 | ### Components 13 | 14 | This is a 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. 15 | 16 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | ### Integrations 42 | 43 | In order to use Svelte Email with any email service provider, you’ll need to convert the components made with Svelte into a HTML string. This is done using the [render](/docs/utilities/render) utility. 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | ### Author 54 | 55 | - Carsten Lebek ([@carstenlebek1](https://twitter.com/carstenlebek1)) 56 | 57 | #### Based on [React Email](https://github.com/resendlabs/react-email) by 58 | 59 | - Bu Kinoshita ([@bukinoshita](https://twitter.com/bukinoshita)) 60 | - Zeno Rocha ([@zenorocha](https://twitter.com/zenorocha)) 61 | -------------------------------------------------------------------------------- /src/routes/docs/[...2]getting-started/[...1]installation/+page.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | To start using `svelte-email` in your SvelteKit project, you just need to install the package: 4 | 5 | ```bash title="Install svelte-email"|copy 6 | npm install svelte-email 7 | ``` 8 | 9 | -------------------------------------------------------------------------------- /src/routes/docs/[...2]getting-started/[...2]usage/+page.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | ## Creating email templates 4 | 5 | Create a new email template in the `src/$lib/emails` directory: 6 | 7 | ```svelte title="src/$lib/emails/welcome.svelte"|copy 8 | 61 | 62 | 63 | 64 | 65 |
66 | 67 | Svelte logo 74 | {firstName}, welcome to svelte-email 75 | A Svelte component library for building responsive emails 76 |
77 | 80 |
81 | Happy coding! 82 |
83 | Carsten Lebek 84 |
85 |
86 | 87 | ``` 88 | 89 | ## Rendering email templates 90 | 91 | ### HTML 92 | 93 | The email templates have to be rendered to HTML on the server. This can be done using the `render` function from `svelte-email`: 94 | 95 | ```js title="src/routes/send-welcome-email/+server.ts"|copy 96 | import WelcomeEmail from '$lib/emails/welcome.svelte'; 97 | import { render } from 'svelte-email'; 98 | 99 | export async function get() { 100 | const html = await render({ 101 | template: WelcomeEmail, 102 | props: { 103 | firstName: 'John' 104 | } 105 | }); 106 | 107 | return { 108 | html 109 | }; 110 | } 111 | ``` 112 | 113 | ### Plain text 114 | 115 | To generate a plain text version of the email, you can set the `plainText` option to `true`: 116 | 117 | ```js title="src/routes/send-welcome-email/+server.ts"|copy 118 | import WelcomeEmail from '$lib/emails/welcome.svelte'; 119 | import { render } from 'svelte-email'; 120 | 121 | export async function get() { 122 | const plainText = await render({ 123 | template: WelcomeEmail, 124 | props: { 125 | firstName: 'John' 126 | }, 127 | options: { 128 | plainText: true 129 | } 130 | }); 131 | 132 | return { 133 | plainText 134 | }; 135 | } 136 | ``` 137 | -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...10]link/+page.md: -------------------------------------------------------------------------------- 1 | # Link 2 | 3 | A hyperlink to web pages, email addresses, or anything else a URL can address. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 | Svelte 13 | ``` 14 | 15 | ## Props 16 | 17 | 20 | 21 | | Name | Type | Required | Default | Description | 22 | | ------------------- | -------- | -------- | -------- | -------------------------------- | 23 | | href | `string` | `true` | | The URL to link to | 24 | | target | `string` | `false` | `_blank` | The target attribute of the link | 25 | -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...11]preview/+page.md: -------------------------------------------------------------------------------- 1 | # Preview 2 | 3 | A preview text that will be displayed in the inbox of the recipient. 4 | 5 | :::admonition type="info" 6 | Email clients have this concept of “preview text” which gives insight into what’s inside the email before you open. A good practice is to keep that text under 90 characters. 7 | ::: 8 | 9 | ## Usage 10 | 11 | ```svelte 12 | 15 | 16 | 17 | ``` 18 | 19 | ## Props 20 | 21 | 24 | 25 | | Name | Type | Required | Default | Description | 26 | | -------------------- | -------- | -------- | ------- | ---------------- | 27 | | preview | `string` | `true` | | The preview text | 28 | -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...12]text/+page.md: -------------------------------------------------------------------------------- 1 | # Text 2 | 3 | A block of text separated by blank spaces. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 | Hello, world! 13 | ``` 14 | 15 | ## Props 16 | 17 | 20 | 21 | | Name | Type | Required | Default | Description | 22 | | ------------------ | -------- | -------- | ------- | ---------------- | 23 | | style | `object` | `false` | | Inline CSS style | 24 | -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...1]HTML/+page.md: -------------------------------------------------------------------------------- 1 | # HTML 2 | 3 | A Svelte html component to wrap emails. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 | 13 | 14 | 15 | ``` 16 | 17 | ## Props 18 | 19 | 22 | 23 | | Name | Type | Description | 24 | | ----------------- | -------- | -------------------------- | 25 | | lang | `string` | The language of the email. | 26 | -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...2]head/+page.md: -------------------------------------------------------------------------------- 1 | # Head 2 | 3 | Contains head components, related to the document such as style and meta elements. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 | 13 | My email 14 | 15 | 18 | 19 | ``` -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...3]button/+page.md: -------------------------------------------------------------------------------- 1 | # Button 2 | 3 | A link that is styled to look like a button. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 | 15 | ``` 16 | 17 | ## Props 18 | 19 | 22 | 23 | | Name | Type | Required | Default | Description | 24 | | ------------------- | -------- | -------- | -------- | --------------------------------- | 25 | | href | `string` | `true` | | The URL to link to | 26 | | style | `object` | `false` | | The CSS styles for the link | 27 | | target | `string` | `false` | `_blank` | The target attribute for the link | 28 | -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...4]container/+page.md: -------------------------------------------------------------------------------- 1 | # Container 2 | 3 | A layout component that centers all the email content. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 | 13 | 14 | 15 | ``` -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...5]column/+page.md: -------------------------------------------------------------------------------- 1 | # Column 2 | 3 | Display a column that separates content areas vertically in your email. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | ``` 21 | -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...6]section/+page.md: -------------------------------------------------------------------------------- 1 | # Section 2 | 3 | Display a section that can be formatted using columns. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 |
13 | Section content 14 |
15 | ``` 16 | -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...7]heading/+page.md: -------------------------------------------------------------------------------- 1 | # Heading 2 | 3 | A block of heading text. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 | Hello world 13 | ``` 14 | 15 | ## Props 16 | 17 | 20 | 21 | | Name | Type | Required | Default | Description | 22 | | --------------- | -------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------ | 23 | | as | `string` | `true` | `h1` | Render component as h1, h2, h3, h4, h5, h6 | 24 | | m | `string` | `false` | | A shortcut for the margin CSS property | 25 | | mx | `string` | `false` | | A shortcut for the margin-left and margin-right CSS properties | 26 | | my | `string` | `false` | | A shortcut for the margin-top and margin-bottom CSS properties | 27 | | mt | `string` | `false` | | A shortcut for the margin-top CSS property | 28 | | mr | `string` | `false` | | A shortcut for the margin-right CSS property | 29 | | mb | `string` | `false` | | A shortcut for the margin-bottom CSS property | 30 | | ml | `string` | `false` | | A shortcut for the margin-left CSS property | 31 | -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...8]hr/+page.md: -------------------------------------------------------------------------------- 1 | # Hr 2 | 3 | Display a divider that separates content areas in your email. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 |
13 | ``` 14 | 15 | ## Props 16 | 17 | 20 | 21 | | Name | Type | Required | Description | 22 | | ------------------ | -------- | -------- | ------------------------------------------------------ | 23 | | style | `object` | `false` | Style object that will be applied to the `hr` element. | 24 | -------------------------------------------------------------------------------- /src/routes/docs/[...3]components/[...9]image/+page.md: -------------------------------------------------------------------------------- 1 | # Image 2 | 3 | Display an image in your email. 4 | 5 | ## Usage 6 | 7 | ```svelte 8 | 11 | 12 | Svelte logo 18 | ``` 19 | 20 | :::admonition type="tip" 21 | All email clients can display .png, .gif, and .jpg images. Unfortunately, .svg images are not well supported, regardless of how they’re referenced, so avoid using these. See [Can I Email](https://www.caniemail.com/features/image-svg/) for more information. 22 | ::: 23 | 24 | ## Props 25 | 26 | 29 | 30 | | Name | Type | Required | Description | 31 | | ------------------- | -------- | -------- | ----------------------------------- | 32 | | alt | `string` | `false` | The alternative text for the image. | 33 | | src | `string` | `true` | The image source. | 34 | | width | `string` | `true` | The image width. | 35 | | height | `string` | `true` | The image height. | 36 | | style | `object` | `false` | The image style. | 37 | -------------------------------------------------------------------------------- /src/routes/docs/[...4]utilities/[...1]render/+page.md: -------------------------------------------------------------------------------- 1 | # Render 2 | 3 | Transform Svelte components into HTML email templates. 4 | 5 | ## 1. Create an email using Svelte 6 | 7 | ```svelte title="src/$lib/emails/Hello.svelte" 8 | 13 | 14 | 15 | 16 | Hello, {name}! 17 | 18 |
19 | 20 | 21 | ``` 22 | 23 | ## 2. Convert to HTML 24 | 25 | ```js title="src/routes/emails/hello/+server.js" 26 | import { json } from '@sveltejs/kit'; 27 | import { render } from 'svelte-email'; 28 | import Hello from '$lib/emails/Hello.svelte'; 29 | 30 | export function GET() { 31 | const html = render({ 32 | template: Hello, 33 | props: { 34 | name: 'World' 35 | } 36 | }); 37 | 38 | return json({ 39 | html 40 | }); 41 | } 42 | ``` 43 | 44 | This will return the following HTML: 45 | 46 | ```html 47 | 48 | 49 | 50 | 51 |

Hello, World!

52 |
53 | 58 | 59 | 62 | 63 | 66 | Visit Svelte 67 | 68 | 69 | 72 | 73 | 74 | 75 | 76 | ``` 77 | 78 | ## 3. Convert to plain text 79 | 80 | Plain text versions of emails are important because they ensure that the message can be read by the recipient even if they are unable to view the HTML version of the email. 81 | 82 | This is important because not all email clients and devices can display HTML email, and some recipients may have chosen to disable HTML email for security or accessibility reasons. 83 | 84 | Here’s how to convert a Svelte component into plain text. 85 | 86 | ```js title="src/routes/emails/hello/+server.js" 87 | import { json } from '@sveltejs/kit'; 88 | import { render } from 'svelte-email'; 89 | import Hello from '$lib/emails/Hello.svelte'; 90 | 91 | export function GET() { 92 | const text = render({ 93 | template: Hello, 94 | props: { 95 | name: 'World' 96 | }, 97 | options: { 98 | plainText: true 99 | } 100 | }); 101 | 102 | return json({ 103 | text 104 | }); 105 | } 106 | ``` 107 | 108 | This will return the following plain text: 109 | 110 | ```text 111 | Hello, World! 112 | 113 | -------------------------------------------------------------------------------- 114 | 115 | Visit Svelte [https://svelte.dev] 116 | ``` 117 | 118 | ## Options 119 | 120 | 123 | 124 | | Name | Type | Description | 125 | | ---------------------- | --------- | -------------------------------- | 126 | | plainText | `boolean` | Convert the email to plain text. | 127 | | pretty | `boolean` | Pretty print the HTML. | 128 | -------------------------------------------------------------------------------- /src/routes/docs/[...5]integrations/[...1]overview/+page.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | Leverage different email service providers to send emails using Svelte. 4 | 5 | In order to use Svelte Email with any email service provider, you’ll need to convert the components made with Svelte into a HTML string. This is done using the render utility. 6 | 7 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/routes/docs/[...5]integrations/[...2]nodemailer/+page.md: -------------------------------------------------------------------------------- 1 | # Send email using Nodemailer 2 | 3 | Learn how to send an email using Svelte Email and Nodemailer. 4 | 5 | ## 1. Install dependencies 6 | 7 | ```bash title="npm"|copy 8 | npm install svelte-email nodemailer 9 | ``` 10 | 11 | ```bash title="pnpm"|copy 12 | pnpm add svelte-email nodemailer 13 | ``` 14 | 15 | ## 2. Create an email using Svelte 16 | 17 | 20 | 21 | Start by building your email template in a `.svelte` file. For example, let's create a simple email template called `Hello.svelte`: 22 | 23 | ```svelte title="src/$lib/emails/Hello.svelte" 24 | 29 | 30 | 31 | 32 | Hello, {name}! 33 | 34 |
35 | 36 | 37 | ``` 38 | 39 | ## 3. Convert to HTML and send email 40 | 41 | Next, create a server route that will convert the Svelte template to HTML and send the email using Nodemailer. 42 | 43 | ```js title="src/routes/emails/hello/+server.js" 44 | import { json } from '@sveltejs/kit'; 45 | import { render } from 'svelte-email'; 46 | import Hello from '$lib/emails/Hello.svelte'; 47 | import nodemailer from 'nodemailer'; 48 | 49 | const transporter = nodemailer.createTransport({ 50 | host: 'smtp.ethereal.email', 51 | port: 587, 52 | secure: false, 53 | auth: { 54 | user: 'my_user', 55 | pass: 'my_password' 56 | } 57 | }); 58 | 59 | const emailHtml = render({ 60 | template: Hello, 61 | props: { 62 | name: 'Svelte' 63 | } 64 | }); 65 | 66 | const options = { 67 | from: 'you@example.com', 68 | to: 'user@gmail.com', 69 | subject: 'hello world', 70 | html: emailHtml 71 | }; 72 | 73 | transporter.sendMail(options); 74 | ``` 75 | -------------------------------------------------------------------------------- /src/routes/docs/[...5]integrations/[...3]sendgrid/+page.md: -------------------------------------------------------------------------------- 1 | # Send email using SendGrid 2 | 3 | Learn how to send an email using Svelte Email and the SendGrid Node.js SDK. 4 | 5 | ## 1. Install dependencies 6 | 7 | ```bash title="npm"|copy 8 | npm install svelte-email @sendgrid/mail 9 | ``` 10 | 11 | ```bash title="pnpm"|copy 12 | pnpm add svelte-email @sendgrid/mail 13 | ``` 14 | 15 | ## 2. Create an email using Svelte 16 | 17 | Start by building your email template in a `.svelte` file. For example, let's create a simple email template called `Hello.svelte`: 18 | 19 | ```svelte title="src/$lib/emails/Hello.svelte" 20 | 25 | 26 | 27 | 28 | Hello, {name}! 29 | 30 |
31 | 32 | 33 | ``` 34 | 35 | ## 3. Convert to HTML and send email 36 | 37 | Next, create a server route that will convert the Svelte template to HTML and send the email using the SendGrid Node.js SDK. 38 | 39 | ```js title="src/routes/emails/hello/+server.js" 40 | import { render } from 'svelte-email'; 41 | import Hello from '$lib/emails/Hello.svelte'; 42 | import sendgrid from '@sendgrid/mail'; 43 | 44 | sendgrid.setApiKey(process.env.SENDGRID_API_KEY); 45 | 46 | const emailHtml = render({ 47 | template: Hello, 48 | props: { 49 | name: 'Svelte' 50 | } 51 | }); 52 | 53 | const options = { 54 | from: 'you@example.com', 55 | to: 'user@gmail.com', 56 | subject: 'hello world', 57 | html: emailHtml, 58 | }; 59 | 60 | sendgrid.send(options); 61 | ``` 62 | -------------------------------------------------------------------------------- /src/routes/docs/[...5]integrations/[...4]postmark/+page.md: -------------------------------------------------------------------------------- 1 | # Send email using Postmark 2 | 3 | Learn how to send an email using Svelte Email and the Postmark Node.js SDK. 4 | 5 | ## 1. Install dependencies 6 | 7 | ```bash title="npm"|copy 8 | npm install svelte-email postmark 9 | ``` 10 | 11 | ```bash title="pnpm"|copy 12 | pnpm add svelte-email postmark 13 | ``` 14 | 15 | ## 2. Create an email using Svelte 16 | 17 | Start by building your email template in a `.svelte` file. For example, let's create a simple email template called `Hello.svelte`: 18 | 19 | ```svelte title="src/$lib/emails/Hello.svelte" 20 | 25 | 26 | 27 | 28 | Hello, {name}! 29 | 30 |
31 | 32 | 33 | ``` 34 | 35 | ## 3. Convert to HTML and send email 36 | 37 | Next, create a server route that will convert the Svelte template to HTML and send the email using the Postmark Node.js SDK. 38 | 39 | ```js title="src/routes/emails/hello/+server.js" 40 | import { render } from 'svelte-email'; 41 | import Hello from '$lib/emails/Hello.svelte'; 42 | import postmark from 'postmark'; 43 | 44 | const client = new postmark.ServerClient(process.env.POSTMARK_API_KEY); 45 | 46 | const emailHtml = render({ 47 | template: Hello, 48 | props: { 49 | name: 'Svelte' 50 | } 51 | }); 52 | 53 | const options = { 54 | From: 'you@example.com', 55 | To: 'user@gmail.com', 56 | Subject: 'hello world', 57 | HtmlBody: emailHtml, 58 | }; 59 | 60 | client.sendEmail(options); 61 | ``` 62 | -------------------------------------------------------------------------------- /src/routes/docs/[...5]integrations/[...5]aws-ses/+page.md: -------------------------------------------------------------------------------- 1 | # Send email using AWS SES 2 | 3 | Learn how to send an email using Svelte Email and the AWS SES Node.js SDK. 4 | 5 | ## 1. Install dependencies 6 | 7 | ```bash title="npm"|copy 8 | npm install svelte-email aws-sdk 9 | ``` 10 | 11 | ```bash title="pnpm"|copy 12 | pnpm add svelte-email aws-sdk 13 | ``` 14 | 15 | ## 2. Create an email using Svelte 16 | 17 | Start by building your email template in a `.svelte` file. For example, let's create a simple email template called `Hello.svelte`: 18 | 19 | ```svelte title="src/$lib/emails/Hello.svelte" 20 | 25 | 26 | 27 | 28 | Hello, {name}! 29 | 30 |
31 | 32 | 33 | ``` 34 | 35 | ## 3. Convert to HTML and send email 36 | 37 | Next, create a server route that will convert the Svelte template to HTML and send the email using the AWS SES Node.js SDK. 38 | 39 | ```js title="src/routes/emails/hello/+server.js" 40 | import { render } from 'svelte-email'; 41 | import Hello from '$lib/emails/Hello.svelte'; 42 | import AWS from 'aws-sdk'; 43 | 44 | AWS.config.update({ region: process.env.AWS_SES_REGION }); 45 | 46 | const emailHtml = render({ 47 | template: Hello, 48 | props: { 49 | name: 'Svelte' 50 | } 51 | }); 52 | 53 | const options = { 54 | Source: 'you@example.com', 55 | Destination: { 56 | ToAddresses: ['user@gmail.com'] 57 | }, 58 | Message: { 59 | Body: { 60 | Html: { 61 | Charset: 'UTF-8', 62 | Data: emailHtml 63 | } 64 | }, 65 | Subject: { 66 | Charset: 'UTF-8', 67 | Data: 'hello world' 68 | } 69 | } 70 | }; 71 | 72 | const sendPromise = new AWS.SES({ apiVersion: '2010-12-01' }).sendEmail(options).promise(); 73 | ``` 74 | -------------------------------------------------------------------------------- /src/routes/docs/[...6]examples/[...1]airbnb-review/+page.md: -------------------------------------------------------------------------------- 1 | # Airbnb Review Notification 2 | 3 | ## Template 4 | 5 | ```svelte title="Template"|copy 6 | 108 | 109 | 110 | 111 | 112 | 113 | Airbnb 114 |
115 | {authorName} 116 |
117 | Here's what {authorName} wrote 118 | {reviewText} 119 | 120 | Now that the review period is over, we’ve posted {authorName}’s review to your Airbnb 121 | profile. 122 | 123 | 124 | While it’s too late to write a review of your own, you can send your feedback to {authorName} 125 | using your Airbnb message thread. 126 | 127 |
128 | 129 |
130 |
131 | Common questions 132 | 133 | How do reviews work? 134 | 135 | 136 | 137 | How do star ratings work? 138 | 139 | 140 | 141 | 142 | Can I leave a review after 14 days? 143 | 144 | 145 |
146 | Airbnb, Inc., 888 Brannan St, San Francisco, CA 94103 147 | Report unsafe behavior 148 |
149 | 150 | ``` 151 | 152 | ## Result 153 | 154 | ### HTML 155 | 156 | 159 | 160 | 161 | 162 | ### Plain Text 163 | 164 |
165 | {@html data.plainText.replace(/\n/g, "
")} 166 |
167 | -------------------------------------------------------------------------------- /src/routes/docs/[...6]examples/[...1]airbnb-review/+page.server.ts: -------------------------------------------------------------------------------- 1 | import { render } from '$lib'; 2 | import Email from './Email.svelte'; 3 | 4 | export const prerender = true; 5 | 6 | export async function load() { 7 | const html = render({ 8 | template: Email, 9 | options: { 10 | pretty: true 11 | } 12 | }); 13 | 14 | const plainText = render({ 15 | template: Email, 16 | options: { 17 | plainText: true 18 | } 19 | }); 20 | 21 | return { 22 | html, 23 | plainText 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /src/routes/docs/[...6]examples/[...1]airbnb-review/Email.svelte: -------------------------------------------------------------------------------- 1 | 102 | 103 | 104 | 105 | 106 | 107 | Airbnb 108 |
109 | {authorName} 110 |
111 | Here's what {authorName} wrote 112 | {reviewText} 113 | 114 | Now that the review period is over, we’ve posted {authorName}’s review to your Airbnb profile. 115 | 116 | 117 | While it’s too late to write a review of your own, you can send your feedback to {authorName} 118 | using your Airbnb message thread. 119 | 120 |
121 | 122 |
123 |
124 | Common questions 125 | 126 | How do reviews work? 127 | 128 | 129 | 130 | How do star ratings work? 131 | 132 | 133 | 134 | 135 | Can I leave a review after 14 days? 136 | 137 | 138 |
139 | Airbnb, Inc., 888 Brannan St, San Francisco, CA 94103 140 | Report unsafe behavior 141 |
142 | 143 | -------------------------------------------------------------------------------- /src/routes/docs/[...6]examples/[...1]apple-receipt/+page.md: -------------------------------------------------------------------------------- 1 | # Apple Receipt 2 | 3 | ## Template 4 | 5 | ```svelte title="Template"|copy 6 | 237 | 238 | 239 | 240 | 241 |
242 | 243 |
244 | 245 | Apple Logo 246 | 247 | 248 | 249 | Receipt 250 | 251 |
252 |
253 | 254 | Save 3% on all your Apple purchases with Apple Card. 255 | 1{' '} 256 | Apply and use in minutes 257 | 2 258 | 259 |
260 | 261 | 262 | 263 | 268 | 281 | 282 | 283 | 288 | 289 | 290 | 299 | 304 | 305 | 306 |
264 | APPLE ID 265 |
266 | zeno.rocha@gmail.com 267 |
269 | BILLED TO 270 |
271 | Visa .... 7461 (Apple Pay) 272 |
273 | Zeno Rocha 274 |
275 | 2125 Chestnut St 276 |
277 | San Francisco, CA 94123 278 |
279 | USA 280 |
284 | DATE 285 |
286 | Jul 20, 2023 287 |
291 | ORDER ID 292 |
293 | 296 | ML4F5L8522 297 | 298 |
300 | DOCUMENT NO. 301 |
302 | 121565300446 303 |
307 | 308 |
309 | 310 | App Store 311 | 312 |
313 |
314 | 315 | HBO Max 322 | 323 | 324 | 325 | 326 | HBO Max: Stream TV & Movies 327 | 328 |
329 | HBO Max Ad-Free (Monthly) 330 |
331 | Renews Aug 20, 2023 332 |
333 | 338 | Write a Review 339 | 340 |  |   341 |   342 | 347 | Report a Problem 348 | 349 |
350 |
351 | 352 | 353 | $14.99 354 | 355 |
356 |
357 |
358 | 359 | TOTAL 360 | 361 | 362 | 363 | $14.99 364 | 365 |
366 |
367 |
368 | 369 | Apple Card 370 | 371 |
372 |
373 | 374 | Save 3% on all your Apple purchases. 375 | 376 |
377 |
378 | 379 | 383 | Apple Wallet 390 | Apply and use in minutes 391 | 392 | 393 |
394 |
395 | 396 | 1. 3% savings is earned as Daily Cash and is transferred to your Apple Cash card when 397 | transactions post to your Apple Card account. If you do not have an Apple Cash card, Daily 398 | Cash can be applied by you as a credit on your statement balance. 3% is the total amount of 399 | Daily Cash earned for these purchases. See the Apple Card Customer Agreement for more 400 | details on Daily Cash and qualifying transactions. 401 |
402 |
403 | 2. Subject to credit approval. 404 |
405 |
406 | To access and use all the features of Apple Card, you must add Apple Card to Wallet on an iPhone 407 | or iPad with iOS or iPadOS 13.2 or later. Update to the latest version of iOS or iPadOS by going 408 | to Settings > General > Software Update. Tap Download and Install. 409 |
410 |
411 | Available for qualifying applicants in the United States. 412 |
413 |
414 | Apple Card is issued by Goldman Sachs Bank USA, Salt Lake City Branch. 415 |
416 |
417 | If you reside in the US territories, please call Goldman Sachs at 877-255-5923 with questions 418 | about Apple Card. 419 |
420 | 421 | Privacy: We use a 422 | 423 | {' '} 424 | Subscriber ID{' '} 425 | 426 | to provide reports to developers. 427 | 428 | 429 | Get help with subscriptions and purchases. 430 | 431 | Visit Apple Support. 432 | 433 |
434 |
435 | Learn how to{' '} 436 | 439 | manage your password preferences 440 | {' '} 441 | for iTunes, Apple Books, and App Store purchases. 442 |
443 |
444 |
445 | You have the option to stop receiving email receipts for your subscription renewals. If you have 446 | opted out, you can still view your receipts in your account under Purchase History. To manage 447 | receipts or to opt in again, go to{' '} 448 | 451 | Account Settings. 452 | 453 |
454 | 455 |
456 | 457 | Apple Card 458 | 459 |
460 | 461 | 462 | 463 | Account Settings 464 | {' '} 465 | •{' '} 466 | Terms of Sale{' '} 467 | •{' '} 468 | 469 | Privacy Policy{' '} 470 | 471 | 472 | 473 | 474 | Copyright © 2023 Apple Inc.
{' '} 475 | All rights reserved 476 |
477 |
478 |
479 | 480 | ``` 481 | 482 | ## Result 483 | 484 | ### HTML 485 | 486 | 489 | 490 | 491 | 492 | ### Plain Text 493 | 494 |
495 | {@html data.plainText.replace(/\n/g, "
")} 496 |
497 | -------------------------------------------------------------------------------- /src/routes/docs/[...6]examples/[...1]apple-receipt/+page.server.ts: -------------------------------------------------------------------------------- 1 | import { render } from '$lib'; 2 | import Email from './Email.svelte'; 3 | 4 | export const prerender = true; 5 | 6 | export async function load() { 7 | const html = render({ 8 | template: Email, 9 | options: { 10 | pretty: true 11 | } 12 | }); 13 | 14 | const plainText = render({ 15 | template: Email, 16 | options: { 17 | plainText: true 18 | } 19 | }); 20 | 21 | return { 22 | html, 23 | plainText 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /src/routes/docs/[...6]examples/[...1]apple-receipt/Email.svelte: -------------------------------------------------------------------------------- 1 | 233 | 234 | 235 | 236 | 237 |
238 | 239 |
240 | 241 | Apple Logo 242 | 243 | 244 | 245 | Receipt 246 | 247 |
248 |
249 | 250 | Save 3% on all your Apple purchases with Apple Card. 251 | 1{' '} 252 | Apply and use in minutes 253 | 2 254 | 255 |
256 | 257 | 258 | 259 | 264 | 277 | 278 | 279 | 284 | 285 | 286 | 295 | 300 | 301 | 302 |
260 | APPLE ID 261 |
262 | zeno.rocha@gmail.com 263 |
265 | BILLED TO 266 |
267 | Visa .... 7461 (Apple Pay) 268 |
269 | Zeno Rocha 270 |
271 | 2125 Chestnut St 272 |
273 | San Francisco, CA 94123 274 |
275 | USA 276 |
280 | DATE 281 |
282 | Jul 20, 2023 283 |
287 | ORDER ID 288 |
289 | 292 | ML4F5L8522 293 | 294 |
296 | DOCUMENT NO. 297 |
298 | 121565300446 299 |
303 | 304 |
305 | 306 | App Store 307 | 308 |
309 |
310 | 311 | HBO Max 318 | 319 | 320 | 321 | 322 | HBO Max: Stream TV & Movies 323 | 324 |
325 | HBO Max Ad-Free (Monthly) 326 |
327 | Renews Aug 20, 2023 328 |
329 | 334 | Write a Review 335 | 336 |  |   337 |   338 | 343 | Report a Problem 344 | 345 |
346 |
347 | 348 | 349 | $14.99 350 | 351 |
352 |
353 |
354 | 355 | TOTAL 356 | 357 | 358 | 359 | $14.99 360 | 361 |
362 |
363 |
364 | 365 | Apple Card 366 | 367 |
368 |
369 | 370 | Save 3% on all your Apple purchases. 371 | 372 |
373 |
374 | 375 | 379 | Apple Wallet 386 | Apply and use in minutes 387 | 388 | 389 |
390 |
391 | 392 | 1. 3% savings is earned as Daily Cash and is transferred to your Apple Cash card when 393 | transactions post to your Apple Card account. If you do not have an Apple Cash card, Daily 394 | Cash can be applied by you as a credit on your statement balance. 3% is the total amount of 395 | Daily Cash earned for these purchases. See the Apple Card Customer Agreement for more 396 | details on Daily Cash and qualifying transactions. 397 |
398 |
399 | 2. Subject to credit approval. 400 |
401 |
402 | To access and use all the features of Apple Card, you must add Apple Card to Wallet on an iPhone 403 | or iPad with iOS or iPadOS 13.2 or later. Update to the latest version of iOS or iPadOS by going 404 | to Settings > General > Software Update. Tap Download and Install. 405 |
406 |
407 | Available for qualifying applicants in the United States. 408 |
409 |
410 | Apple Card is issued by Goldman Sachs Bank USA, Salt Lake City Branch. 411 |
412 |
413 | If you reside in the US territories, please call Goldman Sachs at 877-255-5923 with questions 414 | about Apple Card. 415 |
416 | 417 | Privacy: We use a 418 | 419 | {' '} 420 | Subscriber ID{' '} 421 | 422 | to provide reports to developers. 423 | 424 | 425 | Get help with subscriptions and purchases. 426 | 427 | Visit Apple Support. 428 | 429 |
430 |
431 | Learn how to{' '} 432 | 435 | manage your password preferences 436 | {' '} 437 | for iTunes, Apple Books, and App Store purchases. 438 |
439 |
440 |
441 | You have the option to stop receiving email receipts for your subscription renewals. If you have 442 | opted out, you can still view your receipts in your account under Purchase History. To manage 443 | receipts or to opt in again, go to{' '} 444 | 447 | Account Settings. 448 | 449 |
450 | 451 |
452 | 453 | Apple Card 454 | 455 |
456 | 457 | 458 | 459 | Account Settings 460 | {' '} 461 | •{' '} 462 | Terms of Sale{' '} 463 | •{' '} 464 | 465 | Privacy Policy{' '} 466 | 467 | 468 | 469 | 470 | Copyright © 2023 Apple Inc.
{' '} 471 | All rights reserved 472 |
473 |
474 |
475 | 476 | -------------------------------------------------------------------------------- /src/routes/kit-docs/[dir].sidebar/+server.js: -------------------------------------------------------------------------------- 1 | import { createSidebarRequestHandler, kebabToTitleCase } from '@svelteness/kit-docs/node'; 2 | 3 | /** @type {import('./$types').RequestHandler} */ 4 | export const GET = createSidebarRequestHandler({ 5 | formatCategoryName: (dirname) => kebabToTitleCase(dirname).replace('Api', 'API'), 6 | }); 7 | -------------------------------------------------------------------------------- /src/routes/kit-docs/[slug].meta/+server.js: -------------------------------------------------------------------------------- 1 | import { createMetaRequestHandler } from '@svelteness/kit-docs/node'; 2 | 3 | /** @type {import('./$types').RequestHandler} */ 4 | export const GET = createMetaRequestHandler(); 5 | -------------------------------------------------------------------------------- /src/routes/sitemap.xml/+server.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | 3 | export async function GET() { 4 | const filePaths = Object.keys(await import.meta.glob('../**/*.{svelte,md}')); 5 | 6 | const urls = filePaths 7 | .map((filePath) => 8 | filePath 9 | .slice(3) 10 | .replace(path.extname(filePath), '') 11 | .replace(/\+page$/, '') 12 | // remove last slash 13 | .replace(/\/$/, '') 14 | // remove all instances of [...x] from string, where x is a number 15 | .replace(/\[\.\.\.\d+\]/g, ''), 16 | ) 17 | .filter((url) => !url.endsWith('+layout')) 18 | .map( 19 | (url) => ` 20 | 21 | https://kit-docs-demo.vercel.app/${url} 22 | daily 23 | 0.7 24 | 25 | `, 26 | ) 27 | .join('\n'); 28 | 29 | return new Response( 30 | ` 31 | 32 | 40 | ${urls} 41 | 42 | `.trim(), 43 | { 44 | headers: { 45 | 'Cache-Control': 'max-age=0, s-maxage=3600', 46 | 'Content-Type': 'application/xml', 47 | }, 48 | }, 49 | ); 50 | } 51 | -------------------------------------------------------------------------------- /static/airbnb-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/static/airbnb-logo.png -------------------------------------------------------------------------------- /static/airbnb-review-user.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/static/airbnb-review-user.jpeg -------------------------------------------------------------------------------- /static/apple-card-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/static/apple-card-icon.png -------------------------------------------------------------------------------- /static/apple-hbo-max-icon.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/static/apple-hbo-max-icon.jpeg -------------------------------------------------------------------------------- /static/apple-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/static/apple-logo.png -------------------------------------------------------------------------------- /static/apple-wallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/static/apple-wallet.png -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmjoseph07/svelty-email/7a4f0d0e5c5fed6d52ada4e3a23e0a7de8473957/static/favicon.png -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-auto'; 2 | import { vitePreprocess } from '@sveltejs/kit/vite'; 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | // Consult https://kit.svelte.dev/docs/integrations#preprocessors 7 | // for more information about preprocessors 8 | preprocess: vitePreprocess(), 9 | extensions: ['.svelte', '.md'], 10 | 11 | kit: { 12 | adapter: adapter() 13 | } 14 | }; 15 | 16 | export default config; 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true 12 | } 13 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias 14 | // 15 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 16 | // from the referenced tsconfig.json - TypeScript does not merge them in 17 | } 18 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite'; 2 | import icons from 'unplugin-icons/vite'; 3 | import kitDocs from '@svelteness/kit-docs/node'; 4 | 5 | /** @type {import('vite').UserConfig} */ 6 | const config = { 7 | plugins: [icons({ compiler: 'svelte' }), kitDocs(), sveltekit()] 8 | }; 9 | 10 | export default config; 11 | --------------------------------------------------------------------------------