@prezly/rock-emails

See the Make campaign layout responsive project in Linear.

This codebase relies on the following projects:

Emails Rendering API

đź’ˇ Note: The implementation does not talk to the Prezly API, and instead requires all API data required for rendering to be present in the request body.

Rendering a storyless email campaign

POST /api/render/campaign/:campaignId
Content-Type: application/json

{
   "campaign": { /* Campaign */ },
   "footer": "<p>You have received this email message, because you are a subscriber of Vent Airlines.</p>",
   "referencedStories": {
      "847e8e3f-2ae1-4dcb-8cf4-ad9e702671b0": {
        type: "link",
        url: "https://www.prezly.com/help/onetrust-cookie-consent-integration",
        title: "OneTrust cookie consent integration",
        description: "Learn how to integrate OneTrust cookie consent management into your Prezly site.",
        thumbnail_url:
            "https://cdn.uc.assets.prezly.com/fad6c662-1ddd-4406-bef6-83fabec952b6/-/crop/2400x1026/0,197/-/preview/-/preview/600x600/",
        thumbnail_width: 2400,
        thumbnail_height: 1026,
        version: "1.0",
    }
   }, 
   "referencedCoverage" {
     "621346": {
       // Coverage
     }
   }
   
}

Response

{ "status": "ok", "html": "..." }

Error response

đź’ˇ Anything with non-200 status code is an error response. The app generate JSON error responses with useful ingformation for debugging.

{ "status": "error", "code": "...", "message": "...", "errors": [ ... ] }

Rendering an email campaign with a story

POST /api/render/story-campaign/:campaignId
Content-Type: application/json

{
   "campaign": { /* Campaign */ },
   "story": { /* ExtendedStory */ },
   "newsroom": { /* Newsroom */ },
   "newsroomLanguageSettings": { /* NewsroomLanguageSettings */ },
   "preset": { /* NewsroomThemePreset */ },
   "footer": "<p>You have received this email message, because you are a subscriber of Vent Airlines.</p>",
   "referencedStories": {
      "847e8e3f-2ae1-4dcb-8cf4-ad9e702671b0": {
        type: "link",
        url: "https://www.prezly.com/help/onetrust-cookie-consent-integration",
        title: "OneTrust cookie consent integration",
        description: "Learn how to integrate OneTrust cookie consent management into your Prezly site.",
        thumbnail_url:
            "https://cdn.uc.assets.prezly.com/fad6c662-1ddd-4406-bef6-83fabec952b6/-/crop/2400x1026/0,197/-/preview/-/preview/600x600/",
        thumbnail_width: 2400,
        thumbnail_height: 1026,
        version: "1.0",
    }
   }, 
   "referencedCoverage" {
     "621346": {
       "id: "621346",
       // ...
     }
   }
}

Response

{ "status": "ok", "html": "..." }

Error response

Anything with non-200 status code is an error response. The app generate JSON error responses with useful ingformation for debuggig.

{ "status": "error", "code": "...", "message": "...", "errors": [ ... ] }

Development

This package is using PNPM as a package manager, and provides an .nvmrc file to make sure developers are using the right node version for development.

pnpm install

There are two applications in the codebase: the API server and the dev server.

Dev server

The dev server is provided by React Email (it’s a Next.js-based application with React Email’s additional bells and whistles).

To run it:

pnpm run dev

đź’ˇ Key locations

✉️ Sending emails

You can send emails right from the dev server UI with no additional configuration thanks to the Resend Team who integrated their email sending API into this project and allow using it for free.

API server

This is a simple Express API server to accept and validate request JSON data, pass it to the email rendering components and return the result.

To run it:

pnpm build && pnpm run start

đź’ˇ Key locations

đź’© Tricky parts

One of the trickiest part in this project’s implementation is how we render raw HTML comments.

Because there is no way in React to render blocks of HTML comments, I had to be creative. This repository contains a patch for @react-email/render that automatically unwraps markup between <script type="text/html+raw">*</script> tags. This way we can freely render any conditional comments, often required for better Microsoft Outlook support.

The downside is that it’s necessary to recreate the patch every time we update the mentioned package.

Deployment

The application is automatically deployed using the Github Actions workflow configured. Every merge or push to the main branch will be automatically deployed.

The app is available at this URL: https://emails-rendering.prezly.net/ (access protected by Clouldflare Warp).