Skip to content

fix(editor): keep the default theme import in EmailEditor's published output - #3708

Open
dudusotero wants to merge 2 commits into
resend:canaryfrom
dudusotero:fix/editor-theme-css-import
Open

fix(editor): keep the default theme import in EmailEditor's published output#3708
dudusotero wants to merge 2 commits into
resend:canaryfrom
dudusotero:fix/editor-theme-css-import

Conversation

@dudusotero

@dudusotero dudusotero commented Aug 17, 2026

Copy link
Copy Markdown

Summary

EmailEditor is documented as importing @react-email/editor/themes/default.css on its own, and src/email-editor/email-editor.tsx has import '../ui/themes/default.css' for that. The import never reaches the published package: tsdown extracts the CSS into dist/style.css, drops the import from dist/index.mjs / dist/index.cjs, and dist/style.css is not in exports, so nothing can load it. Every published version ships this way, so <EmailEditor /> renders an unstyled bubble menu and slash command menu unless the app imports the theme itself. #3637 reported the orphan dist/style.css; #3638 removed the dangling ./styles/* export entries but the stylesheet is still unreachable. apps/web does not hit this because apps/web/src/app/editor/layout.tsx imports the theme explicitly.

css: { inject: true } from @tsdown/css is not enough here: it keeps the import in the ESM output but also writes a literal import './style.css' into the .cjs file, which breaks the CJS entry. This PR instead adds a small Rolldown plugin to tsdown.config.ts that treats every CSS import under src/ as external and rewrites it to the matching public entry from package.json exports. ../ui/themes/default.css becomes @react-email/editor/themes/default.css, which scripts/copy-css.ts already emits into dist/. The build now produces:

dist/index.mjs:  import "@react-email/editor/themes/default.css";
dist/index.cjs:  require("@react-email/editor/themes/default.css");

Only the root entry gets the import; the other subpaths are unchanged, dist/style.css is no longer emitted, and importing a CSS file that has no exports entry fails the build with a message pointing at the import. Nothing under src/ changes.

One consequence to be aware of: Jest setups without a CSS moduleNameMapper, and plain Node scripts importing @react-email/editor without a bundler, will now hit the CSS import on the root entry. If keeping the theme opt-in is preferred, the alternative is to remove the import from email-editor.tsx, stop emitting dist/style.css, and update the docs; I can switch the PR to that.

Test plan

  • pnpm build (with dts) and pnpm typecheck in packages/editor pass
  • pnpm test:unit: 50 files, 502 tests pass
  • biome check clean
  • Packed the build with pnpm pack and installed it in a Vite + React 19 app with no CSS import of its own: Vite loads ui/themes/default.css from the package and the menus render styled. The same app renders unstyled against the published 1.7.2.

Summary by cubic

Ships the default theme CSS with EmailEditor so bubble and slash menus are styled by default. The build now keeps the import in both ESM and CJS by rewriting CSS imports to exported subpaths; previously the import was extracted to an unexported file and menus rendered unstyled unless apps imported @react-email/editor/themes/default.css.

  • Review and migration
    • Confirm package.json exports include ./themes/default.css and that only the root entry imports it.
    • No dist/style.css is emitted; the build fails if a CSS import lacks an exports entry.
    • Jest or plain Node consumers must handle CSS imports (stub/map .css); bundler apps need no changes.

Written for commit f2c34fb. Summary will update on new commits.

Review in cubic

@changeset-bot

changeset-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f2c34fb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@react-email/editor Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

@dudusotero is attempting to deploy a commit to the resend Team on Vercel.

A member of the Team first needs to authorize it.

@dudusotero
dudusotero changed the base branch from main to canary August 17, 2026 22:35
@github-actions github-actions Bot added the linear-synced PR has been synced to Linear label Aug 18, 2026
@pkg-pr-new

pkg-pr-new Bot commented Aug 23, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@react-email/editor@3708

commit: f2c34fb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

linear-synced PR has been synced to Linear

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant