HTML-report with chrome-image report as child

  • Hi.
    I need to render html for an email. The html includes an image and some SVG. SVG is not widely supported in email clients, so I need to convert part of the report to an image.

    Here is roughly what I want to do:

    1. Main report is html recipe
    2. Child report is chrome-image recipe
    3. Embed child in an img-tag in the mail report
    4. Also, I'd like to get higher resolution of the image

    Q1: What is the syntax for using a chrome-img report in an img-tag?

    The image I get from the child report seems to be binary. Is there any way of getting it as base64? In that case the below might work?

      <img src=src='data:image/jpeg;base64, {#child child_image_with_svg @data.drawing$={{{childTemplateSerializeData ../this}}} @data.controlpoint$={{{childTemplateSerializeData ./this}}} }'>

    Q2. What is the easiest way of increasing the resolution of the chrome-image file?

    • Should I use width and height of the SVG container in the child report?

  • Please, I need to know if this is possible to solve. Otherwise I need to get started with a more complicated solution, i.e. send my SVG via a separate service to convert them to images. I'd rather not go down this route, because it would give me a logistics problem when there are many SVGs for many places in the report.

    It would be really awesome if jsreport could solve this. It already seems to be really close.

    • The best solution would be if this could be solved with the #child command, maybe in combination with #asset (which has encoding support).
    • Otherwise I'm wondering if there is some way to transfer the result from a #child call into a helper. I could manually convert it to Base64 and prepend with the needed URI stuff if I could just get hold of the binary buffer.

  • I found a solution. But I'd really like to know if it's a "hack" or an "ok" solution. Didn't find much documentation of afterRender(), but I got this working:

    Is it ok to completely alter res.content? Will I get into trouble for mutating the content?

    function afterRender(req, res, done) {
      res.content = Buffer.from(res.content).toString('base64');

  • You have found a very nice solution!

    The primary purpose of afterRender is to modify the res.content. So it isn't a hack.

  • Thanks Jan!
    As usual, the flexibility of jsreport delivers.
    I'm really glad that I opted for jsreport when I evaluated my options.

    To my joy, I also found that the recipe settings stays in the template even if I change the recipe. I.e. I can switch to chrome-image in Studio and set jpg quality to 90%. This chrome-image-setting stays in the template even I switch back to html in Studio.

    I ended up with a little more flexible solution, allowing me to use the same child template both as html (when rendering pdfs) and as image (when rendering html emails).

    function afterRender(req, res, done) {
      if(req.template.recipe === 'chrome-image') {
        res.content = Buffer.from(res.content).toString('base64');

    Any idéas for Q2?
    I'm still struggling with the image resolution. I tried to increase the svg size in the child. This works, but I cannot get "object-fit: contain" to work when I'm placing the image in an img tag in the master report. The image gets bigger, as it should. But it doesn't scale to be contained by the surrounding div.

  • Arghh!
    Back to the drawing board again. I was so thrilled to get this working.. until I sent and received my first test-email. Started to dig into this a bit and found a great article.


    I guess I'll have to handle the file logistics anyway. I'll venture into the following:

    1. enlist all SVGs and images needed in the email
    2. render each SVG separately with a chrome-image recipe and save the images at s3
    3. render the html-email with links to the saved files

    I'd rather not have to do the above, but it seems that I have no choice if I want my emails to be readable in various mail clients. One upside is that I can probably solve the resolution and object-fit when I have an actual image to work with (compared to a an embedded base64 image).

Log in to reply

Looks like your connection to jsreport forum was lost, please wait while we try to reconnect.