@lupinum/nuxt-email 1.0.0-beta.3 → 1.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +29 -1
  3. package/dist/agent/AGENTS.md +47 -0
  4. package/dist/agent/manifest.json +208 -0
  5. package/dist/agent/pages/docs/components/code.md +68 -0
  6. package/dist/agent/pages/docs/components/content.md +111 -0
  7. package/dist/agent/pages/docs/components/layout.md +89 -0
  8. package/dist/agent/pages/docs/components/markdown.md +49 -0
  9. package/dist/agent/pages/docs/components/structure.md +122 -0
  10. package/dist/agent/pages/docs/components/tailwind.md +41 -0
  11. package/dist/agent/pages/docs/components.md +56 -0
  12. package/dist/agent/pages/docs/getting-started/choose-a-tool.md +38 -0
  13. package/dist/agent/pages/docs/getting-started/first-email.md +99 -0
  14. package/dist/agent/pages/docs/getting-started/installation.md +97 -0
  15. package/dist/agent/pages/docs/getting-started/render-from-nitro.md +59 -0
  16. package/dist/agent/pages/docs/getting-started.md +62 -0
  17. package/dist/agent/pages/docs/guides/client-compatibility.md +65 -0
  18. package/dist/agent/pages/docs/guides/plain-text.md +42 -0
  19. package/dist/agent/pages/docs/guides/preview-workflow.md +83 -0
  20. package/dist/agent/pages/docs/guides/sending-email.md +132 -0
  21. package/dist/agent/pages/docs/guides/standalone-rendering.md +118 -0
  22. package/dist/agent/pages/docs/guides/subject-lines.md +95 -0
  23. package/dist/agent/pages/docs/guides/tailwind.md +128 -0
  24. package/dist/agent/pages/docs/guides/testing-your-emails.md +118 -0
  25. package/dist/agent/pages/docs/guides.md +32 -0
  26. package/dist/agent/pages/docs/reference/conformance.md +55 -0
  27. package/dist/agent/pages/docs/reference/define-email.md +69 -0
  28. package/dist/agent/pages/docs/reference/errors.md +72 -0
  29. package/dist/agent/pages/docs/reference/migration.md +144 -0
  30. package/dist/agent/pages/docs/reference/module.md +90 -0
  31. package/dist/agent/pages/docs/reference/render-email.md +107 -0
  32. package/dist/agent/pages/docs/reference.md +30 -0
  33. package/dist/module.json +1 -1
  34. package/package.json +9 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.0.0-beta.4
4
+
5
+ [compare changes](https://github.com/lupinum-dev/nuxt-email/compare/v1.0.0-beta.3...v1.0.0-beta.4)
6
+
7
+ ### 🚀 Enhancements
8
+
9
+ - **docs:** Ship versioned package guidance ([#55](https://github.com/lupinum-dev/nuxt-email/pull/55))
10
+
11
+ ### 🩹 Fixes
12
+
13
+ - **deps:** Clear workspace advisories and update Vitest ([#54](https://github.com/lupinum-dev/nuxt-email/pull/54))
14
+
15
+ ### ❤️ Contributors
16
+
17
+ - Matthias Amon
18
+
3
19
  ## v1.0.0-beta.3
4
20
 
5
21
  [compare changes](https://github.com/lupinum-dev/nuxt-email/compare/v1.0.0-beta.2...v1.0.0-beta.3)
package/README.md CHANGED
@@ -25,7 +25,7 @@
25
25
  </p>
26
26
 
27
27
  > [!WARNING]
28
- > [`1.0.0-beta.2`](https://www.npmjs.com/package/@lupinum/nuxt-email/v/1.0.0-beta.2) is published on npm's `next` tag. The [three-client beta smoke test](https://github.com/lupinum-dev/nuxt-email/blob/main/docs/release/client-qa-checklist.md#100-beta1-smoke-test) passed against beta.1; the full eight-client checklist and an external transactional beta still block stable `1.0.0`. The unscoped `nuxt-email` package on npm is unrelated to this project.
28
+ > [`1.0.0-beta.3`](https://www.npmjs.com/package/@lupinum/nuxt-email/v/1.0.0-beta.3) is published on npm's `next` tag. The [three-client beta smoke test](https://github.com/lupinum-dev/nuxt-email/blob/main/docs/release/client-qa-checklist.md#100-beta1-smoke-test) passed against beta.1; the full eight-client checklist and an external transactional beta still block stable `1.0.0`. The unscoped `nuxt-email` package on npm is unrelated to this project.
29
29
 
30
30
  ## Why use Nuxt Email?
31
31
 
@@ -61,6 +61,34 @@ export default defineNuxtConfig({
61
61
  })
62
62
  ```
63
63
 
64
+ <!-- BEGIN:consumer-onboarding -->
65
+
66
+ ### Use a coding agent
67
+
68
+ A coding agent is a development tool that can inspect and change your project.
69
+ After installation, copy this prompt into your coding agent:
70
+
71
+ ```text
72
+ Add Nuxt Email to this Nuxt application and render one transactional email from
73
+ a Vue template. Read the project's existing instructions first. Resolve
74
+ @lupinum/nuxt-email/agent-docs from this application's directory and read its
75
+ starting pages. Use the installed version's examples and public types. Preserve
76
+ existing routes, security boundaries, conventions, and AGENTS.md instructions.
77
+ Add or update one short Nuxt Email pointer in AGENTS.md if the project allows
78
+ it; do not duplicate the documentation. If the file is absent, create only that
79
+ pointer. Report missing guidance. Verify the server render, HTML and plain-text
80
+ output, and one invalid request. Keep delivery in application-owned code.
81
+ ```
82
+
83
+ If the installed package has no `agent-docs` export, read its packaged README,
84
+ types, and `CONFORMANCE.md`. Use documentation from the matching source tag when
85
+ more detail is needed. Installing or updating the package does not edit project
86
+ instructions. The pointer resolves the installed package, so upgrades and
87
+ rollbacks select the matching documentation without copying it into your
88
+ application.
89
+
90
+ <!-- END:consumer-onboarding -->
91
+
64
92
  ## Quick start
65
93
 
66
94
  Create `app/emails/welcome.vue`:
@@ -0,0 +1,47 @@
1
+ # @lupinum/nuxt-email
2
+
3
+ Documentation for installed version 1.0.0-beta.4.
4
+
5
+ Read the relevant local pages before changing this package’s integration.
6
+ Project instructions govern architecture, style and permissions.
7
+
8
+ ## Start here
9
+
10
+ - [Installation](./pages/docs/getting-started/installation.md) — /docs/getting-started/installation
11
+ - [Module behavior](./pages/docs/reference/module.md) — /docs/reference/module
12
+
13
+ ## Find a page
14
+
15
+ The index below maps public documentation routes to this installed snapshot.
16
+ For links to this documentation site, use the matching local page in manifest.json
17
+ instead of fetching a possibly different website version. Preserve URL fragments.
18
+ External dependencies have their own versioned contracts. Report missing guidance.
19
+
20
+ - [Overview](./pages/docs/components.md) — /docs/components
21
+ - [Code](./pages/docs/components/code.md) — /docs/components/code
22
+ - [Content](./pages/docs/components/content.md) — /docs/components/content
23
+ - [Layout](./pages/docs/components/layout.md) — /docs/components/layout
24
+ - [Markdown](./pages/docs/components/markdown.md) — /docs/components/markdown
25
+ - [Structure](./pages/docs/components/structure.md) — /docs/components/structure
26
+ - [Tailwind](./pages/docs/components/tailwind.md) — /docs/components/tailwind
27
+ - [Introduction](./pages/docs/getting-started.md) — /docs/getting-started
28
+ - [Choose the right tool](./pages/docs/getting-started/choose-a-tool.md) — /docs/getting-started/choose-a-tool
29
+ - [Your first email](./pages/docs/getting-started/first-email.md) — /docs/getting-started/first-email
30
+ - [Installation](./pages/docs/getting-started/installation.md) — /docs/getting-started/installation
31
+ - [Render from Nitro](./pages/docs/getting-started/render-from-nitro.md) — /docs/getting-started/render-from-nitro
32
+ - [Guides](./pages/docs/guides.md) — /docs/guides
33
+ - [Client compatibility and proofs](./pages/docs/guides/client-compatibility.md) — /docs/guides/client-compatibility
34
+ - [Plain text](./pages/docs/guides/plain-text.md) — /docs/guides/plain-text
35
+ - [Preview workflow](./pages/docs/guides/preview-workflow.md) — /docs/guides/preview-workflow
36
+ - [Sending email](./pages/docs/guides/sending-email.md) — /docs/guides/sending-email
37
+ - [Render outside Nitro](./pages/docs/guides/standalone-rendering.md) — /docs/guides/standalone-rendering
38
+ - [Subject lines](./pages/docs/guides/subject-lines.md) — /docs/guides/subject-lines
39
+ - [Using Tailwind](./pages/docs/guides/tailwind.md) — /docs/guides/tailwind
40
+ - [Testing your emails](./pages/docs/guides/testing-your-emails.md) — /docs/guides/testing-your-emails
41
+ - [Reference](./pages/docs/reference.md) — /docs/reference
42
+ - [Conformance and divergences](./pages/docs/reference/conformance.md) — /docs/reference/conformance
43
+ - [defineEmail](./pages/docs/reference/define-email.md) — /docs/reference/define-email
44
+ - [Error types](./pages/docs/reference/errors.md) — /docs/reference/errors
45
+ - [Migration from React Email](./pages/docs/reference/migration.md) — /docs/reference/migration
46
+ - [Module behavior](./pages/docs/reference/module.md) — /docs/reference/module
47
+ - [renderEmail](./pages/docs/reference/render-email.md) — /docs/reference/render-email
@@ -0,0 +1,208 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "name": "@lupinum/nuxt-email",
4
+ "version": "1.0.0-beta.4",
5
+ "entrySha256": "a5d837ccbd208ce1924ee015f852d3b46397076faff9fc0c9db3e407bad466e8",
6
+ "startRoutes": [
7
+ "/docs/getting-started/installation",
8
+ "/docs/reference/module"
9
+ ],
10
+ "pages": [
11
+ {
12
+ "title": "Overview",
13
+ "route": "/docs/components",
14
+ "url": "https://nuxt-email.lupinum.com/docs/components",
15
+ "file": "pages/docs/components.md",
16
+ "sha256": "0e77e7d3e2b416385f4acf4a82a501b01752e8144bf3f2280c957f44dfa29eed"
17
+ },
18
+ {
19
+ "title": "Code",
20
+ "route": "/docs/components/code",
21
+ "url": "https://nuxt-email.lupinum.com/docs/components/code",
22
+ "file": "pages/docs/components/code.md",
23
+ "sha256": "df92b0166b7587f481b7dffd77b2cf1082d8f22f6f83cbc8d98fcb78f2a01f78"
24
+ },
25
+ {
26
+ "title": "Content",
27
+ "route": "/docs/components/content",
28
+ "url": "https://nuxt-email.lupinum.com/docs/components/content",
29
+ "file": "pages/docs/components/content.md",
30
+ "sha256": "1248dbdeeac67e2cb1d06708ce85a14e683dde556d95c8e8d6340cd530d0b476"
31
+ },
32
+ {
33
+ "title": "Layout",
34
+ "route": "/docs/components/layout",
35
+ "url": "https://nuxt-email.lupinum.com/docs/components/layout",
36
+ "file": "pages/docs/components/layout.md",
37
+ "sha256": "9d5b477e1d8851a1e1b4eab317c9e1216f588690681d2114f5008f926adb6f6c"
38
+ },
39
+ {
40
+ "title": "Markdown",
41
+ "route": "/docs/components/markdown",
42
+ "url": "https://nuxt-email.lupinum.com/docs/components/markdown",
43
+ "file": "pages/docs/components/markdown.md",
44
+ "sha256": "51d86aa26c831464e1a974bc807acf1bfd1e3a536a775c44cd0c18f823cccff4"
45
+ },
46
+ {
47
+ "title": "Structure",
48
+ "route": "/docs/components/structure",
49
+ "url": "https://nuxt-email.lupinum.com/docs/components/structure",
50
+ "file": "pages/docs/components/structure.md",
51
+ "sha256": "805b8b130f06435f567c281990fb7c1e513ef4b7d4a4f5854097f37e7ad0122d"
52
+ },
53
+ {
54
+ "title": "Tailwind",
55
+ "route": "/docs/components/tailwind",
56
+ "url": "https://nuxt-email.lupinum.com/docs/components/tailwind",
57
+ "file": "pages/docs/components/tailwind.md",
58
+ "sha256": "fb9efa4a2f0c3760d175de5e36e119c25fe06421061bb6b537de0d91f34e44dc"
59
+ },
60
+ {
61
+ "title": "Introduction",
62
+ "route": "/docs/getting-started",
63
+ "url": "https://nuxt-email.lupinum.com/docs/getting-started",
64
+ "file": "pages/docs/getting-started.md",
65
+ "sha256": "26cdbef4fbd789b82e371d83ba0202b83a85c63910855f199429d5e616c4f220"
66
+ },
67
+ {
68
+ "title": "Choose the right tool",
69
+ "route": "/docs/getting-started/choose-a-tool",
70
+ "url": "https://nuxt-email.lupinum.com/docs/getting-started/choose-a-tool",
71
+ "file": "pages/docs/getting-started/choose-a-tool.md",
72
+ "sha256": "642860367a82e6e451da048a42c2ac3da07ff17baaf6e16115959e6008b70e62"
73
+ },
74
+ {
75
+ "title": "Your first email",
76
+ "route": "/docs/getting-started/first-email",
77
+ "url": "https://nuxt-email.lupinum.com/docs/getting-started/first-email",
78
+ "file": "pages/docs/getting-started/first-email.md",
79
+ "sha256": "ea6715f9a39dc41af50a368b2febdd11aa911caae5c6c7d37ca9b27cc279cec9"
80
+ },
81
+ {
82
+ "title": "Installation",
83
+ "route": "/docs/getting-started/installation",
84
+ "url": "https://nuxt-email.lupinum.com/docs/getting-started/installation",
85
+ "file": "pages/docs/getting-started/installation.md",
86
+ "sha256": "659d61afd40046b2d3df97943eb043edb2b81e6d5bb57b67080ab846fbbbc30c"
87
+ },
88
+ {
89
+ "title": "Render from Nitro",
90
+ "route": "/docs/getting-started/render-from-nitro",
91
+ "url": "https://nuxt-email.lupinum.com/docs/getting-started/render-from-nitro",
92
+ "file": "pages/docs/getting-started/render-from-nitro.md",
93
+ "sha256": "50346191584cdd30e2bbbf763d8ea472b128d4755264aed9774a16ac58b3195c"
94
+ },
95
+ {
96
+ "title": "Guides",
97
+ "route": "/docs/guides",
98
+ "url": "https://nuxt-email.lupinum.com/docs/guides",
99
+ "file": "pages/docs/guides.md",
100
+ "sha256": "d153a226878be000ede7a577580fab0d7edeeed038e4c05462bf1e2a6b7fdc84"
101
+ },
102
+ {
103
+ "title": "Client compatibility and proofs",
104
+ "route": "/docs/guides/client-compatibility",
105
+ "url": "https://nuxt-email.lupinum.com/docs/guides/client-compatibility",
106
+ "file": "pages/docs/guides/client-compatibility.md",
107
+ "sha256": "660232cceb2c2c7e0caa8ca214961815ef8145e3100af799a2d7fac2bf79d8f3"
108
+ },
109
+ {
110
+ "title": "Plain text",
111
+ "route": "/docs/guides/plain-text",
112
+ "url": "https://nuxt-email.lupinum.com/docs/guides/plain-text",
113
+ "file": "pages/docs/guides/plain-text.md",
114
+ "sha256": "23a4b6fa7279afa761b2594733ab232da1f61740dd34b9a29bd3ce45b4d08d21"
115
+ },
116
+ {
117
+ "title": "Preview workflow",
118
+ "route": "/docs/guides/preview-workflow",
119
+ "url": "https://nuxt-email.lupinum.com/docs/guides/preview-workflow",
120
+ "file": "pages/docs/guides/preview-workflow.md",
121
+ "sha256": "5be43853fb705a873f2f4aeb63621c71699a4e5f5104c191282a3bea6c0d3c6f"
122
+ },
123
+ {
124
+ "title": "Sending email",
125
+ "route": "/docs/guides/sending-email",
126
+ "url": "https://nuxt-email.lupinum.com/docs/guides/sending-email",
127
+ "file": "pages/docs/guides/sending-email.md",
128
+ "sha256": "3fb9ecc61b952c67cbc1d819bdc71ac462d0df486d6924d5c40a7bcdae5da5f8"
129
+ },
130
+ {
131
+ "title": "Render outside Nitro",
132
+ "route": "/docs/guides/standalone-rendering",
133
+ "url": "https://nuxt-email.lupinum.com/docs/guides/standalone-rendering",
134
+ "file": "pages/docs/guides/standalone-rendering.md",
135
+ "sha256": "d57a1c25f718855835eeb0fe1f777b4357bc43152becb620023994fdb1a97dbf"
136
+ },
137
+ {
138
+ "title": "Subject lines",
139
+ "route": "/docs/guides/subject-lines",
140
+ "url": "https://nuxt-email.lupinum.com/docs/guides/subject-lines",
141
+ "file": "pages/docs/guides/subject-lines.md",
142
+ "sha256": "a6ba3d802ef5ca15da53e9984e7f780471725656f31c00cc16483d89b6a19fad"
143
+ },
144
+ {
145
+ "title": "Using Tailwind",
146
+ "route": "/docs/guides/tailwind",
147
+ "url": "https://nuxt-email.lupinum.com/docs/guides/tailwind",
148
+ "file": "pages/docs/guides/tailwind.md",
149
+ "sha256": "9e3917ee826e27131816c847e4ff5b8b1bbd573c2c3ea0b01b803bb96cdab77e"
150
+ },
151
+ {
152
+ "title": "Testing your emails",
153
+ "route": "/docs/guides/testing-your-emails",
154
+ "url": "https://nuxt-email.lupinum.com/docs/guides/testing-your-emails",
155
+ "file": "pages/docs/guides/testing-your-emails.md",
156
+ "sha256": "afab583c1e55b7f0c87a7c130e022d3709a67ff7ee956000d1f7b8c5ae3fca30"
157
+ },
158
+ {
159
+ "title": "Reference",
160
+ "route": "/docs/reference",
161
+ "url": "https://nuxt-email.lupinum.com/docs/reference",
162
+ "file": "pages/docs/reference.md",
163
+ "sha256": "9171124fcd3b19d7998bc2e6ccd682a94f8235572991f91658de4f86f90fc94a"
164
+ },
165
+ {
166
+ "title": "Conformance and divergences",
167
+ "route": "/docs/reference/conformance",
168
+ "url": "https://nuxt-email.lupinum.com/docs/reference/conformance",
169
+ "file": "pages/docs/reference/conformance.md",
170
+ "sha256": "154107d980ef6485aed64356f9478975987cc652b47edd2ec5727951f909f046"
171
+ },
172
+ {
173
+ "title": "defineEmail",
174
+ "route": "/docs/reference/define-email",
175
+ "url": "https://nuxt-email.lupinum.com/docs/reference/define-email",
176
+ "file": "pages/docs/reference/define-email.md",
177
+ "sha256": "d0c3b62959477064dbb8e3d38982aa7c3536de5ab8a7f3b9ced2d6e89e621d93"
178
+ },
179
+ {
180
+ "title": "Error types",
181
+ "route": "/docs/reference/errors",
182
+ "url": "https://nuxt-email.lupinum.com/docs/reference/errors",
183
+ "file": "pages/docs/reference/errors.md",
184
+ "sha256": "73d1445030087a96f799d26822c16feb1495e5e18dc155e36b41f4fa0ea2ab17"
185
+ },
186
+ {
187
+ "title": "Migration from React Email",
188
+ "route": "/docs/reference/migration",
189
+ "url": "https://nuxt-email.lupinum.com/docs/reference/migration",
190
+ "file": "pages/docs/reference/migration.md",
191
+ "sha256": "3c9b28e055a98e67861f26db023feb24e46fb64f187385b9e22f162e72b69f63"
192
+ },
193
+ {
194
+ "title": "Module behavior",
195
+ "route": "/docs/reference/module",
196
+ "url": "https://nuxt-email.lupinum.com/docs/reference/module",
197
+ "file": "pages/docs/reference/module.md",
198
+ "sha256": "dc3f2279f7704a06495d9cbbddcb9a25b33af5f25d142313d8563b1fd0743ab5"
199
+ },
200
+ {
201
+ "title": "renderEmail",
202
+ "route": "/docs/reference/render-email",
203
+ "url": "https://nuxt-email.lupinum.com/docs/reference/render-email",
204
+ "file": "pages/docs/reference/render-email.md",
205
+ "sha256": "fab12cbe778918019a49ad1508935ba5b53992420c85ed2a567b259adf6c6219"
206
+ }
207
+ ]
208
+ }
@@ -0,0 +1,68 @@
1
+ ---
2
+ title: "Code"
3
+ description: "Compatibility-safe inline code and opt-in syntax-highlighted blocks."
4
+ url: "https://nuxt-email.lupinum.com/docs/components/code"
5
+ route: "/docs/components/code"
6
+ locale: "en"
7
+ section: "Documentation"
8
+ collection: "docs"
9
+ source: "ginko-content"
10
+ ---
11
+
12
+ # Code
13
+
14
+ > Compatibility-safe inline code and opt-in syntax-highlighted blocks.
15
+
16
+ ## ECodeInline
17
+
18
+ `ECodeInline` renders inline code inside a text flow. Place it inside `EText` (or another text element). It accepts safe HTML attributes and forwards them, plus `style`, to both emitted elements.
19
+
20
+ | Prop | Type | Default | Required |
21
+ | --- | --- | --- | --- |
22
+ | — | No component-specific props; accepts [shared safe native attributes](/raw/docs/components.md#rules-every-component-shares). | — | — |
23
+
24
+ It renders three siblings: a `<style>` with the `Orange.fr` webmail compatibility rule, a visible `<code>` element, and a hidden copy `<span>` (`display:none`). The hidden compatibility copy is excluded from plain-text conversion, so recipients receive the code once.
25
+
26
+ ```vue
27
+ <EText>
28
+ Run <ECodeInline class="inline-code">pnpm install</ECodeInline> to begin.
29
+ </EText>
30
+ ```
31
+
32
+ ## ECodeBlock
33
+
34
+ `ECodeBlock` is available only when `codeBlock` is configured on the Nuxt module. It uses the Shiki syntax highlighter and renders escaped tokens with inline theme colors. The language list is a closed build-time allowlist. Only configured languages and the grammars they import are bundled. A different runtime `language` value throws and lists the enabled languages.
35
+
36
+ | Prop | Type | Default | Required |
37
+ | --- | --- | --- | --- |
38
+ | `code` | `string` | — | Yes |
39
+ | `language` | Configured language union | — | Yes |
40
+ | `lineNumbers` | `boolean` | `false` | No |
41
+ | `fontFamily` | `string` | `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace` | No |
42
+
43
+ Code is escaped before rendering. The language is typed from the configured allowlist and checked again at runtime. Line numbers are decorative and excluded from plain text.
44
+
45
+ ```ts [nuxt.config.ts]
46
+ export default defineNuxtConfig({
47
+ modules: ['@lupinum/nuxt-email'],
48
+ nuxtEmail: {
49
+ codeBlock: {
50
+ languages: ['typescript', 'bash'],
51
+ theme: 'github-dark',
52
+ },
53
+ },
54
+ })
55
+ ```
56
+
57
+ ```vue
58
+ <ECodeBlock
59
+ :code="source"
60
+ language="typescript"
61
+ line-numbers
62
+ style="border-radius:8px;padding:16px"
63
+ />
64
+ ```
65
+
66
+ The configured theme produces concrete inline colors; there is no stylesheet or browser runtime. Author styles are also inline for email-client compatibility. Theme selection is build-time because email clients do not reliably support the CSS-variable approach used for responsive light/dark Shiki themes.
67
+
68
+ Without `codeBlock`, the component is unregistered and Shiki performs no module-setup or production-bundle work. Use the generated `#nuxt-email/testing` binding when testing templates that contain `ECodeBlock`.
@@ -0,0 +1,111 @@
1
+ ---
2
+ title: "Content"
3
+ description: "EText, EHeading, ELink, EImg, EHr, and EButton for visible email content."
4
+ url: "https://nuxt-email.lupinum.com/docs/components/content"
5
+ route: "/docs/components/content"
6
+ locale: "en"
7
+ section: "Documentation"
8
+ collection: "docs"
9
+ source: "ginko-content"
10
+ ---
11
+
12
+ # Content
13
+
14
+ > EText, EHeading, ELink, EImg, EHr, and EButton for visible email content.
15
+
16
+ These components carry the visible content of an email. Layout-sensitive components provide email-safe defaults. `ELink` is visually neutral.
17
+
18
+ ## EText
19
+
20
+ `EText` renders a `<p>` with `font-size: 14px`, `line-height: 24px`, and `16px` top and bottom margins. Author styles override these defaults.
21
+
22
+ | Prop | Type | Default | Required |
23
+ | --- | --- | --- | --- |
24
+ | — | No component-specific props; accepts [shared safe native attributes](/raw/docs/components.md#rules-every-component-shares). | — | — |
25
+
26
+ ```vue
27
+ <EText :style="{ color: '#334155' }">Your workspace is ready.</EText>
28
+ ```
29
+
30
+ ## EHeading
31
+
32
+ `EHeading` renders a heading element. An unsupported tag fails during rendering.
33
+
34
+ | Prop | Type | Default | Required |
35
+ | --- | --- | --- | --- |
36
+ | `as` | `'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6'` | `h1` | No |
37
+
38
+ It also accepts [shared safe native attributes](/raw/docs/components.md#rules-every-component-shares).
39
+
40
+ ```vue
41
+ <EHeading as="h2">Account ready</EHeading>
42
+ ```
43
+
44
+ ## ELink
45
+
46
+ `ELink` renders a visually neutral anchor. It adds no color or text decoration.
47
+
48
+ | Prop | Type | Default | Required |
49
+ | --- | --- | --- | --- |
50
+ | `href` | `string` | — | Yes |
51
+ | `target` | Safe native anchor target | `_blank` | No |
52
+
53
+ `href` must be non-empty. The value is escaped, but its URL scheme is not validated. Set visual styles explicitly and validate application-controlled URLs.
54
+
55
+ ```vue
56
+ <ELink href="https://example.com/account" style="color:#2563eb">Open account</ELink>
57
+ ```
58
+
59
+ ## EImg
60
+
61
+ `EImg` renders an image with block display and no border, outline, or text decoration.
62
+
63
+ | Prop | Type | Default | Required |
64
+ | --- | --- | --- | --- |
65
+ | `src` | `string` | — | Yes |
66
+ | `alt` | `string` | — | Yes |
67
+
68
+ `src` must be non-empty. Use `alt=""` for a decorative image. The URL is serialized but never fetched. Safe image attributes such as `width` and `height` are accepted.
69
+
70
+ ```vue
71
+ <EImg src="https://example.com/logo.png" alt="Example" width="120" height="32" />
72
+ ```
73
+
74
+ ## EHr
75
+
76
+ `EHr` renders a full-width horizontal rule with a transparent border and a `1px solid #eaeaea` top border. Author styles override individual defaults.
77
+
78
+ | Prop | Type | Default | Required |
79
+ | --- | --- | --- | --- |
80
+ | — | No component-specific props; accepts [shared safe native attributes](/raw/docs/components.md#rules-every-component-shares). | — | — |
81
+
82
+ ```vue
83
+ <EHr :style="{ borderTopColor: '#cbd5e1' }" />
84
+ ```
85
+
86
+ ## EButton
87
+
88
+ `EButton` renders an anchor with conditional Outlook spacer markup. The spacer keeps its padding usable in Outlook for Windows.
89
+
90
+ | Prop | Type | Default | Required |
91
+ | --- | --- | --- | --- |
92
+ | `href` | `string` | — | Yes |
93
+ | `target` | Safe native anchor target | `_blank` | No |
94
+ | `style` | Vue style value | Email-safe anchor defaults | No |
95
+
96
+ The default style uses `line-height: 100%`, no text decoration, inline-block display, and `max-width: 100%`. It also sets the Outlook-specific `mso-padding-alt` property to `0px`. Author styles override these values.
97
+
98
+ Padding accepts finite non-negative numbers or `px`, `em`, `rem`, and `%` values. Shorthand accepts one to four values. Invalid units, negative or non-finite values, and output large enough to inflate the message fail during rendering.
99
+
100
+ ```vue
101
+ <EButton
102
+ href="https://example.com/activate"
103
+ :style="{ backgroundColor: '#0f5132', color: '#fff', padding: '12px 20px' }"
104
+ >
105
+ Activate account
106
+ </EButton>
107
+ ```
108
+
109
+ <card title="Client notes" icon="lucide:mail">
110
+ Remote images are often blocked, so always provide useful alternative text. Outlook for Windows ignores CSS padding on inline anchors; `EButton` supplies conditional spacer markup for that client. Verify both behaviors during [manual QA](/raw/docs/guides/client-compatibility.md).
111
+ </card>
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: "Layout"
3
+ description: "EContainer, ESection, ERow, and EColumn — presentation-table primitives for stable email layouts."
4
+ url: "https://nuxt-email.lupinum.com/docs/components/layout"
5
+ route: "/docs/components/layout"
6
+ locale: "en"
7
+ section: "Documentation"
8
+ collection: "docs"
9
+ source: "ginko-content"
10
+ ---
11
+
12
+ # Layout
13
+
14
+ > EContainer, ESection, ERow, and EColumn — presentation-table primitives for stable email layouts.
15
+
16
+ These components use presentation tables for email-client compatibility.
17
+
18
+ ## EContainer
19
+
20
+ `EContainer` renders a centered presentation table for bounded content. It defaults to `align="center"`, `width="100%"`, and a maximum width of `37.5em`. Its fixed attributes are `border="0"`, `cellpadding="0"`, `cellspacing="0"`, and `role="presentation"`.
21
+
22
+ | Prop | Type | Default | Required |
23
+ | --- | --- | --- | --- |
24
+ | — | No component-specific props; accepts safe table attributes except the fixed attributes above. | — | — |
25
+
26
+ ```vue
27
+ <EContainer :style="{ maxWidth: '600px' }">Content</EContainer>
28
+ ```
29
+
30
+ ## ESection
31
+
32
+ `ESection` renders a full-width presentation table with one inner cell.
33
+
34
+ | Prop | Type | Default | Required |
35
+ | --- | --- | --- | --- |
36
+ | — | No component-specific props; accepts safe table attributes except `border`, `cellpadding`, `cellspacing`, and `role`. | — | — |
37
+
38
+ ```vue
39
+ <ESection :style="{ padding: '16px' }">Content</ESection>
40
+ ```
41
+
42
+ ## ERow
43
+
44
+ `ERow` renders a full-width presentation table whose row receives its default slot. Put `EColumn` components directly in the slot.
45
+
46
+ | Prop | Type | Default | Required |
47
+ | --- | --- | --- | --- |
48
+ | — | No component-specific props; accepts safe table attributes except `border`, `cellpadding`, `cellspacing`, and `role`. | — | — |
49
+
50
+ ```vue
51
+ <ERow><EColumn>Content</EColumn></ERow>
52
+ ```
53
+
54
+ ## EColumn
55
+
56
+ `EColumn` renders a `<td>` cell. It has no default width and adds no synthetic React marker.
57
+
58
+ | Prop | Type | Default | Required |
59
+ | --- | --- | --- | --- |
60
+ | — | No component-specific props; accepts safe cell attributes such as `width`, `colspan`, alignment, and `style`. | — | — |
61
+
62
+ ```vue
63
+ <EColumn width="50%">Left</EColumn>
64
+ ```
65
+
66
+ ## Padding placement
67
+
68
+ `EContainer`, `ESection`, and `ERow` move physical padding known at render time to a `<td>`. This includes author styles and non-variant Tailwind utilities. Responsive and pseudo-class utilities remain CSS rules because they have no single inline value. Put responsive padding on an inner `EColumn` and verify the target clients.
69
+
70
+ `ERow` adds its padding wrapper only when physical padding exists. Logical padding properties remain on the table.
71
+
72
+ ## Fixed presentation attributes
73
+
74
+ `EContainer`, `ESection`, and `ERow` reject overrides for `border`, `cellpadding`, `cellspacing`, and `role`, including alternate casing. Use `style` when you need a visual border. This deliberate [divergence](/raw/docs/reference/conformance.md) prevents silently broken layout semantics.
75
+
76
+ ```vue
77
+ <EContainer :style="{ maxWidth: '600px', padding: '24px' }">
78
+ <ESection :style="{ padding: '16px 20px' }">
79
+ <ERow>
80
+ <EColumn width="50%">Left</EColumn>
81
+ <EColumn width="50%">Right</EColumn>
82
+ </ERow>
83
+ </ESection>
84
+ </EContainer>
85
+ ```
86
+
87
+ <card title="Client note: Outlook columns" icon="lucide:columns-3">
88
+ Columns remain table cells in Outlook for Windows. Give them explicit widths and verify narrow layouts in your [client QA](/raw/docs/guides/client-compatibility.md).
89
+ </card>
@@ -0,0 +1,49 @@
1
+ ---
2
+ title: "Markdown"
3
+ description: "EMarkdown renders Markdown to email-safe HTML with inline styles and per-element overrides."
4
+ url: "https://nuxt-email.lupinum.com/docs/components/markdown"
5
+ route: "/docs/components/markdown"
6
+ locale: "en"
7
+ section: "Documentation"
8
+ collection: "docs"
9
+ source: "ginko-content"
10
+ ---
11
+
12
+ # Markdown
13
+
14
+ > EMarkdown renders Markdown to email-safe HTML with inline styles and per-element overrides.
15
+
16
+ ## EMarkdown
17
+
18
+ `EMarkdown` renders Markdown to email-safe HTML with inline styles. It is useful when content comes from a content management system (CMS) rather than Vue markup.
19
+
20
+ | Prop | Type | Default | Required |
21
+ | --- | --- | --- | --- |
22
+ | `source` | `string` | Text-only default slot | No |
23
+ | `markdownCustomStyles` | Per-element style map | Built-in email-safe styles | No |
24
+
25
+ When `source` is a string, it takes precedence over the default slot. Custom styles merge over the defaults.
26
+
27
+ Raw HTML is rejected, including HTML comments. Links and images accept relative URLs plus `http`, `https`, `mailto`, `tel`, and `cid`; other schemes are rejected after HTML-entity and control-character normalization. HTML-looking text inside code spans and fences is escaped. This keeps Markdown from becoming an implicit raw-HTML escape hatch.
28
+
29
+ The rendered container accepts Vue's normal `class`, `style`, and safe HTML attributes. Use ordinary string, object, or array `style` values; include CSS units explicitly for dimensional values such as padding.
30
+
31
+ The default slot must contain **text only**; an element child throws a `TypeError` rather than being silently stringified. Links render with `target="_blank"`, and tables render with `role="presentation"`.
32
+
33
+ ```vue
34
+ <EMarkdown source="# Title\n\nA paragraph with a [link](https://example.com)." />
35
+ ```
36
+
37
+ With overrides:
38
+
39
+ ```vue
40
+ <EMarkdown
41
+ :source="body"
42
+ :markdown-custom-styles="{ h1: { color: '#0f172a' }, a: { color: '#2563eb' } }"
43
+ :style="{ padding: '0 24px' }"
44
+ />
45
+ ```
46
+
47
+ <card title="Divergence: no data-id marker" icon="lucide:git-compare">
48
+ Unlike React Email, the container omits the `data-id="react-email-markdown"` marker (the same no-data-id divergence as `EColumn`). No Vue behavior consumes the marker. See the [conformance report](/raw/docs/reference/conformance.md).
49
+ </card>