HTML Emailも React + Tailwind CSS で書ける時代キテた

![SLVReactTailwindEmailJA.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780317/20d45379-12cd-4cbb-8850-82b65c75e151.jpeg)


gm! エルソウルラボ、Validators DAO の kishi.sol です。

フロントエンド開発の世界は、ReactやTailwind CSSをはじめとするオープンソース技術の進化によって劇的に改善され、スピーディかつ高品質なUIを構築する環境が整いました。

コンポーネントベースの開発スタイルが定着したことで、保守性が高まり、コードを資産として残せるようになったことは間違いありません。かつてレスポンシブレイアウトに苦戦したのも今や昔話で、Tailwindのエコシステムを活用すれば誰もが簡単に美しくモダンなWeb UIを作成できるようになっています。

しかし一方で、私たちを悩ませ続けてきた最後の砦があります。それが「HTMLメール」です。

HTMLメールの開発は、昔ながらの「黒魔術」こと、HTMLとインラインCSSを駆使する必要がありました。ReactやTailwindが主流となり、もはやHTML+インラインCSSでUIを開発することは非現実的であり、むしろそれらの旧技術から脱却したことが、モダンで高品質なUIを実現できた大きな理由でした。

HTMLメールを美しく仕上げるのは職人技が必要で、熟練のエンジニアでなければ理想のメールを作るのは困難でした。メール送信サービスが提供するテンプレートを利用すれば多少の負担は軽減されますが、APIバックエンドとのインテグレーションの相性は悪く、カスタマイズ性に乏しくどれも似たような没個性的なデザインになりがちでした。Tailwindで作ったような洗練されたUIと比較すると、コードが資産として積み上がっていかないことは明らかです。

テンプレートエンジンを使っても、結局デザイン調整の際にインラインCSSを触る必要があり、変更のたびに大きな苦痛を伴います。

同じ課題に悩んできた同胞のあなたなら、この痛みをよく理解していることでしょう。

そこで今回、私たちはこの問題を根本から解決する方法として、「React Email」を使ったサンプルをオープンソースで公開しました。

私達の大好きな React + Tailwind CSS の環境で、コンポーネントを組み合わせてHTML Emailを構築できます。

TypeScriptやeslint、prettierなど必要な設定も全て整った状態で提供しています。下記のコードは実際に動作するサンプルなので、ぜひ参考にしていただければ幸いです。

全コードはオープンソースとして公開しています。

https://github.com/ValidatorsDAO/slv/tree/main/cf-workers-template/contact-email

## 動作サンプル

![ContactUsJA.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780317/791b2ed0-3e94-4a95-b326-425a7c99619a.jpeg)

https://web-ssg.slv.dev/ja/contact

## 主要コード

```tsx
import { Html, Body, Container, Section, Text, Tailwind, Img, Hr } from '@react-email/components'
import Header from '@/email/utils/Header'
import { logoUrl, orgName } from '@/config'

interface Props {
  contactRequestBody: ContactRequestBody
}

export default function ContactFormEmail({ contactRequestBody }: Props) {
  const { name, email, message, locale } = contactRequestBody
  const isJa = locale === 'ja'

  const texts = {
    greeting: isJa ? `${name}様、お問い合わせありがとうございます。` : `Thank you for contacting us, ${name}.`,
    received: isJa ? '以下の内容を受け取りました。' : 'We have received your message:',
    nameLabel: isJa ? 'お名前' : 'Name',
    emailLabel: isJa ? 'メールアドレス' : 'Email',
    messageLabel: isJa ? 'メッセージ' : 'Message',
    footer: isJa ? '後ほど担当者よりご連絡いたします。' : 'Our team will reach out to you shortly.',
  }

  return (
    <Tailwind>
      <Html lang={isJa ? 'ja' : 'en'}>
        <Header lang={isJa ? 'ja' : 'en'} />
        <Body className="font-sans bg-zinc-950">
          <Container className="max-w-lg mx-auto px-4 py-6">
            <Section className="pt-20 pb-8">
              <Img src={logoUrl} className="w-28" />
            </Section>
            <Text className="text-2xl font-bold text-white tracking-tight">
              {texts.received}
            </Text>
            <Text className="text-zinc-100 pb-3">{texts.greeting}</Text>
            <Hr className="border-zinc-500" />

            <Section>
              <Text className="text-zinc-300">
                <strong className="text-zinc-100">{texts.nameLabel}:</strong> {name}
              </Text>
              <Text className="text-zinc-300">
                <strong className="text-zinc-100">{texts.emailLabel}:</strong> {email}
              </Text>
              <Text className="text-zinc-300">
                <strong className="text-zinc-100">{texts.messageLabel}:</strong>
                <br />
                {message}
              </Text>
            </Section>

            <Hr className="border-zinc-500" />

            <Text className="text-zinc-100 pt-3">{texts.footer}</Text>
            <Text className="text-xs text-zinc-300 pt-3">※ This mail is for test purpose.</Text>
            <Text className="text-sm text-zinc-400 py-12">© {new Date().getFullYear()} {orgName}</Text>
          </Container>
        </Body>
      </Html>
    </Tailwind>
  )
}
```

https://github.com/ValidatorsDAO/slv/tree/main/cf-workers-template/contact-email

送信されるメール

![EmailWrittenByReactJA.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780317/d6ff6509-b321-4767-9872-6c8548c18460.jpeg)


このようにReactとTailwindの技術資産を最大限に活かし、より保守管理しやすく高品質な開発環境を構築できます。

私たちの研究成果や技術改善はすべてオープンソース「SLV」として共有されます。これからも爆速でモダンなアプリフレームワークとしてSLVを進化させていきます。

今後ともよろしくお願いいたします。

### 参考リンク

- [SLV](https://slv.dev/)
- [React Email](https://react.email/)
- [Resend](https://resend.com/)
- [Tailwind CSS](https://tailwindcss.com/)
- [Validators DAO Discord](https://discord.gg/C7ZQSrCkYR)