NextJS

How to Develop Emails with React: Running NextJS without Client JavaScript

Email development, oh thou necessary evils of the world.

Server side React (NextJS) would be helpful in constructing components and maintaining a united stack, but after the server render, no JavaScript or React is actually needed in the resulting HTML.

To completely disable client side JavaScript from document, do:

1. Put on a Helmet

React Helmet is a “document head manager for React”, which would allow us to manipulate and customize all attributes of <html>, <head> and <body> tag even after we ditch NextJS’s <Header> component.

To add the Helmet to your NextJS setup, see the example here:

2. Remove Script Tags

Everything like the example above, except that at the end of _document.js, return:

return (
   <html {...this.helmetHtmlAttrComponents}>
      <head>{this.helmetHeadComponents}</head>
      <body {...this.helmetBodyAttrComponents}>
          <Main />
      </body>
   </html>
)

Note that we’re using a basic lowercase <head> tag instead of importing NextJS’s <Head> tag, which would prevent NextJS from injecting all sorts of interesting stuff while still allowing us to customize head tag in any pages we create. Also we’re omitting the <NextScript />.

3. <Style> in Document Head

For emails, we will be generating <style> tag directly inside of <head> instead of linking to external css files. To achieve so, install style loaders:

$ npm i --save-dev to-string-loader css-loader less-loader less

Or switch less for sass loader if you so prefer. Then in your next.config.js, add:

config.module.rules.push({
    test: /\.(css|less)$/,
    use: [
      'to-string-loader',
      {
        loader: 'css-loader',
        options: { esModule: false },
      },
      'less-loader'
    ],
})

This would allow us to write .less styles for components, as such:

# welcome-email.js

import { Helmet } from 'react-helmet'
import styles from './welcome.less'

export default function WelcomeEmail() {
    return (
        <>
            <div className="welcome">
                <h1>Test h1</h1>
            </div>

            <Helmet>
                <style>{styles}</style>
            </Helmet>
        </>
    )
}
# welcome.less

.welcome {
    color: darkred;

    h1 {
        font-size: 5rem;
    }
}

Resulting HTML will look like this:

<style> injected into head by react-helmet

4. Profit.

Voilà! No script will be loaded.

A final note on injecting styles into <head>, if you’re relatively new to email development: these styles won’t be included if emails are forwarded. So, your best bet would be to use inline styles 99% of the time, relying on <style> tag only when specifying @media queries, so that nothing will break when emails are being forwarded.

2020-11 Update:

Since NextJS 9.5.4 update, they’ve added an annoying warning that might show up quite a lot if you use your own <head>:

warn  - Your custom Document (pages/_document) did not render all the required subcomponents.
Missing components: <Head />, <NextScript />
Read how to fix here: https://err.sh/next.js/missing-document-component

To disable this specific warning, see How to Disable Any NextJS Warning.

Standard

One thought on “How to Develop Emails with React: Running NextJS without Client JavaScript

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.