sofn-xyz / mailing

Build, test, send emails with React
https://www.mailing.run
MIT License
3.6k stars 74 forks source link

Generate proper project boilerplate on init #75

Open mrlubos opened 1 year ago

mrlubos commented 1 year ago

Similarly to other tools such as CRA, it would be nice if mailing generated a complete project boilerplate including package.json and README describing which scripts are available and what they do. The project currently makes some assumptions about how the user runs and serves the templates (e.g. no build command for raw HTML), this should be documented too.

psugihara commented 1 year ago

The project definitely makes the assumption that you're using it in a react app and we've tested with next.js, redwood, and remix (in js and ts). A standalone mode with project generation would be great.

This goes well with https://github.com/successor-software/mailing/issues/69 and I think would have helped in #60

Can you tell me a bit about your use-case and what input/output you're looking for? I saw that you're also interested in the API idea... where would you want to host that?

Thanks @mrlubos!

mrlubos commented 1 year ago

@psugihara Sure. I have an existing project where I created my own "mailing" package and used it to develop email templates. Our email infrastructure definitely needs some love, but it is what it is, so... we have a client written in TypeScript (CRA boilerplate), server written in Python (FastAPI), and emails hosted in SendGrid. The server sends requests to SendGrid with customization data and SendGrid fetches the correct template and delivers it.

At the moment, I am looking to replace my custom "mailing" package with mailing without modifying our infrastructure. I could live with the explicit React imports, but inability to generate raw HTML is a blocker right now. My implementation uses babel with a bunch of presets to output plain HTML which I can manually copy-paste into SendGrid UI. I don't mind how you generate the HTML, I just need the ability to do that.

My project is hosted in a monorepo, so it's important that I can configure where to output the HTML. In my scenario, I may be hosting emails in packages/emails, but the output should go to build/emails. Lastly, and I haven't tested this yet, I need to be able to inject environment variables into mailing. For example, the transport constant you have in your boilerplate accepts auth.pass value. This should be injected at runtime as process.env.MY_AUTH_PASS so I don't check secrets into version control.

Hope this helps, but let me know if you have more questions!

psugihara commented 1 year ago

Got it, really appreciate all of that context. It seems like the biggest blocker is that you can't export the HTML.

A few ideas...

  1. As of 0.6.2, there's now a render function exported from mailing-core that will render mjml-react components you pass it. You can see it in action here.
  2. We could easily add a build command that would compile the emails/previews to html in a user-specified build directory. Something like mailing build-previews.
  3. Prioritize a server mode like #58, but since you're working in TS I'm guessing it's easier to use the library directly with render (2).
  4. We could show the HTML in the preview server UI.

Would one of those work well for you? For something like 2 or 4, would hardcoded props in the preview functions work or do you have dynamic props you want to render with (I'm guessing from the sendgrid UI copy/paste that it's pretty static)?

One curiosity... why do you copy the HTML into the sendgrid UI rather than sending from your app code via smtp?

Also, environment variables should work just fine in the templates but LMK if you see issues.

mrlubos commented 1 year ago

@psugihara i will have a look over the weekend/next week and respond, thanks for the suggestions!

psugihara commented 1 year ago

sounds good. excited to help get you up and running.

On Aug 3, 2022, at 5:35 PM, Lubos @.***> wrote:

 @psugihara i will have a look over the weekend/next week and respond, thanks for the suggestions!

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.

mrlubos commented 1 year ago

@psugihara I looked at your suggestion and my assessment is:

Please let me know how likely you're to add 2 to mailing, otherwise I may go with 1.

You're right, static props will work for me. Due to the integration with SendGrid, I use the handlebars templating language to inject variables into templates. None of the features you list would break this workflow.

Why do I copy? Laziness, I guess. It started as a single template, copy-paste one more, and one more, you know how it goes. At this point I would definitely benefit from some automation but it's not clear what benefits this would give me. I rarely need to update multiple templates and making one-off changes is fast and straightforward with the current approach.

I am currently considering moving templates into the server code, curious if you have any thoughts on that. The challenge is that our server is written in Python, so the communication with templates would have to happen through HTML files. This is fine, but it means I will definitely need the ability to output HTML. In addition to that, I need an automated way to update templates inside the server code. One of my ideas at the moment is outputting the HTML files into the server project and update handlers with new variables as needed. Ideally, my templates would be consumed as a package so I always know which version I'm running, but I am not sure how to achieve that. I also want to avoid creating a complex setup just to gain this single benefit, so it would have to be reasonably simple to implement.

psugihara commented 1 year ago

@mrlubos thanks, great info.

Yes we will definitely ship #2 in the next few days. I'll ping here when it's ready.

Your setup totally makes sense and I understand the copy pasting now. I like the idea of having my templates tested and under source control, but there's a nice simplicity to your setup and most importantly it's working.

mrlubos commented 1 year ago

@psugihara Thanks! Would it be possible to have a pre-render step? Or maybe a different approach if you can think of anything. This is related to Handlebars I mention above. Imagine I write my whole template in mjml and add some Handlebars to it. The standard way to do that is with MjmlHtml component. This will work once rendered and used with SendGrid, but it looks really strange in preview because it doesn't support Handlebars. My thinking with pre-render step is I could receive the input and pipe it into Handlebars before returning the output. This should work for both dev and build steps

psugihara commented 1 year ago

Cool idea, I think I'm following.

What would you imagine as an interface for the pre-render step? One idea would be using a mailing.config.js rather than mailing.config.json (similar to next.config.js) and letting you specify a hook. Could look something like this...

module.exports = {
  emailsDir: 'packages/mailing',
  previewExportDir: 'build/emails',
  htmlTransformHook: (htmlString) => myTransformation(htmlString)
};

Then the preview server would run that hook right after it compiled the react to html and use the output wherever it would normally use html.

Just spitballing a solution, but lmk if it seems like I understand your idea.

mrlubos commented 1 year ago

@psugihara my initial idea was to have an array of plugins, but this would work too. I'm convoluting multiple ideas in this thread, sorry! Maybe this could be discussed once we get all these other issues sorted out