revivek / oy Goto Github PK
View Code? Open in Web Editor NEWRender HTML emails on the server with React.
License: MIT License
Render HTML emails on the server with React.
License: MIT License
See the section titled "Avoid shorthand for fonts and hex notation".
https://www.campaignmonitor.com/resources/will-it-work/guidelines/
Follow up to #50
We use Oy for sending internationalized emails, including in RTL languages like Hebrew and Arabic.
For best results, we need to control the generated HTML's "lang" and "dir" attributes (see this).
Seems like the natural way would be to pass "lang" and "dir" as arguments to HTML4.generateDefaultTemplate, and (if given) add them as <html> tag attributes in that function.
I can submit a pull request if you want. Should be a pretty straightforward change though :)
It's currently difficult to see what tests are run and in what order.
I am using sendgrid to send emails
When I pass in the string of HTML generated by the renderTemplate function the HEAD css gets stripped out.
We provide a default email base template, although it may not be best or desired for others. Oy.renderTemplate
should take an optional new function parameter to return a HTML string.
Hey Vivek,
I have a react project and I would like to use this with css-modules styles.
Have you used it with that in the past ?
Regards,
Andrei
Hi,
I am wondering if it is possible to send the rendered html as an email using oy? If so, any example will be very helpful.
thanks in advance.
I'm possibly missing something obvious here, but I can't seem to get this working with my Meteor application. After running meteor npm install oy-vey
, I get the following error on the server anytime I include import Oy from 'oy-vey';
anywhere in the server code:
Error: Cannot find module './components/DefaultElement'
at makeMissingError (packages/modules-runtime.js:221:12)
at require (packages/modules-runtime.js:231:19)
at meteorInstall.node_modules.oy-vey.lib.Oy.js (packages/modules.js:3377:23)
at fileEvaluate (packages/modules-runtime.js:333:9)
at require (packages/modules-runtime.js:228:16)
at meteorInstall.server.main.js (server/main.js:1:70)
at fileEvaluate (packages/modules-runtime.js:333:9)
at require (packages/modules-runtime.js:228:16)
at /~/.meteor/local/build/programs/server/app/app.js:7482:1
at /~/.meteor/local/build/programs/server/boot.js:338:34
I don't get that error if I import the package from the client code, but I obviously want to run it on the server so that I can render a string of html before sending an email. Any suggestions?
Excellent suggestion by @rafikk.
Going in 0.4.0 release.
previewText
is an required option, but as far as I can tell it's just added to an invisible <span>
. It's not clear to me why it's necessary or what's it's use really.
Whats the problem with omitting that invisible element? Which clients benefit from it and what is a good/correct previewText
?
Can you clarify, please?
Part of 0.4.0 release.
It's recommended to keep the delivered HTML to smaller than 100KB, to avoid getting emails cut off or rejected due to spam.
This would go into Oy.renderTemplate
.
Hi in my case I want to get rid of the annoying blue colored links set on Apple devices. In order to achieve that I would have to add the following meta tag to my email template:
< meta name="format-detection" content="email=no" >
So in general it would be nice if we could add meta tags just as we could add title.
This issue seems to be new, and may well be Google's fault.
Apparently emails that are set as RTL are shown in the wrong size. I don't know whether it's the "correct" size which fails to get scaled down like it always does, or whether it's scaled up for some reason, but the content is stretched beyond the screen's width and cannot be scrolled to.
This doesn't happen on PCs or iPhones, and happens only when the direction is RTL.
You can see it happening with this basic code:
<Table style={{width: '600px', height: '50px', background: '#CCC', 'text-align': 'center'}}>
<TBody><TR><TD style={{width:'600px'}}>Hello</TD></TR></TBody>
</Table>
If Oy is rendered with dir: LTR then everything is fine, but with dir: RTL the whole thing is scaled up, and the centered text can be seen close to the edge. (You can tell it's not an issue with the text's position because the grey background goes all the way to the screen's edge and beyond, instead of the whole thing having a margin like it usually does)
One that demos all levels of the architecture:
To be consistent with other web codebases.
I've experimented with this a bit myself with an in-house solution to building HTML emails with React, but I think fleshing out Oy is better than everyone reinventing wheels.
As we all know, developing responsive emails is an utter pain in the ass. Alongside React solutions, i've also tried things like Foundation for Emails and BeeFree. None of them work particularly well. I think React solutions are the way to go, and Oy seems like a decent starting point.
Something Foundation does well is provide layout primitives as an abstraction over tables. But unfortunately you're also left to fend for yourself as soon as you want to do any customisation. I'd like to see Foundation's primitives adapted to fit React, so we can benefit from existing patterns for inlining styles, e.g. Radium.
If you forget to set the dimensions for each image, a number of clients will invent their own sizes when images are blocked and break your layout. Also, ensure that any images are correctly sized before adding them to your email. Some email clients will ignore the dimensions specified in code and rely on the true dimensions of your image.
"Always include the dimensions of your image"
https://www.campaignmonitor.com/resources/will-it-work/guidelines/
hey guys
on my templates there is no props so no props.children if I use plain JS instead of JSX
Layout = require "./layout"
Header = require "./header"
Footer = require "./footer"
Title = require "./title"
Body = require "./body"
Button = require "./button"
Separator = require "./separator"
Template = (props)=>
Layout {},
Header {lang:lang}
Separator {height:20}
Title
title: "et-verify-email-welcome"
lang:lang
Separator {height:20}
Body
body: "et-verify-email-description"
lang:lang
Separator {height:20}
Button
title: url
url: url
lang:lang
Separator {height:20}
Footer {lang:lang}
HTML = RenderTemplate(Template(),{
title: translate "et-verify-email-subject", null , null , lang
previewText: translate "et-verify-email-subject", null , null , lang}
)
I'm using something like this.
and getting this.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
dir="ltr"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width"/>
<title>Title</title>
<style type="text/css">
#__bodyTable__ {
margin: 0;
padding: 0;
width: 100% !important;
}
</style>
<!--[if gte mso 9]>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![endif]-->
</head>
<body bgcolor="#FFFFFF" width="100%" style="-webkit-font-smoothing: antialiased; width:100% !important; background:#FFFFFF;-webkit-text-size-adjust:none; margin:0; padding:0; min-width:100%; direction: ltr;">
<table bgcolor="#FFFFFF" id="__bodyTable__" width="100%" style="-webkit-font-smoothing: antialiased; width:100% !important; background:#FFFFFF;-webkit-text-size-adjust:none; margin:0; padding:0; min-width:100%">
<tr>
<td align="center">
<span style="display: none !important; color: #FFFFFF; margin:0; padding:0; font-size:1px; line-height:1px;">Title</span>
<table width="100%" style="-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;mso-table-lspace:0pt;mso-table-rspace:0pt;border-collapse:collapse;margin:0px auto;" align="center"></table>
</td>
</tr>
</table>
</body>
</html>
layout.coffee
Oy = require "oy-vey"
{ Table, TBody, TR, TD, Img, A } = Oy
module.exports = (props) ->
return Table
width:"100%"
align:"center"
style:
WebkitTextSizeAdjust: '100%'
msTextSizeAdjust: '100%'
msoTableLspace: '0pt'
msoTableRspace: '0pt'
borderCollapse: 'collapse'
margin: '0px auto'
,
TBody {}, TR {}, TD {align:"center"},
Table
width: 300
align: "center"
style:
WebkitTextSizeAdjust: '100%'
msTextSizeAdjust: '100%'
msoTableLspace: '0pt'
msoTableRspace: '0pt'
borderCollapse: 'collapse'
margin: '0px auto'
,
TBody {}, TR {}, TD {align:"center"}, props.children
So am I doing somthing wrong or? any idea?
3 digit hex color codes are not uniformly supported across some legacy email clients.
Currently this library is using CleanCSS to minify provided CSS, which uses 'shorthand compacting' to convert 6 digit hex color codes to 3 digit hex color codes where appropriate.
Given that this library is focused on email rendering, it may make sense to set the CleanCSS' shorthandCompacting option to false by default. Alternatively allowing the user to configure which options a provided to the CleanCSS constructor may be useful and provide the desired functionality where required.
i.e. Allow <table>
versus requiring <Table>
. This would cut the API for usage down to one function: Oy.renderTemplate
.
See subject ^, thanks!
hey there!
if I'm using inline images I got this warning.
Thanks!
Cya crazyx13th
I am trying to configure Go-To-Actions in my emails but not having much luck. Does this library support that capability?
I have also tried leveraging React Helmet inside my emails but no luck. The emails send but no actions appear to the end user.
<Email>
...
<Helmet>
<script type="application/ld+json">
{`
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://watch-movies.com/watch?movieId=abc123",
"name": "Watch movie"
},
"description": "Watch the 'Avengers' movie online"
}
`}
</script>
</Helmet>
...
</Email>
I have stateful components that do work before being ready (wait some data to load, rendering into canvas and then in a base64 image, etc..).
I don't want to move my state in top of the tree because it loses the modularity of components. (and it wouldn't be easy in my usecase anyway)
is it possible we can do this with Oy ?
If not, what is the difference between Oy.renderTemplate
and doing ReactDOM.render(vdom,container)
and then container.innerHTML
? (can I do the extra stuff that Oy.renderTemplate is doing but using ReactDOM.render ?)
Thanks
Remove line and bump to 0.2.1.
Funny enough, I saw someone star this project on my GitHub's homepage and I also happen to own oy
on npm.
Since I never found a use for the package, and don't think I will any time soon, I'm willing to transfer ownership to the creator(s) of this project.
Just thought I might throw that offer out there.
(This issue might also exist in services other than gmail)
When rendering an email with dir: 'rtl', the email is not displayed correct in gmail.
I solved this by adding "direction: ${dir}" to the tag's style.
Hi would be great to have .d.ts files for this project. Would you happen to already have that and be able to share?
Thanks,
-Jeff
The react-htmt-email project features a great approach to validating styles based on a map of allowed/supported email clients. I like how Oy has very useful custom propTypes for markup, but as of now only one ShorthandFontRule actually validates style.
Would be ideal to borrow that repo's approach in order to configure a style validator the same way for Oy.
Thoughts?
React is logging these warnings every time we render templates. Table seems to have border as a default prop which is causing this warning.
I think it should be safe to remove since according to React docs unknown props are stripped, so the default border prop is never actually getting rendered anyway.
Using react version 15.5.4
After adding standard propTypes definition on a component, I receive multiple warnings during render. For example:
"Warning: You are manually calling a React.PropTypes validation function for the heading
prop on ReportHeader
. This is deprecated and will not work in the next major version. You may be seeing this warning due to a third-party PropTypes library. See https://fb.me/react-warning-dont-call-proptypes for details."
Had to remove deleting the prop due to React throwing errors on modified props (as it should). This means type="table"
or the like leaks to the rendered child element, increasing filesize and in general not being useful.
How would you set the body background color?
Thanks!
All HTML4.generateDefaultTemplate
arguments are added directly to the raw HTML.
While not a vulnerability per se, it opens up an attack vector against careless users who directly pass unsanitized user-generated values, which unfortunately is a common scenario.
Consider escaping these values as a best effort to protect Oy users.
See #55.
As of June 10, 2015, we can remove the data-*
attributes that get search and replaced (data-bgcolor
, data-align
, etc.) to the HTML4 variants. We can use the is
property. This should also fix an unlikely but still possible bug resulting from the current search and replace strategy: since we operate on the raw string, all of data-background and its cousins would be replaced. This means an HTML5 newsletter writing about how "AlignerFoo.js uses data-align to align your elements" would turn into "AlignerFoo.js uses align to align your elements."
facebook/react#140 (comment)
facebook/react#3752
To do:
data-*
attributes from OyTable
, OyImg
, etc.is
attribute before those removed data-*
attributes.data-*
attributes in utils/HTML4.js
I'm curious as to why this module forces the body
background to be white? And also being an inline styles, this takes precedence over any headCSS
passed in. I have an email that has a full page blue background, and I'm unable to edit this without editing the node_module
.
Great idea! This would save a lot of time for my team.
I'm facing an issue while using the imported react component. What is going wrong here?
Is this related to how the component needed to be done?
var React = require('react');
var Oy = require('oy-vey')
const {Table, TBody, TR, TD} = Oy;
var tempalte = require('../views/emails/react/template.jsx');
const html = Oy.renderTemplate(<Template />, {,^, SyntaxError: Unexpected token <, at Object.exports.runInThisContext (vm.js:73:16), at Module._compile (module.js:543:28), at Object.Module._extensions..js (module.js:580:10), at Module.load (module.js:488:32), at tryModuleLoad (module.js:447:12), at Function.Module._load (module.js:439:3), at Module.require (module.js:498:17)
Component - template.jsx
//switched to require instead of import.
var React = require('react');
var { Grid, Row, Col } = require('react-flexbox-grid');
const {Table, TBody, TR, TD} = Oy;
export default (props) => {
//a lot of lines that return react code
}
I have also noticed Illegal export declaration error.
From https://facebook.github.io/react/docs/reusable-components.html
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
}
}
Thing is, we don't use propName
and componentName
. We might want to refactor them out to increase readability.
I just wasted an impressive amount of time trying to figure out why oy
didn’t have a renderTemplate
method. Turns out I had installed the wrong oy
. Looks like @cistov beat you all to that URL by a few years.
oyvey
and oy-vey
are available. Installing from Github works pretty well, too.
Aaaaaaaaaanyways. if you need me, I’ll be over here, yelling into a pillow until my yeller can’t yell no more.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.