react-email-rails 0.10.0 → 0.11.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d0666badbedb79a20a1fec50afc5aedde5398a3777620f5c2f6c2e080a2a5e2
4
- data.tar.gz: f19f1dba07f2ad62bf5737e3fab859c33a526305963ee239a1eb63d3048cc7f9
3
+ metadata.gz: 727de1abdcab5dab75ca38cf157b919b01a74fc6e8c1aef873a658ebed812a68
4
+ data.tar.gz: 023f5e0bd2ac88a010e8db0a3f1bcdaac28b2cf9424106ad45d2a6ab68a8411a
5
5
  SHA512:
6
- metadata.gz: 3905f2042d9932512be861bd7bf0be13f7dde1e9f481dae3ebbbe36f676f8562ecc29532a91649e1e64102454427057599d10baa47866ed9bbab6699163546a8
7
- data.tar.gz: 6236d1b78f000473a2bb696bbf204ce72143bd62abdc1008a0ce0fa05be88777ca2416101107894f92feaea79d16fbc7f9fc4e13d4c00e8b52ca31dff289fa64
6
+ metadata.gz: ad68609561536c4eb37215e578d1b94ec37fb77ef80c9334b68e2277a29c10d5d13040fe5817810e430ff067fe7d2ac03960815649897ab424b0fade017981bb
7
+ data.tar.gz: 77e460b82033c452fd7a4baaa2b711dba701dce6f7c2e572b10f2ddd4b7ad5b87b0b8572b3cd47382adc72a247227a57a8a9e2109ed717e7b23f7d44619ba08a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.1
4
+
5
+ - Republish of 0.11.0 with no code changes. The 0.11.0 npm package was never published: npm provenance publishing requires GitHub-hosted runners, so the release workflow's publish job now runs on one. Do not use gem 0.11.0; it has no matching npm package.
6
+
7
+ ## 0.11.0
8
+
9
+ - Generated applications now use React Email 6's unified `react-email` package for email components instead of `@react-email/components`.
10
+ - `@react-email/render` is now a runtime dependency of the `react-email-rails` npm package instead of a peer dependency, so applications no longer install it directly. The npm package now declares `react-dom` as a peer dependency alongside `react`, matching what the renderer already required at runtime.
11
+
3
12
  ## 0.10.0
4
13
 
5
14
  - **Breaking:** Remove the instance-level `react_share` helper (calling `react_share` from within an action before `mail`). Pass per-mail props directly in the `react:` hash instead; use the class-level `react_share` (with `only`/`except`/`if`/`unless`) for conditional sharing.
data/README.md CHANGED
@@ -8,16 +8,7 @@ react-email-rails lets Rails render React Email components into HTML and plain t
8
8
 
9
9
  ## Why
10
10
 
11
- HTML email is still awkward. React Email gives you a nicer component model, email-safe primitives, Tailwind support, and TypeScript. This gem connects that workflow to Rails without replacing Action Mailer.
12
-
13
- You get:
14
-
15
- - React Email components rendered from `mail(...)`
16
- - HTML and plain-text output from the same component
17
- - Rails mailer previews, tests, queues, callbacks, and delivery
18
- - Vite-powered development rendering
19
- - A production renderer bundle built during `assets:precompile`
20
- - Optional persistent rendering for high-volume workers
11
+ HTML email is still awkward. React Email gives you a nicer component model, email-safe primitives, Tailwind support, and TypeScript. This gem connects that workflow to Rails without replacing Action Mailer: components render through Vite in development and a prebuilt renderer bundle in production, with optional persistent rendering for high-volume workers.
21
12
 
22
13
  ## Status
23
14
 
@@ -34,7 +25,6 @@ The supported Ruby, Rails, Node, React, and Vite versions are tested in CI. Plea
34
25
  - [Usage](#usage)
35
26
  - [Configuration](#configuration)
36
27
  - [Deployment](#deployment)
37
- - [Development](#development)
38
28
  - [Contributing](#contributing)
39
29
  - [Security](#security)
40
30
  - [License](#license)
@@ -43,12 +33,12 @@ The supported Ruby, Rails, Node, React, and Vite versions are tested in CI. Plea
43
33
 
44
34
  | Dependency | Version |
45
35
  |------------|---------|
46
- | Ruby | >= 3.3 |
47
- | Rails | Action Mailer, Active Support, and Railties >= 7.1 and < 9.0 |
48
- | Node | >= 20.19 |
36
+ | Ruby | 3.3+ |
37
+ | Rails | 7.1–8.x |
38
+ | Node | 20.19+ |
49
39
  | Vite | 7 or 8 |
50
40
  | React | 18 or 19 |
51
- | `@react-email/render` | 2.x |
41
+ | React Email | 6.x |
52
42
 
53
43
  We recommend [rails_vite](https://github.com/skryukov/rails_vite/) for Vite in Rails apps.
54
44
 
@@ -68,21 +58,20 @@ bundle install
68
58
  bin/rails generate react_email_rails:install
69
59
  ```
70
60
 
71
- The installer creates `config/initializers/react_email_rails.rb`, installs missing JavaScript dependencies when it can detect your package manager, adds `reactEmailRails()` to `vite.config.*`, and creates `app/javascript/emails`.
61
+ The installer creates `config/initializers/react_email_rails.rb`, installs missing JavaScript dependencies when it can detect your package manager, adds `reactEmailRails()` to `vite.config.*` (creating `vite.config.ts` if none exists), and creates `app/javascript/emails`.
72
62
 
73
63
  After installation, the normal Rails flow applies:
74
64
 
75
65
  - Generate mailers and components with `bin/rails generate react_email_rails:email ...`.
76
66
  - Run `bin/dev` in development; email components render through Vite on demand.
77
67
  - Run `bin/rails assets:precompile` for production; the renderer bundle builds automatically.
78
- - Run `bin/rails react_email_rails:build` directly when CI or tests need the bundle without the full asset task.
79
68
 
80
69
  ### Manual Setup
81
70
 
82
71
  If you prefer to wire things up yourself, install the npm package and React Email dependencies:
83
72
 
84
73
  ```sh
85
- npm i react-email-rails @react-email/render @react-email/components react react-dom
74
+ npm i react-email-rails react-email react react-dom
86
75
  ```
87
76
 
88
77
  Use the equivalent command for pnpm, Yarn, or Bun if your app uses a different package manager.
@@ -107,7 +96,7 @@ Generate a mailer and React Email component:
107
96
  bin/rails generate react_email_rails:email Account welcome
108
97
  ```
109
98
 
110
- The generator follows Rails' mailer generator shape: `NAME [method method]`. It creates a mailer, React component, mailer preview, and test. It also reads `emails.path` and `emails.extension` from `reactEmailRails()` when available.
99
+ The generator follows Rails' mailer generator shape: `NAME [method method]`. It creates a mailer, React component, mailer preview, and test. It also reads `emails.path` and `emails.extension` from your `reactEmailRails()` Vite options when available.
111
100
 
112
101
  Pass flags when you need to override the detected component directory or extension:
113
102
 
@@ -139,7 +128,7 @@ Then edit the generated component:
139
128
 
140
129
  ```tsx
141
130
  // app/javascript/emails/account_mailer/welcome.tsx
142
- import { Body, Container, Html, Text } from "@react-email/components"
131
+ import { Body, Container, Html, Text } from "react-email"
143
132
 
144
133
  type WelcomeProps = {
145
134
  account: {
@@ -166,7 +155,7 @@ Deliver it like any other Action Mailer email:
166
155
  AccountMailer.with(account: current_account).welcome.deliver_later
167
156
  ```
168
157
 
169
- React Email also provides primitives like [`<Button>`, `<Heading>`, `<Tailwind>`, and more](https://react.email/docs/components/html).
158
+ React Email also provides primitives like [`<Button>`, `<Heading>`, `<Tailwind>`, and more](https://react.email/components).
170
159
 
171
160
  ## Rendering
172
161
 
@@ -178,9 +167,9 @@ Every `react:` email renders HTML and plain text from the same component. If ren
178
167
 
179
168
  ### Live-Reloading Previews
180
169
 
181
- In development, Action Mailer previews automatically reload themselves when you edit an email component. react-email-rails registers a [preview interceptor](https://api.rubyonrails.org/classes/ActionMailer/Base.html#class-ActionMailer::Base-label-Previewing+emails) that injects `@vite/client` into the preview, and the `reactEmailRails()` plugin broadcasts a full reload over Vite's websocket whenever a file under your emails directory changes.
170
+ In development, Action Mailer previews automatically reload themselves when you edit an email component. react-email-rails registers a [preview interceptor](https://api.rubyonrails.org/classes/ActionMailer/Base.html#class-ActionMailer::Base-label-Previewing+emails) that injects `@vite/client` into the preview, and the `reactEmailRails()` plugin broadcasts a full reload over Vite's WebSocket whenever a file under your emails directory changes.
182
171
 
183
- The `live_reload_url` defaults to Vite's `http://localhost:5173`, but you can point elsewhere if needed, or set it to a falsy value to disable live reload. (See [Configuration](#configuration))
172
+ `live_reload_url` defaults to Vite's `http://localhost:5173`. Point it elsewhere if your dev server runs on a different port, or set it to a falsy value to disable live reload:
184
173
 
185
174
  ```ruby
186
175
  ReactEmailRails.configure do |config|
@@ -192,31 +181,7 @@ end
192
181
 
193
182
  ### Passing Props
194
183
 
195
- Top-level keys passed to `react:` become props on the component's default export. The API is intentionally close to [inertia-rails](https://inertia-rails.dev), so apps using both libraries should feel consistent.
196
-
197
- ```ruby
198
- mail(
199
- to: account.email,
200
- subject: "Welcome",
201
- react: {
202
- account: {
203
- name: account.name,
204
- },
205
- },
206
- )
207
- ```
208
-
209
- ```tsx
210
- type WelcomeProps = {
211
- account: {
212
- name: string
213
- }
214
- }
215
-
216
- export default function Welcome({ account }: WelcomeProps) {
217
- // ...
218
- }
219
- ```
184
+ Top-level keys passed to `react:` become props on the component's default export, as shown in the [Quick Start](#quick-start). The API is intentionally close to [inertia-rails](https://inertia-rails.dev), so apps using both libraries should feel consistent.
220
185
 
221
186
  ### Component Inference
222
187
 
@@ -249,7 +214,7 @@ class AccountMailer < ApplicationMailer
249
214
  end
250
215
  ```
251
216
 
252
- Action Mailer's framework assigns, including `params` and `rendered_format`, are excluded from instance props.
217
+ Action Mailer's internal assigns, such as `params` and `rendered_format`, are excluded from instance props.
253
218
 
254
219
  To make React the default for every action, set `default react: true` on the mailer (or `ApplicationMailer`). Each `mail` call then renders the inferred component without repeating `react: true`, and a single action can opt back out with `react: false`:
255
220
 
@@ -361,26 +326,12 @@ Every `react:` email receives `mailer` and `message` props, mirroring the [`mail
361
326
 
362
327
  ```tsx
363
328
  import type { Mailer, Message } from "react-email-rails"
364
- import { Body, Container, Html, Text } from "@react-email/components"
365
329
 
366
330
  type WelcomeProps = {
367
331
  account: { name: string }
368
332
  mailer: Mailer
369
333
  message: Message
370
334
  }
371
-
372
- export default function Welcome({ account, mailer, message }: WelcomeProps) {
373
- return (
374
- <Html>
375
- <Body>
376
- <Container>
377
- <Text>Welcome, {account.name}</Text>
378
- <Text>Re: {message.subject}</Text>
379
- </Container>
380
- </Body>
381
- </Html>
382
- )
383
- }
384
335
  ```
385
336
 
386
337
  | Prop | Example |
@@ -394,7 +345,7 @@ export default function Welcome({ account, mailer, message }: WelcomeProps) {
394
345
 
395
346
  Context is merged before prop serialization, so keys follow `config.transform_props` just like your own props. The exported TypeScript types describe the default `:lower_camel` shape.
396
347
 
397
- Per-mail and shared props win on conflict, so a prop named `mailer` or `message` overrides the injected context. Serializer props receive the context when `as_json` returns a hash. Collections, arrays, and other non-object values pass through unchanged so their top-level shape is preserved.
348
+ Per-mail and shared props win on conflict, so a prop named `mailer` or `message` overrides the injected context. When props come from a serializer, the context is merged in as long as `as_json` returns a hash; collections, arrays, and other non-object values pass through unchanged so their top-level shape is preserved.
398
349
 
399
350
  ### Prop Serialization
400
351
 
@@ -404,7 +355,7 @@ Prop keys are camelized by default, so `plan_name` arrives in React as `planName
404
355
 
405
356
  ### Component Files
406
357
 
407
- Files and directories starting with `_` are ignored as renderable email entries by default. Use them for shared components, layouts, and helpers:
358
+ Files and directories starting with `_` are excluded from the email component registry by default. Use them for shared components, layouts, and helpers:
408
359
 
409
360
  ```text
410
361
  app/javascript/emails/
@@ -422,7 +373,7 @@ Action Mailer layouts are not applied to `react:` emails. In React Email, layout
422
373
 
423
374
  ```tsx
424
375
  // app/javascript/emails/_components/email_layout.tsx
425
- import { Body, Container, Html } from "@react-email/components"
376
+ import { Body, Container, Html } from "react-email"
426
377
  import type { ReactNode } from "react"
427
378
 
428
379
  type EmailLayoutProps = {
@@ -442,7 +393,7 @@ export function EmailLayout({ children }: EmailLayoutProps) {
442
393
 
443
394
  ```tsx
444
395
  // app/javascript/emails/account_mailer/welcome.tsx
445
- import { Text } from "@react-email/components"
396
+ import { Text } from "react-email"
446
397
  import { EmailLayout } from "../_components/email_layout"
447
398
 
448
399
  export default function Welcome() {
@@ -526,7 +477,7 @@ Persistent mode details:
526
477
 
527
478
  ### Render Options
528
479
 
529
- `render_options` is passed to [@react-email/render](https://react.email/docs/utilities/render). Use `html` and `text` keys to configure each output. Option keys are camelized before they cross into JavaScript.
480
+ `render_options` is passed to [@react-email/render](https://react.email/docs/utilities/render). Use `html` and `text` keys to configure each output. Option keys are camelized before they cross into JavaScript, so `html_to_text_options` becomes `htmlToTextOptions`.
530
481
 
531
482
  ```ruby
532
483
  ReactEmailRails.configure do |config|
@@ -561,7 +512,7 @@ The callback receives the error plus render context such as `component:`.
561
512
 
562
513
  ### Instrumentation
563
514
 
564
- Every render emits `render.react-email-rails` through [ActiveSupport::Notifications](https://guides.rubyonrails.org/active_support_instrumentation.html). Payloads include `component` and successful HTML size in `html_bytes`.
515
+ Every render emits `render.react-email-rails` through [ActiveSupport::Notifications](https://guides.rubyonrails.org/active_support_instrumentation.html). Payloads include the `component` and, on success, the rendered HTML size in `html_bytes`.
565
516
 
566
517
  ```ruby
567
518
  ActiveSupport::Notifications.subscribe("render.react-email-rails") do |event|
@@ -574,18 +525,9 @@ end
574
525
 
575
526
  ### Vite Configuration
576
527
 
577
- Most apps only need the plugin from [Installation](#installation):
578
-
579
- ```ts
580
- import { defineConfig } from "vite"
581
- import { reactEmailRails } from "react-email-rails"
582
-
583
- export default defineConfig({
584
- plugins: [reactEmailRails()],
585
- })
586
- ```
528
+ Most apps only need the bare `reactEmailRails()` plugin from [Installation](#installation).
587
529
 
588
- The isolated renderer loads `reactEmailRails()`, JSX support, and component-facing Vite config such as `resolve`, `define`, `css`, `json`, `assetsInclude`, `esbuild`, and `oxc`. It does not load your other app plugins unless you explicitly add them with `vite.plugins`.
530
+ The isolated renderer loads `reactEmailRails()`, JSX support, and component-facing Vite config such as `assetsInclude`, `css`, `define`, `esbuild`, `json`, `oxc`, and `resolve`. It does not load your other app plugins unless you explicitly add them with `vite.plugins`.
589
531
 
590
532
  Server, preview, dependency optimization, and build output settings stay owned by react-email-rails so Rails can always find the renderer bundle.
591
533
 
@@ -617,7 +559,7 @@ reactEmailRails({
617
559
  })
618
560
  ```
619
561
 
620
- Component names come from the Vite directory layout. To map mailer actions to a different layout, override `component_path_resolver` on the Ruby side so both halves stay in sync.
562
+ Component names come from the file layout under `emails.path`. To map mailer actions to a different layout, override `component_path_resolver` on the Ruby side so both halves stay in sync.
621
563
 
622
564
  ### Email-Only Vite Plugins
623
565
 
@@ -653,7 +595,7 @@ reactEmailRails({
653
595
  })
654
596
  ```
655
597
 
656
- Externalized bundles can be smaller and may build faster, but the externalized packages must be available at runtime.
598
+ Externalized bundles can be smaller and may build faster, but the packages they reference must be available at runtime.
657
599
 
658
600
  ## Deployment
659
601
 
@@ -663,7 +605,7 @@ Production deploys should run the normal Rails asset task:
663
605
  bin/rails assets:precompile
664
606
  ```
665
607
 
666
- react-email-rails hooks `react_email_rails:build` into `assets:precompile`. The build task loads `reactEmailRails()` options from your Vite config and writes `tmp/react-email-rails/emails.js` with the email component registry.
608
+ react-email-rails hooks `react_email_rails:build` into `assets:precompile` (and `react_email_rails:clobber` into `assets:clobber`). The build task loads `reactEmailRails()` options from your Vite config and writes `tmp/react-email-rails/emails.js` with the email component registry.
667
609
 
668
610
  You can run the renderer build directly:
669
611
 
@@ -673,9 +615,9 @@ bin/rails react_email_rails:build
673
615
 
674
616
  Production rendering requires that bundle. If it is missing, rendering raises `ReactEmailRails::RenderError` and Action Mailer does not send the email.
675
617
 
676
- Set `SKIP_REACT_EMAIL_RAILS_BUILD=1` to skip the automatic asset hook. Directly running `bin/rails react_email_rails:build` always attempts the build.
618
+ Set `SKIP_REACT_EMAIL_RAILS_BUILD=1` to skip the automatic asset hooks. Directly running `bin/rails react_email_rails:build` always attempts the build.
677
619
 
678
- The npm package, Vite, React, and `@react-email/render` must be available when Rails runs `assets:precompile`.
620
+ The npm package, Vite, and React must be available when Rails runs `assets:precompile`.
679
621
 
680
622
  The Ruby gem and npm package must stay on the same version. A protocol/version handshake catches mismatched installs and raises an actionable `ReactEmailRails::RenderError`.
681
623
 
@@ -701,29 +643,9 @@ end
701
643
 
702
644
  If you check at boot, scope it to processes that send mail so the rest of the app does not pay the cost.
703
645
 
704
- ## Development
705
-
706
- See [CONTRIBUTING.md](CONTRIBUTING.md) for local setup, checks, formatting, and release verification.
707
-
708
- The short version:
709
-
710
- ```sh
711
- bundle install
712
- cd vite && pnpm install
713
- ```
714
-
715
- Run the core checks before opening a pull request:
716
-
717
- ```sh
718
- ruby scripts/check_version_sync.rb
719
- bin/test
720
- bin/lint
721
- cd vite && pnpm run build
722
- ```
723
-
724
646
  ## Contributing
725
647
 
726
- Bug reports and pull requests are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request so the local checks and release expectations are clear.
648
+ Bug reports and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for local setup, the checks to run before opening a pull request, and release expectations.
727
649
 
728
650
  ## Security
729
651
 
@@ -7,8 +7,7 @@ module ReactEmailRails::Generators; end
7
7
  class ReactEmailRails::Generators::InstallGenerator < Rails::Generators::Base
8
8
  JAVASCRIPT_PACKAGES = [
9
9
  "react-email-rails",
10
- "@react-email/render",
11
- "@react-email/components",
10
+ "react-email",
12
11
  "react",
13
12
  "react-dom",
14
13
  ].freeze
@@ -1,4 +1,4 @@
1
- import { Body, Container, Heading, Html, Text } from "@react-email/components"
1
+ import { Body, Container, Heading, Html, Text } from "react-email"
2
2
 
3
3
  export default function <%= @component_name %>() {
4
4
  return (
@@ -33,8 +33,8 @@ class ReactEmailRails::MailerContext
33
33
  def message_context
34
34
  message = mailer.message
35
35
 
36
- MESSAGE_FIELDS.each_with_object({}) do |field, context|
37
- context[field.to_s] = message.public_send(field)
36
+ MESSAGE_FIELDS.to_h do |field|
37
+ [field.to_s, message.public_send(field)]
38
38
  end
39
39
  end
40
40
  end
@@ -1,3 +1,3 @@
1
1
  module ReactEmailRails
2
- VERSION = "0.10.0"
2
+ VERSION = "0.11.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: react-email-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Supertape