react-email icon indicating copy to clipboard operation
react-email copied to clipboard

Hot Reload not working when modifying components imported in the email files (when using path aliases)

Open NickTiut opened this issue 10 months ago β€’ 4 comments

Describe the Bug

I have the following file structure:

react-email-bug/
┣ emails/
┃ ┣ _components/
┃ ┃ ┣ footer.tsx
┃ ┃ ┣ layout.tsx
┃ β”— generic.tsx
┣ node_modules/
┣ package-lock.json
┣ package.json
β”— readme.md

When I modify anything in footer.tsx (or layout.tsx), the dev server outputs βœ” Successfully rendered footer.tsx in 236ms but does not re-render generic.tsx that imports both of those components.

Which package is affected (leave empty if unsure)

react-email

Link to the code that reproduces this issue

https://github.com/NickTiut/react-email-bug

To Reproduce

Run npm run dev on the example provided. Modify anything in the _components/layout.tsx or _components/footer.tsx files. Web client does not update. If you restart the dev server, the changes are picked up.

Expected Behavior

Any change to the components should be reflected instantly on the web client.

What's your node version? (if relevant)

20.4.0

NickTiut avatar Jan 20 '25 16:01 NickTiut

We do support hot reloading for changing files imported into an email template, but we don't support TypeScript's path aliases, that seems to be the issue in your case.

gabrielmfern avatar Jan 22 '25 15:01 gabrielmfern

@gabrielmfern Thanks for the clarification. Will it be supported in the future? I'm sure path aliases are widely used.

NickTiut avatar Jan 22 '25 19:01 NickTiut

Hot Reloading also does not work for subpath imports such as, for example:

import Button from '#common/emails/_components/Button.js'

Charioteer avatar Jan 23 '25 12:01 Charioteer

Similar to what @Charioteer said. Hot reloading doesn't seem to work for ESM/Typescript projects in general. Specifically when importing paths like: import { Button } from './components/button.component.js' Or: import { Button } from './components/button.component.jsx' While the filename is: button.component.tsx

EmericW avatar Feb 13 '25 15:02 EmericW

I came across a similar issue. If I imported my component like import { Cmp } from './_components/cmp.tsx' , hot reloading wouldn't work and I'd get an error in my dev console

β¨― [TypeError: Cannot read properties of undefined (reading 'PreviewProps')] {
  digest: '1844140163'
  β Ό Rendering email template cmp.tsx

At which point it would just hang, but if I restarted the dev server then all would be fine.

I've now switched to the default export from my component file, so I import like import Cmp from from './_components/cmp.tsx'. Hot reloading now works. There's still an error in the logs but doesn't impede functionality as far as I can tell.

βœ– Failed while rendering cmp.tsx
  βœ” Successfully rendered SampleEmail.tsx in 335ms

smallbellows avatar Apr 02 '25 17:04 smallbellows

I was seeing a similar issue as @smallbellows. As long as I export a default from each of my components, I no longer get that error and hot module reloading appears to work with one caveat.

the CLI shows that it failed to when rendering my child component but then shows the re-render of the full template working as expected.

 βœ– Failed while rendering AgentInfo.tsx
 βœ” Successfully rendered market-report.tsx in 242ms

relevant package versions

{
  "@react-email/components": "0.0.35",
  "react-email": "4.0.3",
  "react": "18.3.1",
  "react-dom": "18.3.1",
}

derekaug avatar Apr 02 '25 20:04 derekaug

Same here. as a workaround just make sure all your files you import from have any export default

jony89 avatar Apr 12 '25 10:04 jony89

I'm not sure if it's the same issue, but I’ve encountered the following problem: I have a file located at emails/transactional/activate-account.tsx. Hot reload doesn’t work when I make changes to activate-account.tsx in that path. However, if the file is placed directly in the emails folder, hot reload works as expected. I'm using export default in activate-account.tsx. UPDATE: I've encountered this issue only with the latest version of react-email. I'll create a repository with the bug and open a new issue later.

a-gunderin avatar May 05 '25 21:05 a-gunderin

The hot reload is not working in a monorepo (Turborepo) which the components are in another package in the repo.

EX:

src/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ email/ -> React Email app
β”‚   └── ...
└── packages/
    β”œβ”€β”€ templates/
    β”‚   β”œβ”€β”€ components/
    β”‚   β”‚   └── component.tsx
    β”‚   β”œβ”€β”€ index.ts
    β”‚   └── package.json
    └── ...

The component is imported as follows:

import { Component } from "@repo/templates";

I've tried the default export/import, but seems not to be supported ether.

LuanRoger avatar May 05 '25 21:05 LuanRoger

Can you all try this with [email protected]? It should have it fixed, and it works on my testing

gabrielmfern avatar May 12 '25 18:05 gabrielmfern

I can confirm my case is fixed. Thanks πŸ™

EmericW avatar May 13 '25 07:05 EmericW

I'm not sure if it's the same issue, but I’ve encountered the following problem: I have a file located at emails/transactional/activate-account.tsx. Hot reload doesn’t work when I make changes to activate-account.tsx in that path. However, if the file is placed directly in the emails folder, hot reload works as expected. I'm using export default in activate-account.tsx. UPDATE: I've encountered this issue only with the latest version of react-email. I'll create a repository with the bug and open a new issue later.

@a-gunderin I tracked this myself at https://github.com/resend/react-email/issues/2242

francescosalvi avatar May 15 '25 07:05 francescosalvi

I also just found this issue after facing similar issue of components not triggering the render. I am also using TypeScript's path aliases.

Canary build seems to have fixed the issue.

ayhanap avatar May 19 '25 20:05 ayhanap

Seems like this has been fixed as of [email protected]

gabrielmfern avatar Jul 10 '25 19:07 gabrielmfern