winsoroaks
winsoroaksā€¢14mo ago

Uncaught Failed to analyze email/emailClient.js: Unexpected token '<'

hello team. sorry to keep bugging y'all. im running into
400 Bad Request: InvalidModules: Hit an error while pushing:
Loading the pushed modules encountered the following
error:
Uncaught Failed to analyze emailClient.js: Unexpected token '<'
400 Bad Request: InvalidModules: Hit an error while pushing:
Loading the pushed modules encountered the following
error:
Uncaught Failed to analyze emailClient.js: Unexpected token '<'
here's the code
"use node"

import { createElement } from "react"
import { v } from "convex/values"
import { Resend } from "resend"

import { internalAction } from "../_generated/server"
import ResendExampleTemplate from "../../react-email-starter/emails/resendExampleTemplate"

export const sendEmail = internalAction({
args: {
to: v.string(),
subject: v.string(),
},
handler: async (ctx, { to, subject }) => {
const emailTemplate = createElement(ResendExampleTemplate)

let message = {
from: "onboarding@resend.dev",
subject,
to,
}

if (process.env.NODE_ENV === "development") {
console.log("local email template: ", emailTemplate)
} else {
const resend = new Resend(process.env.RESEND_API_KEY)
return resend.emails.send({ ...message, react: emailTemplate })
}
},
})
"use node"

import { createElement } from "react"
import { v } from "convex/values"
import { Resend } from "resend"

import { internalAction } from "../_generated/server"
import ResendExampleTemplate from "../../react-email-starter/emails/resendExampleTemplate"

export const sendEmail = internalAction({
args: {
to: v.string(),
subject: v.string(),
},
handler: async (ctx, { to, subject }) => {
const emailTemplate = createElement(ResendExampleTemplate)

let message = {
from: "onboarding@resend.dev",
subject,
to,
}

if (process.env.NODE_ENV === "development") {
console.log("local email template: ", emailTemplate)
} else {
const resend = new Resend(process.env.RESEND_API_KEY)
return resend.emails.send({ ...message, react: emailTemplate })
}
},
})
i am currently installing the Resend module outside of the convex/ dir. (i cannot install this inside the convex/ dir since it would contain another node_modules folder). installing the Resend module outside of the convex/ dir allows me to run email dev --port 3001 to look at the email previews based on the guide: https://react.email/docs/getting-started/manual-setup. naturally i'd be doing
import ResendExampleTemplate from "../../react-email-starter/emails/resendExampleTemplate"
import ResendExampleTemplate from "../../react-email-starter/emails/resendExampleTemplate"
in the convex/emailClient.ts to import the template. alternatively i can just copy paste the files over from the react-email-starter/ folder to the convex/templates/ folder and do
// emailClient.ts
import ResendExampleTemplate from "./templates/resendExampleTemplate"
// emailClient.ts
import ResendExampleTemplate from "./templates/resendExampleTemplate"
what do y'all think?
21 Replies
ballingt
ballingtā€¢14mo ago
could you use .jsx as the extension in your file that uses React? (guessing that's what the unexpected < character is about) (or tsx) It should be ok either way, but installing a library and putting a file somewhere are two different things: installing a library with npm install resend adds it to the first node_modules/package.json in a parent directory. Since convex/ dir should never have either of these, installing a library should always go outside the directory, even if you run the command inside. You can still put the resendExampleTemplate inside the convex directory if you want.
winsoroaks
winsoroaksOPā€¢14mo ago
$ ls convex/email/ | grep "email"
emailClient.tsx

$ npm run dev:backend

> convex-my-project@0.1.0 dev:backend
> convex dev

āœ– Error: Unable to push deployment config to https://....convex.cloud
400 Bad Request: InvalidModules: Hit an error while pushing:
Loading the pushed modules encountered the following
error:
Uncaught Failed to analyze email/emailClient.js: Unexpected token '<'
$ ls convex/email/ | grep "email"
emailClient.tsx

$ npm run dev:backend

> convex-my-project@0.1.0 dev:backend
> convex dev

āœ– Error: Unable to push deployment config to https://....convex.cloud
400 Bad Request: InvalidModules: Hit an error while pushing:
Loading the pushed modules encountered the following
error:
Uncaught Failed to analyze email/emailClient.js: Unexpected token '<'
ballingt
ballingtā€¢14mo ago
Hm, bummer. But that file extension shouldn't matter, what matters is the file extension where you use jsx syntax. Do all files where you use React angle brackets use .jsx or .tsx?
winsoroaks
winsoroaksOPā€¢14mo ago
i believe so. esp the files that involve the email templates
ballingt
ballingtā€¢14mo ago
We'd like to open up the esbuild config used to compile Convex files a bit for advanced users but haven't done it yet for plug and play simplicity. But if we can't get things like this working in all situations that'll be the next step. Any obvious differences between this and the little example I made, https://github.com/thomasballinger/convex-html-email-example/blob/main/convex/email.tsx
GitHub
convex-html-email-example/convex/email.tsx at main Ā· thomasballinge...
Contribute to thomasballinger/convex-html-email-example development by creating an account on GitHub.
winsoroaks
winsoroaksOPā€¢14mo ago
the same file works if it lives in the convex/ dir
ballingt
ballingtā€¢14mo ago
eg are you importing React? import * as React from 'react oh!
winsoroaks
winsoroaksOPā€¢14mo ago
import * as React from "react"
import { Button, Html } from "@react-email/components"

export default function ResendExampleTemplate() {
return (
<Html>
<Button
href="https://example.com"
style={{ background: "#000", color: "#fff", padding: "12px 20px" }}
>
Click me
</Button>
</Html>
)
}
import * as React from "react"
import { Button, Html } from "@react-email/components"

export default function ResendExampleTemplate() {
return (
<Html>
<Button
href="https://example.com"
style={{ background: "#000", color: "#fff", padding: "12px 20px" }}
>
Click me
</Button>
</Html>
)
}
yes
ballingt
ballingtā€¢14mo ago
interesting, huh
winsoroaks
winsoroaksOPā€¢14mo ago
should i remove it? it only fails if it lives in the parent dir / outside of convex dir
ballingt
ballingtā€¢14mo ago
Huh! Ok then maybe different tsconfig.json setting are being used by esbuild for these different locations (I think tsconfig.json is the only file that effects this and could be different) you don't have a package.json in the convex directory by chance? Next I'd compare these two tsconfig files or to unblock you fir now, does it work to keep this templates directory inside the convex directory? hopefully whatever that email dev --port command takes a location to look for these templates? Or you suggested solution works
winsoroaks
winsoroaksOPā€¢14mo ago
oops out of luck,
The following mandatory changes were made to your tsconfig.json:

- jsx was set to preserve (next.js implements its own optimized jsx transform)
The following mandatory changes were made to your tsconfig.json:

- jsx was set to preserve (next.js implements its own optimized jsx transform)
yes i'll do copy paste. i'd def love to see a preview of the email templates thanks tom šŸ™‚
ballingt
ballingtā€¢14mo ago
ooo ok if this is a next.js issue other folks are going to hit it, thanks for bringing this up!
winsoroaks
winsoroaksOPā€¢14mo ago
more like a resend stuff. resend creates their own module
No description
ballingt
ballingtā€¢14mo ago
oh cool, I'll do a more involved example so we have a test if this. Once bundled files include code from separate projects but included by imports this gets more complicated. might be a bit longer then but we'll figure something out! worst case a bit more config will be required, which is something folks have asked for anyway.
winsoroaks
winsoroaksOPā€¢14mo ago
no problem! not blocking šŸ™‚
ballingt
ballingtā€¢14mo ago
Oh also note that NODE_ENV isn't going to work in Convex ā€” it's always development for now! So you'll want to set your own environment variable here for conditional env/prod behavior.
winsoroaks
winsoroaksOPā€¢14mo ago
yes. im aware of that
Smurfens
Smurfensā€¢8mo ago
Hi! I am running in to the same problem, as mentioned above, trying to use Resend. Any update on the matter?
Michal Srb
Michal Srbā€¢8mo ago
You need to put the JSX file somewhere in the convex folder (and make sure the file that contains JSX has .jsx or .tsx extension). Check your tsconfig.json too: https://github.com/thomasballinger/convex-html-email-example/blob/main/convex/tsconfig.json#L21
GitHub
convex-html-email-example/convex/tsconfig.json at main Ā· thomasball...
Contribute to thomasballinger/convex-html-email-example development by creating an account on GitHub.
Smurfens
Smurfensā€¢8mo ago
Thanks for getting back to me and the link, will check it out asap. Love the product btw!

Did you find this page helpful?