<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ email - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ email - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 19:41:30 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/email/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Add Media to Your HTML Email Template ]]>
                </title>
                <description>
                    <![CDATA[ In my previous article, "How to Create a Responsive HTML Email Template," we explored the fundamentals of designing and coding a simple HTML email template that adapts beautifully across different devices and email clients.  I got a couple of questio... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-media-to-your-html-email-template/</link>
                <guid isPermaLink="false">66ba1be1b6a437d5f189cf83</guid>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Fanny Nyayic ]]>
                </dc:creator>
                <pubDate>Tue, 23 Apr 2024 17:40:54 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/Add-Media-to-Your-HTML-Email-Template.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In my previous article, "<a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-a-responsive-html-email-template/">How to Create a Responsive HTML Email Template</a>," we explored the fundamentals of designing and coding a simple HTML email template that adapts beautifully across different devices and email clients. </p>
<p>I got a couple of questions about adding media to the HTML email template.</p>
<p>Building on that foundation, I'll guide you through different ways of adding media to your HTML email template. Adding media such as images, videos, and audio can significantly increase the engagement and effectiveness of your communications. </p>
<h3 id="heading-requirements">Requirements</h3>
<ul>
<li>A simple HTML email template. You can create one following <a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-a-responsive-html-email-template/">this guide</a>. </li>
</ul>
<h2 id="heading-how-to-add-images-to-your-email-template">How to Add Images to Your Email Template</h2>
<p>Images are the most common type of media added to emails. Here's how to include them in your HTML email templates:</p>
<ul>
<li>Before adding an image, ensure it is properly sized and optimized for web use. A common practice is to keep the image width under 600 pixels to fit most email clients without scaling. For this particular example we have a stock image and resized it to 600 x 750 pixels as shown below.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/600x750.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>this is the image we shall be uploading</em></p>
<ul>
<li>Upload your image to a reliable web server or content delivery network (CDN). You'll need a stable URL to reference in your email.  </li>
</ul>
<p>For this example we'll use <a target="_blank" href="https://imgbb.com/">the imgbb website</a> and upload our image. Click on "Start Uploading<em>"</em> and choose the image.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713853483929.png" alt="Image" width="600" height="400" loading="lazy">
<em>imgbb is one of the free image hosting platforms</em></p>
<p>After choosing the image to use, select "Don't Autodelete" and click on Upload.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713853781152.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choose Don't Autodelete from the dropdown</em></p>
<p>After uploading, a URL will be generated. Click on the dropdown and choose "HTML full linked"</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713854879006-copy-code.png" alt="Image" width="600" height="400" loading="lazy">
<em>The embed code generated</em></p>
<ul>
<li>Copy the HTML code generated and insert it within a desired section in your email template as shown.</li>
</ul>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://ibb.co/XpRp2N8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://i.ibb.co/q9Q9yX5/600x750.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"600x750"</span> <span class="hljs-attr">border</span>=<span class="hljs-string">"0"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>Feel free to try out other embed code options to test how your image will appear in the email template. </p>
<p>Below is the outcome of the inserted image:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713854742721.png" alt="Image" width="600" height="400" loading="lazy">
<em>image successfully inserted to our email template</em></p>
<p><strong>Note</strong>: Always include the <code>alt</code> attribute to provide alternative text for scenarios where the image cannot be displayed.</p>
<h2 id="heading-how-to-embed-videos-in-your-email-template">How to Embed Videos in Your Email Template</h2>
<p>Direct video playback is not supported in most email clients. Instead, you can embed a clickable thumbnail that links to a video hosted online:</p>
<ul>
<li><strong>Create a Thumbnail</strong>: Capture a frame from your video or create a custom graphic that represents the video content. This will act as a placeholder. In this example, we'll use the same image as the thumbnail.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713855881423-thumbnail.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ul>
<li>From the dropdown, choose HTML thumbnail linked. Copy the code and paste it to your email template.</li>
</ul>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://ibb.co/XpRp2N8"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://i.ibb.co/XpRp2N8/600x750.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"600x750"</span> <span class="hljs-attr">border</span>=<span class="hljs-string">"0"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<ul>
<li><strong>Link to the Video</strong>: Modify the above code to use the thumbnail as a clickable image linked to the video URL. </li>
<li>Change the URL in the <code>&lt;a href =""&gt;</code> to the video link as shown below.</li>
</ul>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://youtu.be/UG8rjxYBfFg?si=xU2zqCtQW5-2z7nw"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://i.ibb.co/XpRp2N8/600x750.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"600x750"</span> <span class="hljs-attr">border</span>=<span class="hljs-string">"0"</span>&lt;/<span class="hljs-attr">a</span>&gt;</span>
</code></pre>
<p>This HTML snippet creates a linked image without a border. And this is how it will appear in our email Template:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713856590062-thumbnail.png" alt="Image" width="600" height="400" loading="lazy">
<em>linked thumbnail will appear like this</em></p>
<h2 id="heading-how-to-embed-youtube-videos-in-your-email-template">How to Embed YouTube Videos in Your Email Template</h2>
<p>Alternatively you can directly embed a YouTube video to your email template. Here is how:</p>
<ul>
<li>Go to YouTube and choose the video you would like to embed.</li>
<li>Click on <strong>share -&gt; embed</strong> and an <code>iframe</code> will be generated. Below is an example:</li>
</ul>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">iframe</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"560"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"315"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://www.youtube.com/embed/UG8rjxYBfFg?si=nYBBM032nvBn5tNZ"</span> <span class="hljs-attr">title</span>=<span class="hljs-string">"YouTube video player"</span> <span class="hljs-attr">frameborder</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">allow</span>=<span class="hljs-string">"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"</span> <span class="hljs-attr">referrerpolicy</span>=<span class="hljs-string">"strict-origin-when-cross-origin"</span> <span class="hljs-attr">allowfullscreen</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">iframe</span>&gt;</span>
</code></pre>
<ul>
<li>Copy the <code>iframe</code> and paste it to a <code>&lt;td&gt;</code> section of your HTML email template code. And you will have something looking like this:</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713857296270-youtube.png" alt="Image" width="600" height="400" loading="lazy">
<em>this is an example of a youtube video within an email template</em></p>
<h2 id="heading-how-to-add-audio-to-your-email-template">How to Add Audio to Your Email Template</h2>
<p>Adding audio files directly to emails is also not supported by most email clients. Similar to videos, you can include a link to the audio file:</p>
<ul>
<li><strong>Host the Audio File</strong>: Upload your audio file to a suitable platform or server. There are a number of audio platforms out there, like Google Drive, your own website, YouTube, sound cloud, and so on.</li>
<li>For this example, we'll use a platform called <a target="_blank" href="https://audio.com/">audio.com</a>. Simply create an account by clicking  "join now for free" or sign in if you already have an account.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713861900834.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p> Click upload and choose your .mp3 file which will be stored in your account. Once the audio is complete, click on the share icon.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713862121050.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ul>
<li>This will bring you to a couple of options where you can copy the link or simply embed the link:</li>
</ul>
<p>Click on embed, and you will see a preview of how your audio will appear. Copy the code and paste it to your email template section.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713862229377.png" alt="Image" width="600" height="400" loading="lazy">
<em>code generated by audio.com which can be embedded in the email template</em></p>
<p>You can also eliminate the <code>div</code> and just use the <code>iframe</code> . Also feel free to remove parts you would not want to appear in the email template and customize it to your preference. </p>
<p>Here is the code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"height: 228px; width: 600px;"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">iframe</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://audio.com/embed/audio/1797114509131910?theme=image"</span>
                            <span class="hljs-attr">style</span>=<span class="hljs-string">"display:block; border-radius: 6px; border: none; height: 204px; width: 600px;"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">iframe</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">'https://audio.com/nyayic-fanny'</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"text-align: center; display: block; color: #A4ABB6; font-size: 12px; font-family: sans-serif; line-height: 16px; margin-top: 8px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;"</span>&gt;</span>@nyayic-fanny<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>This is our final outcome for the above:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/screely-1713862296389.png" alt="Image" width="600" height="400" loading="lazy">
<em>our audio will appear like this in our email template</em></p>
<h3 id="heading-using-audio-tag">Using <code>audio</code> tag</h3>
<p>Besides embedding, we can use the audio tag and just add the URL  to our audio source as shown below: </p>
<pre><code class="lang-html"> <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Audio added via audio tag<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">audio</span> <span class="hljs-attr">controls</span>=<span class="hljs-string">"controls"</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">source</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://audio.com/nyayic-fanny/audio/past-life-jvna.mp3"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>? Listen: <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://audio.com/nyayic-fanny/audio/past-life-jvna.mp3"</span>&gt;</span>Audio<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> (mp3)<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
       <span class="hljs-tag">&lt;/<span class="hljs-name">audio</span>&gt;</span>
</code></pre>
<p>Just change the URL to your <code>audio url</code> . And this is how our entire modification should look.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/final-newsletter.png" alt="Image" width="600" height="400" loading="lazy">
<em>our modified html email template</em></p>
<p><strong>Note:</strong> Hotmail and clients that don’t support HTML5 will not work!</p>
<h2 id="heading-best-practices-for-media-in-html-emails">Best Practices for Media in HTML Emails</h2>
<p>When integrating media into HTML emails, consider the following tips to optimize compatibility and user experience:</p>
<ul>
<li>Always use full, absolute URLs for images, videos, and audio to ensure they load correctly in all email clients.</li>
<li>Test Your Emails: Different email clients display HTML content in various ways. Use tools like Litmus or Email on Acid to test how your email renders across different platforms.</li>
<li>Keep Load Times in Mind: Optimize media file sizes to ensure that your emails load quickly, which is crucial for retaining the recipient's attention and improving engagement.</li>
<li>Consider Accessibility: Provide descriptive alt text for images and captions or transcripts for audio and video content.</li>
</ul>
<p>While there are limitations to what email clients can support, using linked images for videos and audio files provides a user-friendly solution that works across most platforms. </p>
<p>Always ensure you test your emails thoroughly and follow best practices to ensure a smooth and engaging user experience.</p>
<p>Happy Coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Responsive HTML Email Template ]]>
                </title>
                <description>
                    <![CDATA[ In this beginner-friendly guide, you'll learn how to create a responsive email template. You'll follow step-by-step instructions with code snippets to design an email template that looks great on any device.  This project is perfect for newcomers eag... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-responsive-html-email-template/</link>
                <guid isPermaLink="false">66ba1be84067550ef786869e</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ projects ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Fanny Nyayic ]]>
                </dc:creator>
                <pubDate>Mon, 15 Apr 2024 23:11:04 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/create-html-email-template-from-scratch.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this beginner-friendly guide, you'll learn how to create a responsive email template. You'll follow step-by-step instructions with code snippets to design an email template that looks great on any device. </p>
<p>This project is perfect for newcomers eager to master email design basics!</p>
<h2 id="heading-step-1-set-up-the-basic-structure">Step 1: Set Up the Basic Structure</h2>
<p>To build an email template, you can start with a basic HTML structure. This includes a <code>DOCTYPE</code> declaration for emails, defining the <code>head</code> and <code>body</code> sections, and using meta tags in the <code>head</code> section to ensure proper mobile rendering and zooming.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Responsive Email Template<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Email content goes here --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h2 id="heading-step-2-create-the-email-structure">Step 2: Create the Email Structure</h2>
<p>Use tables to create the basic structure of your email. This will ensure compatibility across different email clients.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"100%"</span> <span class="hljs-attr">cellpadding</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellspacing</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">border</span>=<span class="hljs-string">"0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">align</span>=<span class="hljs-string">"center"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"600"</span> <span class="hljs-attr">cellpadding</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellspacing</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">border</span>=<span class="hljs-string">"0"</span>&gt;</span>
                <span class="hljs-comment">&lt;!-- Email content goes here --&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
</code></pre>
<h2 id="heading-step-3-add-content-and-inline-styles">Step 3: Add Content and Inline Styles</h2>
<p>Email clients vary in how they render CSS, so it's safer to use inline styles. Here's an example of a simple email body:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"font-family: 'Poppins', Arial, sans-serif"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"100%"</span> <span class="hljs-attr">border</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellspacing</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellpadding</span>=<span class="hljs-string">"0"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">align</span>=<span class="hljs-string">"center"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"padding: 20px;"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"content"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"600"</span> <span class="hljs-attr">border</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellspacing</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellpadding</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"border-collapse: collapse; border: 1px solid #cccccc;"</span>&gt;</span>
                    <span class="hljs-comment">&lt;!-- Header --&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"header"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"background-color: #345C72; padding: 40px; text-align: center; color: white; font-size: 24px;"</span>&gt;</span>
                        Responsive Email Template
                        <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>

                    <span class="hljs-comment">&lt;!-- Body --&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"body"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"padding: 40px; text-align: left; font-size: 16px; line-height: 1.6;"</span>&gt;</span>
                        Hello, All! <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>
                        Lorem odio soluta quae dolores sapiente voluptatibus recusandae aliquam fugit ipsam.
                        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>
                            Lorem ipsum dolor sit amet consectetur adipisicing elit. Veniam corporis sint eum nemo animi velit exercitationem impedit. Incidunt, officia facilis  atque? Ipsam voluptas fugiat distinctio blanditiis veritatis.            
                        <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>

                    <span class="hljs-comment">&lt;!-- Call to action Button --&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"padding: 0px 40px 0px 40px; text-align: center;"</span>&gt;</span>
                            <span class="hljs-comment">&lt;!-- CTA Button --&gt;</span>
                            <span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">cellspacing</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellpadding</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"margin: auto;"</span>&gt;</span>
                                <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                                    <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">align</span>=<span class="hljs-string">"center"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"background-color: #345C72; padding: 10px 20px; border-radius: 5px;"</span>&gt;</span>
                                        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://www.yourwebsite.com"</span> <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"color: #ffffff; text-decoration: none; font-weight: bold;"</span>&gt;</span>Book a Free Consulatation<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
                                    <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                                <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
                            <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
                        <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"body"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"padding: 40px; text-align: left; font-size: 16px; line-height: 1.6;"</span>&gt;</span>
                            Lorem ipsum dolor sit amet consectetur adipisicing elit. Veniam corporis sint eum nemo animi velit exercitationem impedit.             
                        <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
                    <span class="hljs-comment">&lt;!-- Footer --&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"footer"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"background-color: #333333; padding: 40px; text-align: center; color: white; font-size: 14px;"</span>&gt;</span>
                        Copyright <span class="hljs-symbol">&amp;copy;</span> 2024 | Your brand name
                        <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>Here's a breakdown of the main elements and their functions:</p>
<h3 id="heading-body-tag-and-font-setup">Body Tag and Font Setup</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"font-family: 'Poppins', Arial, sans-serif"</span>&gt;</span>
</code></pre>
<p>This sets the default font for the email to 'Poppins', with fallbacks to Arial and sans-serif if 'Poppins' isn't available.</p>
<h3 id="heading-table-structure">Table Structure</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"100%"</span> <span class="hljs-attr">border</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellspacing</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellpadding</span>=<span class="hljs-string">"0"</span>&gt;</span>
</code></pre>
<p>This is the outermost table that takes up 100% of the email's width. The <code>border</code>, <code>cellspacing</code>, and <code>cellpadding</code> are set to 0 to remove default styling and spacing.</p>
<p>Nested inside this table is another <code>&lt;table class="content"&gt;</code> with a fixed width of 600px, centered by its parent with <code>td align="center"</code>. </p>
<p>This inner table includes a border and specific styling, defining it as the main content area.</p>
<h3 id="heading-the-header-section">The Header Section</h3>
<p>The header is styled with a dark blue background using inline CSS (#345C72), white text color, and larger text size (24px). It’s designed to grab attention right at the beginning of the email. </p>
<p><strong>Note</strong><em><strong>:</strong></em> You can customize this section with your brand name or logo instead.</p>
<h3 id="heading-the-body-content">The Body Content</h3>
<p>The body section contains the main message of the email, set in a font size of 16px and line height of 1.6 for better readability. The content is aligned to the left, and the use of <code>&lt;br&gt;</code> tags helps in spacing out the lines.</p>
<h3 id="heading-call-to-action-cta-button">Call to Action (CTA) Button</h3>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- Call to action Button --&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"padding: 0px 40px 0px 40px; text-align: center;"</span>&gt;</span>
                            <span class="hljs-comment">&lt;!-- CTA Button --&gt;</span>
                            <span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">cellspacing</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellpadding</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"margin: auto;"</span>&gt;</span>
                                <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                                    <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">align</span>=<span class="hljs-string">"center"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"background-color: #345C72; padding: 10px 20px; border-radius: 5px;"</span>&gt;</span>
                                        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://www.yourwebsite.com"</span> <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"color: #ffffff; text-decoration: none; font-weight: bold;"</span>&gt;</span>Book a Free Consulatation<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
                                    <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                                <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
                            <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
                        <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
</code></pre>
<p>The CTA button here is designed to stand out with a background color that matches the header, rounded corners (<code>border-radius: 5px</code>), and bold, white text. </p>
<p>The <code>&lt;a&gt;</code> tag within the button is styled to remove the default underline (<code>text-decoration: none</code>) and is linked to a webpage where recipients can "Book a Free Consultation."</p>
<h3 id="heading-footer">Footer</h3>
<p>The footer repeats the styling approach of the header but uses a darker background (#333333) and smaller font size (14px). It can contain copyright information and links or other contact details.</p>
<h3 id="heading-illustration">Illustration</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/email-template-illustration.png" alt="Image" width="600" height="400" loading="lazy">
<em>illustration of the different parts of the template: header, CTA button, and footer</em></p>
<h2 id="heading-step-4-make-it-responsive">Step 4: Make It Responsive</h2>
<p>To ensure the email looks good on mobile devices, you can use CSS media queries. While most of the styling are inline, for responsive behavior, you'll need to add a <code>&lt;style&gt;</code> block in the <code>head</code>. </p>
<p>Media queries adjust styles based on the device's width.</p>
<pre><code class="lang-css">&lt;<span class="hljs-selector-tag">style</span>&gt;
  <span class="hljs-keyword">@media</span> screen <span class="hljs-keyword">and</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">600px</span>) {
    <span class="hljs-selector-class">.content</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span> <span class="hljs-meta">!important</span>;
        <span class="hljs-attribute">display</span>: block <span class="hljs-meta">!important</span>;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span> <span class="hljs-meta">!important</span>;
    }
    <span class="hljs-selector-class">.header</span>, <span class="hljs-selector-class">.body</span>, <span class="hljs-selector-class">.footer</span> {
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span> <span class="hljs-meta">!important</span>;
    }
  }
&lt;/<span class="hljs-selector-tag">style</span>&gt;
</code></pre>
<p>Here’s a breakdown of this specific CSS snippet:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@media</span> screen <span class="hljs-keyword">and</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">600px</span>) { ... }
</code></pre>
<p>This media query targets screens with a maximum width of 600 pixels. It applies the following styles only when the email is viewed on devices with a screen width of 600px or less, which typically includes smartphones and some smaller tablets.</p>
<p>Styles within the media query classes:</p>
<h3 id="heading-content">.content</h3>
<ul>
<li><code>width_: 100% !important;_</code> : This style changes the width of the <code>.content</code> table to use the full width of the screen instead of the 600px specified in the HTML. The <code>!important</code> rule is used to override any other conflicting styles.</li>
<li><code>display: block !important;</code>: Although <code>&lt;table&gt;</code> elements are naturally block-level elements, setting <code>display: block</code> explicitly can help in some email clients to ensure the element behaves as expected.</li>
<li><code>padding: 10px !important;</code>: Adds padding around the content within the <code>.content</code> table, reducing it from the original 40px in the HTML to make better use of the reduced screen space on smaller devices.</li>
</ul>
<h3 id="heading-header-body-footer">.header, .body, .footer</h3>
<ul>
<li><code>padding: 20px !important;</code>: This style uniformly sets the padding of the <em>header, body, and footer</em> sections to <em>20px</em> on all sides, optimizing the spacing for smaller screens. It overrides the various padding settings defined in the HTML, which include larger values in some cases.</li>
</ul>
<p>In the context of email design, the use of <strong>!important</strong> is fairly common to ensure that the styles are applied as intended, overriding both default styles and other potentially conflicting styles that might be applied by the email client itself. </p>
<h2 id="heading-step-5-test-across-email-clients">Step 5: Test Across Email Clients</h2>
<p>It's crucial to test your email template across different email clients (like Gmail, Outlook, and Apple Mail) and devices to ensure compatibility and responsiveness. Tools like Litmus or Email on Acid can help with this.</p>
<h2 id="heading-step-6-adding-google-font">Step 6: Adding Google Font</h2>
<p>Incorporating Google Fonts into an HTML email template can improve its visual appeal significantly. </p>
<p>However, it's important to note that not all email clients support web fonts. Some, like Apple Mail, do support Google Fonts, but others like Gmail do not. To ensure your email looks great to all recipients, always provide a fallback font.</p>
<p>Here's how you can add a Google Font to your email template, along with a fallback option for clients that don't support it:</p>
<h3 id="heading-choose-your-google-font">Choose Your Google Font</h3>
<p>First, visit the <a target="_blank" href="https://fonts.google.com/">Google Fonts</a> website and choose a font. For this example, let's use <em>"Poppins".</em></p>
<h3 id="heading-add-the-font-link-to-your-email-head">Add the Font Link to Your Email Head</h3>
<p>Include the link to the Google Font in the <code>&lt;head&gt;</code> of your HTML document. Since this might not be supported in all email clients, ensure you have a suitable fallback font in your styles.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"preconnect"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://fonts.googleapis.com"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"preconnect"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://fonts.gstatic.com"</span> <span class="hljs-attr">crossorigin</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&amp;display=swap"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>&gt;</span>
</code></pre>
<h3 id="heading-apply-the-font-in-your-styles">Apply the Font in Your Styles</h3>
<p>Use inline CSS to apply the Google Font to your HTML elements, and always include a generic fallback font. In email templates, it's safer to apply styles inline due to varying support for <code>&lt;style&gt;</code> tags across email clients. </p>
<p>Here's how to apply the font to the <code>body</code> of your email and include a fallback:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"font-family: 'Poppins', Arial, sans-serif;"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"100%"</span> <span class="hljs-attr">cellspacing</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">cellpadding</span>=<span class="hljs-string">"0"</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Email content --&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<h2 id="heading-what-we-created">What We Created</h2>
<p>Below is a screenshot of the email template we designed. It features a professional layout with a header containing a logo placeholder, a main body section for your message, and a dark footer with contact and subscription management links. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/email-template.png" alt="Image" width="600" height="400" loading="lazy">
<em>screenshot of the email template</em></p>
<h2 id="heading-additional-tips">Additional Tips:</h2>
<ul>
<li>Keep your CSS inline as much as possible, because many email clients do not support <code>&lt;style&gt;</code> tags.</li>
<li>Use web-safe fonts to ensure that your text appears correctly in all email clients.</li>
<li>Always provide a plain text version of your email for clients that don't support HTML, or have HTML disabled.</li>
</ul>
<p>I hope this guide provides you with a basic framework for creating a responsive email template. As you become more comfortable with email design, you can experiment with more complex layouts and styles.  </p>
<p><em><strong>Happy Coding!</strong></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up a Custom Email with Cloudflare and Mailgun ]]>
                </title>
                <description>
                    <![CDATA[ As a software engineer, you may consider having a professional email account along with your own website, like "info@example.com". But this may cost a certain amount that you'll not be willing to pay. But do you know you can do it for free? There is ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-custom-email/</link>
                <guid isPermaLink="false">66ba2af24d935175898a7069</guid>
                
                    <category>
                        <![CDATA[ cloudflare ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ San B ]]>
                </dc:creator>
                <pubDate>Mon, 15 Apr 2024 13:49:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/boolfalse-gmail-manage-custom-email.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a software engineer, you may consider having a professional email account along with your own website, like "<em>info@example.com</em>". But this may cost a certain amount that you'll not be willing to pay.</p>
<p>But do you know you can do it for free? There is actually a way to do it, and besides the fact that having the professional email account is free, it will help you be more efficient, reliable and secure in your daily work.</p>
<p>In this article, you'll learn how to create and set up your own email address using Cloudflare and Mailgun to manage emails in Gmail. This means that you can send and receive emails directly in your Gmail inbox.</p>
<p>I've done this already for personal use and have taken screenshots of the entire process that you'll see in this article. So I'll share all the necessary steps you need to follow to set up your own email.</p>
<p>Let's figure out what you need to have before you start, what you are going to do, and how it will work.</p>
<h2 id="heading-what-you-need-to-have-before-you-start">What you need to have before you start</h2>
<p>I assume that you already have a domain, let's call it "<em>yourdomain.com</em>". Specifically, you need to have accessibility to connect your domain with Cloudflare and setup DNS records there. A classic example of that is having a domain on some domain registrar (like GoDaddy, Namecheap), and adding your domain to Cloudflare by setting DNS records provided by Cloudflare on your domain registrar account.</p>
<p>Adding a domain to Cloudflare involves updating your domain's DNS nameservers to point to Cloudflare's nameservers. Once the domain is added, Cloudflare acts as an intermediary for web traffic, providing security features like DDoS protection, firewall, and SSL encryption, as well as performance enhancements through caching and content optimization.</p>
<p>If you haven't done that yet, here's the official <a target="_blank" href="https://www.youtube.com/watch?v=7hY3gp_-9EU">video on YouTube</a> on how to connect your domain to Cloudflare.</p>
<p>Additionally, Cloudflare manages DNS records for your domain, allowing you to control how traffic is routed and ensuring reliable delivery of services like email.<br>So, our work in this article will be focusing exactly on that: how to setup your domain on Cloudflare Email.</p>
<p><a target="_blank" href="https://blog.cloudflare.com/email-routing-leaves-beta/">Cloudflare Email</a> has been one of the services of Cloudflare since 2021, which can be used for free (as of now, at least).</p>
<p>The second assumption is that you have Gmail account, and you have access to its email settings. Simply, if you just have a regular "<em>youremail@gmail.com</em>" email, which isn't under the control of any administrator, then you have nothing to worry about. We'll explore and work on email settings later on.</p>
<h2 id="heading-what-you-are-going-to-do">What you are going to do</h2>
<p>In simple words, you're going to create a custom email like "<em>something@yourdomain.com</em>", which you can use to send and receive emails using Gmail's platform. So you will be receiving and reading emails sent to "<em>something@yourdomain.com</em>" in Gmail, as well as sending emails from that custom email using Gmail.</p>
<p>You'll use Cloudflare Email for the email routing, and Mailgun's SMTP server for sending emails.</p>
<h2 id="heading-how-it-will-work">How it will work</h2>
<p>When composing an email from Gmail with the sender set as "<em>something@yourdomain.com</em>", Gmail utilizes Mailgun's SMTP server through the provided credentials, transmitting the email. Mailgun then processes the message and forwards it to the recipient's email server, likely involving DNS lookups to find the recipient's server.</p>
<p>Emails sent to "<em>something@yourdomain.com</em>" are received by Cloudflare's email servers, configured via MX records in the domain's DNS settings. Cloudflare stores the received emails in the associated account, accessible through Gmail, which periodically connects to Cloudflare's servers (using IMAP or POP3 protocols) to retrieve new messages, enabling seamless access to incoming emails.</p>
<h2 id="heading-email-routing-on-cloudflare">Email Routing on Cloudflare</h2>
<blockquote>
<p>Cloudflare Email Routing is designed to simplify the way you create and manage email addresses, without needing to keep an eye on additional mailboxes. With Email Routing, you can create any number of custom email addresses to use in situations where you do not want to share your primary email address, such as when you subscribe to a new service or newsletter. Emails are then routed to your preferred email inbox, without you ever having to expose your primary email address. (<a target="_blank" href="https://developers.cloudflare.com/email-routing/">Cloudflare Docs</a>)</p>
</blockquote>
<p>Sign in to your Cloudflare account and navigate to the Dashboard.<br>Choose and click on the desired website. For me it's "<em>boolfalse.com</em>", as I want to create a custom email like "<em>email@boolfalse.com</em>".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/01-dashboard.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: Websites</em></p>
<p>Navigate to <strong>Email Routing</strong> for the selected website.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/02-email-routing.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: Email Routing</em></p>
<p>If you don't have email routing configured, you may see something similar to the screenshot above. Click "Get started". You may be able to create your own address to receive emails and take action.</p>
<p>We'll skip this without creating our own address because we'll do it manually.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/03-skip-custom-address.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: Custom Email</em></p>
<p>By default, email routing is disabled, so you need to enable it. Click the link to navigate to the <strong>Email Routing</strong> page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/04-enable-email-routing.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: Email Routing</em></p>
<p>Submit it by clicking "Enable Email Routing".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/05-email-dns-records-enable-email-routing.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: Enable Email Routing</em></p>
<p>You need to have three MX and one TXT records:</p>
<ul>
<li>Type: <em><strong>MX</strong></em>; Name: <em><strong>@</strong></em>; Mail Server: <em><strong>route1.mx.cloudflare.net</strong></em>; TTL: <strong><em>Auto</em></strong>; Priority: <em><strong>69</strong></em></li>
<li>Type: <em><strong>MX</strong></em>; Name: <em><strong>@</strong></em>; Mail Server: <em><strong>route2.mx.cloudflare.net</strong></em>; TTL: <strong><em>Auto</em></strong>; Priority: <strong><em>99</em></strong></li>
<li>Type: <em><strong>MX</strong></em>; Name: <strong><em>@</em></strong>; Mail Server: <em><strong>route3.mx.cloudflare.net</strong></em>; TTL: <strong><em>Auto</em></strong>; Priority: <strong><em>40</em></strong></li>
<li>Type: <em><strong>TXT</strong></em>; Name: <em><strong>@</strong></em>; TTL: <strong><em>Auto</em></strong>; Content: <strong>_v=spf1 include:<em>spf.mx.cloudflare.net ~all</em></strong></li>
</ul>
<p>You can see them at the bottom of the <strong>Email Routing</strong> page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/06-required-dns-records.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: DNS records for Email Routing</em></p>
<p>So, as already said, in the left menu, go to "DNS" -&gt; "Records" and add the following records there.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/06-dns-records-added-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: DNS records added</em></p>
<p>After creating these records, go to the <strong>Email Routing</strong> page again.</p>
<p>Here, you only need to have the records you just created. So if you have any other records, just delete them.</p>
<p>For example, I already had an unnecessary entry there that I should delete.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/07-unnecessary-dns-records.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: existing records for Email Routing</em></p>
<p>Submit to delete existing unnecessary records.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/08-delete-existing-dns-records.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: deleting unnecessary records</em></p>
<p>After removing unnecessary DNS records, you will see only the ones you need there.</p>
<p>You will now be able to enable email routing by clicking the "Add records and enable" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/09-enabling-email-routing.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: Enable Email Routing</em></p>
<p>After enabling it you should see something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/10-email-routing-enabled.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: Email DNS records configured</em></p>
<h2 id="heading-how-to-create-a-custom-email-on-cloudflare">How to Create a Custom Email on Cloudflare</h2>
<p>Now go to the <strong>Routes</strong> tab and create an email by clicking the "Create address" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/11-email-routing-routes-tab.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: Email Routing (enabled)</em></p>
<p>In this example, we'll create "<em>email@boolfalse.com</em>" email address, by adding "<em>email</em>" as a custom address, and a destination email address, where I'll be able to receive emails.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/12-creating-email-address.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: Email Routing</em></p>
<p>You should see a notification about that.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/13-email-address-created.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: creating a custom email</em></p>
<p>You should also get an email for confirming this action.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/14-getting-confirmation-email.png" alt="Image" width="600" height="400" loading="lazy">
<em>Verifying the destination email</em></p>
<p>Go on and verify the email address.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/15-verify-email-address.png" alt="Image" width="600" height="400" loading="lazy">
<em>Verify email address</em></p>
<p>Once you've verified the email address, you may get this page:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/16-email-address-verified.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: custom email address is verified</em></p>
<p>You will probably get an email that you've verified your domain with Mailgun:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/36-mailgun-domain-verified-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Notification about custom email address verification</em></p>
<h2 id="heading-how-to-receive-emails-in-the-custom-email">How to Receive Emails in the Custom Email</h2>
<p>Now, your email address is activated, and you can see that here:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/17-email-address-activated.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cloudflare: custom email address is active</em></p>
<p>At this point you can send emails to the custom email you just set up. In this case, it's "<em>email@boolfalse.com</em>".</p>
<p>Below is a test email sent from a different email.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/18-test-email-sending-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Testing email receiving</em></p>
<p>You'll receive a test email to the custom email.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/19-test-email-received.png" alt="Image" width="600" height="400" loading="lazy">
<em>Test email has been received</em></p>
<h2 id="heading-mailgun-adding-new-domain">Mailgun: Adding New Domain</h2>
<p>You can now successfully receive emails, but you can't send emails from that custom email yet.</p>
<p>So, it's time to switch to the mail service provider. In our case, it will be <a target="_blank" href="https://www.mailgun.com/">Mailgun</a>.<br>To do this, you just need to register and attach the card to your Mailgun account. After activating your account with the card attached, you can set up a domain for your email.</p>
<p>You don't have to worry about the card, because Mailgun does not charge for limited quantities. I think the amount it gives is quite suitable for a free package.<br>You can find the price packages in detail <a target="_blank" href="https://www.mailgun.com/pricing/">here</a>.</p>
<p>Go to <strong>Sending</strong> -&gt; <strong>Domains</strong> page, and click the "Add New Domain" button.</p>
<p>In our case it will be "<em>mg.boolfalse.com</em>", as Mailgun recommends that to be able to send emails from your root domain, that is: "<em>email@boolfalse.com</em>".</p>
<p>You should see that recommendation on the right in below image:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/24-mailgun-adding-domain.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: create a new domain</em></p>
<p>You can also select the domain region and DCIM key length, but you can leave everything as default.<br>I will leave DCIM key length as 1024 and "US" as a domain region.</p>
<p>After creating the domain, you may be shown some tips on how to verify your domain.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/23-add-new-domain-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: adding a new domain</em></p>
<p>Mailgun will give you two TXT records, two MX records and one CNAME record to add to your provider.</p>
<ul>
<li>Type: <em><strong>TXT</strong></em>; Name: _<strong>mailto._domainkey.mg.boolfalse.com</strong>_; TTL: <strong><em>Auto</em></strong>; Content: <strong><em></em></strong></li>
<li>Type: <em><strong>TXT</strong></em>; Name: <em><strong>mg.boolfalse.com</strong></em>; TTL: <strong><em>Auto</em></strong>; Content: <strong><em>v=spf1 include:mailgun.org ~all</em></strong></li>
<li>Type: <em><strong>MX</strong></em>; Name: <em><strong>mg.boolfalse.com</strong></em>; Mail Server: <em><strong>mxa.mailgun.org</strong></em>; TTL: <strong><em>Auto</em></strong>; Priority: <em><strong>10</strong></em></li>
<li>Type: <em><strong>MX</strong></em>; Name <strong><em>mg.boolfalse.com</em></strong>; Mail Server: <em><strong>mxb.mailgun.org</strong></em>; TTL: <strong><em>Auto</em></strong>; Priority: <strong><em>10</em></strong></li>
<li>Type: <strong><em>CNAME</em></strong>; Name: <strong><em>email</em></strong>; Target: <strong><em>mailgun.org</em></strong>; TTL: <strong><em>Auto</em></strong>; Proxy Status: <strong><em>On</em></strong></li>
</ul>
<p>In our case, we will add them to Cloudflare.</p>
<p>Below is the first TXT record:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/27-mailgun-dns-record-1-new.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: first TXT record for a new domain</em></p>
<p>Below is the second TXT record:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/29-mailgun-dns-record-2-new.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: second TXT record for a new domain</em></p>
<p>Below is the first MX record:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/30-mailgun-dns-record-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: first MX record for a new domain</em></p>
<p>Below is the second MX record:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/31-mailgun-dns-record-4.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: second MX record for a new domain</em></p>
<p>After you've added two TXT and two MX records, you can check and verify them by clicking the "Verify DNS Records" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/32-mailgun-checking-dns-records.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: checking TXT and MX records for a new domain</em></p>
<p>Lastly, add CNAME record.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/33-mailgun-dns-record-5-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: adding CNAME record for a new domain</em></p>
<p>You may see a warning icon on the left of the CNAME record. You don't need to worry about that. Here's what <a target="_blank" href="https://developers.cloudflare.com/ssl/edge-certificates/additional-options/total-tls/error-messages">official documentation</a> says about it:</p>
<blockquote>
<p>If you recently <a target="_blank" href="https://developers.cloudflare.com/fundamentals/setup/manage-domains/add-site/">added your domain</a> to Cloudflare - meaning that your zone is in a <a target="_blank" href="https://developers.cloudflare.com/dns/zone-setups/reference/domain-status/">pending state</a> - you can often ignore this warning.<br>Once most domains becomes <strong>Active</strong>, Cloudflare will automatically issue a Universal SSL certificate, which will provide SSL/TLS coverage and remove the warning message.</p>
</blockquote>
<p>After adding a CNAME record, you can check and verify it again by clicking the second "Verify DNS Records" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/34-mailgun-checking-dns-records.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: checking CNAME record for a new domain</em></p>
<p>If you have added all 5 records on the Cloudflare successfully, after clicking the verifying button, Mailgun will automatically redirect you to the <strong>Overview</strong> page.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/36-mailgun-verified-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: 2 TXT, 2 MX and 1 CNAME records added for a new domain</em></p>
<p>It means you're ready to add a Sending API key on Mailgun.</p>
<h2 id="heading-mailgun-sending-api-key-amp-smpt-user">Mailgun: Sending API key &amp; SMPT User</h2>
<p>Go to <strong>Sending</strong> -&gt; <strong>Domain Settings</strong> page. Choose the <strong>Sending API keys</strong> tab at the top. You probably won't see any API keys there. You just need to create a new Sending API key. </p>
<p>Click "Add sending key" from the top right corner, and in the pop-up, fill the name of the key you're about to create.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/37-mailgun-create-sending-api-key-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: creating a Sending API key</em></p>
<p>After pressing "Create sending key", you'll get the secret API key that you need to copy and save somewhere safe. After saving the key, you can just close the pop-up.</p>
<p>You should see the created key listed:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/38-mailgun-sending-api-key-created.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: Sending API key created</em></p>
<p>You also need to create a new SMTP user in the Mailgun dashbaord.<br>Go to <strong>Sending</strong> -&gt; <strong>Domain Settings</strong> page. Choose the <strong>SMTP credentials</strong> tab at the top and click the "Add new SMTP user" button on the top left corner. It will open up a pop-up. </p>
<p>Type user credentials there. In our case I'll create a user with the name "email". It will be like a login for your email on Gmail.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/41-mailgun-create-smtp-user.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: creating SMTP user</em></p>
<p>Once you create an SMTP user in Mailgun, you'll see it listed and a password for that user will be generated automatically. To get this password, copy it by clicking the "Copy" button in the pop-up notification in the lower right corner.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/42-mailgun-smtp-user-created.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: SMTP user created</em></p>
<p>Keep this in a safe place for future use. You will need this login and password to authenticate on Gmail.</p>
<p>You are now ready to set up email configurations with your email provider. In our case, we will do this in Gmail.</p>
<p>Open your Gmail account in your desktop browser and go to Settings by clicking the settings icon in the top right corner and click the "See all settings" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/39-gmail-settings-page.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mailgun: new domain is verified</em></p>
<h2 id="heading-gmail-authentication-with-mailgun-smtp-server">Gmail Authentication with Mailgun SMTP Server</h2>
<p>In the Gmail settings page choose the <strong>Accounts and Import</strong> tab and click on the "Add another email address" from the "Send mail as" section:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/40-gmail-add-another-email-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Gmail: Settings</em></p>
<p>It will open a pop-up for the authentication. Use the login and the password you just got by creating an SMTP user on Mailgun. Make sure to fill out the credentials correctly.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/43-gmail-add-smtp-user.png" alt="Image" width="600" height="400" loading="lazy">
<em>Gmail: authenticate a new user using a created SMTP server on Mailgun</em></p>
<p>Submit the form by clicking the "Add Account" button. It'll probably ask you to save the username/password in your browser. It's up to you.</p>
<p>And the last important thing here: it'll ask you to verify adding an account.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/44-gmail-verify-account.png" alt="Image" width="600" height="400" loading="lazy">
<em>Gmail: authentication confirmation for a new user</em></p>
<p>For the verification, the confirmation email will be sent to your primary email.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/45-gmail-confirmation-code.png" alt="Image" width="600" height="400" loading="lazy">
<em>Gmail: authentication verification email</em></p>
<p>You can either use the confirmation code to verify it using the pop-up window or simply follow the link provided in the confirmation email.</p>
<p>In this case, we'll click on a link which will open the page, where you'll be asked to confirm. Click on "Confirm" and simply close the previously opened pop-up window without worrying.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/47-gmail-adding-user-confirmed.png" alt="Image" width="600" height="400" loading="lazy">
<em>Gmail: verifying the authentication</em></p>
<p>Now you're ready to send and receive emails from the custom email you just created.</p>
<p>For sending an email from the custom email, you just need to choose that email as a sender email:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/49-gmail-send-emails-from-custom-email.png" alt="Image" width="600" height="400" loading="lazy">
<em>Gmail: sending emails</em></p>
<p><strong>That's it!</strong></p>
<p>An additional thing that may be useful to you is that you can set the custom email address you just created as the default address for sending emails from Gmail.</p>
<p>You can set this on the settings page in the "Send mail as" section:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/48-gmail-another-email-default.png" alt="Image" width="600" height="400" loading="lazy">
<em>Gmail: Settings (default sender)</em></p>
<p>I hope this guide will be a good resource for setting up your custom email.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this article, you learned how to set up your own email to manage emails in Gmail using Cloudflare Email and Mailgun.</p>
<p>In conclusion, it is worth noting that the choice of tools is not mandatory, other tools can be used instead, but the basic idea and logic will be similar.</p>
<p>You can check out my website at: <a target="_blank" href="https://boolfalse.com/"><strong>boolfalse.com</strong></a></p>
<p>Feel free to share this article. 😇</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Send Emails With Nodemailer in NestJS ]]>
                </title>
                <description>
                    <![CDATA[ By Okure U. Edet While learning Nestjs, I wanted to be able to send test emails with Nodemailer but I had difficulty doing this in the context of a NestJS application. I searched the internet for a solution and after much research, I found one. It tu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-nodemailer-in-nestjs/</link>
                <guid isPermaLink="false">66d4608df855545810e934b3</guid>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ nestjs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ projects ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 10 Apr 2024 11:52:29 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/joanna-kosinska-uGcDWKN91Fs-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Okure U. Edet</p>
<p>While learning Nestjs, I wanted to be able to send test emails with Nodemailer but I had difficulty doing this in the context of a NestJS application. I searched the internet for a solution and after much research, I found one. It turned out to be really simple.</p>
<p>In this article, I will share my solution so you can use it in your NestJS projects.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-set-up-a-nestjs-project">How to Set Up a NestJS Project</a></li>
<li><a class="post-section-overview" href="#heading-how-to-configure-nodemailer-in-your-app">How to Configure Nodemailer in Your App</a></li>
<li><a class="post-section-overview" href="#heading-how-to-send-emails-with-nodemailer">How to Send emails with Nodemailer</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h3 id="heading-how-to-set-up-a-nestjs-project">How to Set Up a NestJS Project</h3>
<p>Ideally, when a user clicks on a forget password route, a link should be sent to the user's email, and through that link, the user should be able to reset their password. This article will demonstrate a test case scenario of how this works using Nodemailer.</p>
<p>Open your favorite IDE or navigate to the terminal and paste the following command:</p>
<pre><code>$ npm i -g @nestjs/cli
$ nest <span class="hljs-keyword">new</span> nodemailer-app
</code></pre><p>The above commands generates a new project called  <code>nodemailer-app</code>. </p>
<p>After doing this, navigate to your project folder and install the Nodemailer packages, <code>npm i --save @nestjs-modules/mailer nodemailer</code> and types, <code>npm i --save-dev @types/nodemailer</code>.</p>
<h3 id="heading-how-to-configure-nodemailer-in-your-app">How to Configure Nodemailer in Your App</h3>
<p>Before moving on, make sure you have an account on <a target="_blank" href="https://mailtrap.io/">mailtrap.io</a>. If you do, just login and navigate to <strong>Email Testing</strong>. Create your own inbox if you don't have one. Navigate to the inbox and you should see your credentials which will be used to configure Nodemailer in your application.</p>
<p>In your project directory, go to the app module file and configure the package:</p>
<pre><code><span class="hljs-keyword">import</span> { Module } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { AppController } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.controller'</span>;
<span class="hljs-keyword">import</span> { AppService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.service'</span>;
<span class="hljs-keyword">import</span> { AuthModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./auth/auth.module'</span>;
<span class="hljs-keyword">import</span> { MailerModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs-modules/mailer'</span>;

@Module({
  <span class="hljs-attr">imports</span>: [
    AuthModule,
    MailerModule.forRoot({
      <span class="hljs-attr">transport</span>: {
        <span class="hljs-attr">host</span>: process.env.EMAIL_HOST,
        <span class="hljs-attr">auth</span>: {
          <span class="hljs-attr">user</span>: process.env.EMAIL_USERNAME,
          <span class="hljs-attr">pass</span>: process.env.EMAIL_PASSWORD,
        },
      },
    }),
  ],
  <span class="hljs-attr">controllers</span>: [AppController],
  <span class="hljs-attr">providers</span>: [AppService],
})
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppModule</span> </span>{}
</code></pre><p>In the above code, you imported the <code>MailerModule</code> from <code>@nestjs-modules/mailer</code>. Then you called a <code>forRoot()</code> method on it. Inside the <code>forRoot()</code> method, you specified a transport property which contains the host and auth properties.</p>
<p>Do not forget to get the host, port, username and password from your credentials in your inbox on <a target="_blank" href="https://mailtrap.io/">mailtrap.io</a>.</p>
<p>You can create a <code>.env</code> file which would house all your credential details. It is advisable to do so. To be able to load the appropriate <code>.env</code> file in NestJS, install this:</p>
<pre><code>$ npm i --save @nestjs/config
</code></pre><p>Then in your <code>app.module.ts</code> file, import a <code>ConfigModule</code>:</p>
<pre><code><span class="hljs-keyword">import</span> { ConfigModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/config'</span>;
</code></pre><p>Still in your <code>app.module.ts</code></p>
<pre><code><span class="hljs-comment">// include the config module in your imports array</span>

@Module({
  <span class="hljs-attr">imports</span>: [
    ConfigModule.forRoot({ <span class="hljs-attr">envFilePath</span>: <span class="hljs-string">'.env'</span>, <span class="hljs-attr">isGlobal</span>: <span class="hljs-literal">true</span> }),
  ],
  <span class="hljs-attr">controllers</span>: [AppController],
  <span class="hljs-attr">providers</span>: [AppService],
})
</code></pre><h3 id="heading-how-to-send-emails-with-nodemailer">How to Send Emails with NodeMailer</h3>
<p>After configuring Nodemailer, it is time to send emails with it.</p>
<p>In your <code>app.service.ts</code> file, paste the following code:</p>
<pre><code><span class="hljs-keyword">import</span> { MailerService } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs-modules/mailer'</span>;
<span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;

@Injectable()
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppService</span> </span>{
  <span class="hljs-keyword">constructor</span>(private readonly mailService: MailerService) {}

  sendMail() {
    <span class="hljs-keyword">const</span> message = <span class="hljs-string">`Forgot your password? If you didn't forget your password, please ignore this email!`</span>;

    <span class="hljs-built_in">this</span>.mailService.sendMail({
      <span class="hljs-attr">from</span>: <span class="hljs-string">'Kingsley Okure &lt;kingsleyokgeorge@gmail.com&gt;'</span>,
      <span class="hljs-attr">to</span>: <span class="hljs-string">'joanna@gmail.com'</span>,
      <span class="hljs-attr">subject</span>: <span class="hljs-string">`How to Send Emails with Nodemailer`</span>,
      <span class="hljs-attr">text</span>: message,
    });
  }
}
</code></pre><p>In the <code>app.service.ts</code> file, the <code>MailerService</code> is injected and then used in the class to send the email. Inside the class, the <code>MailerService</code> has a <code>sendMail</code> function which takes in an object as a parameter. The object contains a <code>from</code>, <code>to</code>, <code>subject</code> and <code>text</code> property.</p>
<p>Once you have done this, in the <code>app.controller.ts</code> file, paste the following code:</p>
<pre><code><span class="hljs-keyword">import</span> { Controller, Get, Res } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { AppService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.service'</span>;

@Controller()
<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppController</span> </span>{
  <span class="hljs-keyword">constructor</span>(private readonly appService: AppService) {}

  @Get()
  sendMailer(@Res() response: any) {
    <span class="hljs-keyword">const</span> mail = <span class="hljs-built_in">this</span>.appService.sendMail();

    <span class="hljs-keyword">return</span> response.status(<span class="hljs-number">200</span>).json({
      <span class="hljs-attr">message</span>: <span class="hljs-string">'success'</span>,
      mail,
    });
  }
}
</code></pre><p>All that is done in the controller is to create a <code>Get</code> request which will call the <code>sendMail</code> function you have created in the service.</p>
<p>Ideally, in a real world application, all this will be done in a forgot password function. And an email will be sent to the user once they click on a forgot password route.</p>
<p>To test this little setup, open your Postman and go to localhost:3000 and hit send.</p>
<p>Then go to your <a target="_blank" href="https://mailtrap.io/inboxes/2445842/messages">mailtrap.io</a> inbox and see your message.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>In this article, you have learned how to send emails with Nodemailer, a software designed to help developers send emails to multiple people at once. </p>
<p>You have also learned how to configure and set it up in the context of a NestJs application.</p>
<p>If you want to connect with me, you can follow me on <a target="_blank" href="https://twitter.com/itzz_okure">Twitter</a> or on <a target="_blank" href="https://www.linkedin.com/in/okure/">Linkedin</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use an Email Validation Service for Flask User Authentication ]]>
                </title>
                <description>
                    <![CDATA[ In today's digital world, online security is really important, and user authentication is a key aspect of it.  Email-based authentication is one of the most popular and widely used methods for user registration and login. But it's not always reliable... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-email-validation-api-for-flask-user-authentication/</link>
                <guid isPermaLink="false">66ba0ea5228e16bed602a896</guid>
                
                    <category>
                        <![CDATA[ authentication ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Flask Framework ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Krishna ]]>
                </dc:creator>
                <pubDate>Thu, 30 Mar 2023 22:22:39 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/email-validation-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In today's digital world, online security is really important, and user authentication is a key aspect of it. </p>
<p><a target="_blank" href="https://ashutoshkrris.hashnode.dev/how-to-set-up-email-verification-in-a-flask-app">Email-based authentication</a> is one of the most popular and widely used methods for user registration and login. But it's not always reliable, as users can enter fake or invalid email addresses during registration. This can lead to security risks and fraud. This is where Email Validation Services come in handy.</p>
<p>In this tutorial, you'll use the <a target="_blank" href="https://emailvalidation.io/">Email Validation Service</a> to help you automate your email validation process during user registration by validating contact information. </p>
<p>The API checks the syntax, domain, and mailbox of an email address, and can even detect disposable and risky emails. </p>
<p>By integrating this API with your application, you can ensure that only valid and genuine email addresses are used for user registration, which will enhance the security of your application.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you get started with the tutorial, make sure you have satisfied the following requirements:</p>
<ul>
<li>Working knowledge of Python</li>
<li>Python 3.8+ installed on your system</li>
<li>Basic knowledge of <a target="_blank" href="https://ashutoshkrris.hashnode.dev/getting-started-with-flask">Flask</a>, <a target="_blank" href="https://ashutoshkrris.hashnode.dev/how-to-use-blueprints-to-organize-your-flask-apps">Flask Blueprints</a> and <a target="_blank" href="https://blog.ashutoshkrris.in/how-to-interact-with-web-services-using-python">Requests</a>.</li>
</ul>
<h2 id="heading-how-to-set-up-the-virtual-environment">How to Set Up the Virtual Environment</h2>
<p>Before you start coding, you'll need to make sure you have all the necessary tools and libraries installed. To ensure that you have a clean and isolated environment, you'll create a virtual environment using <code>venv</code>.</p>
<p>Create a project directory and navigate to it in the terminal:</p>
<pre><code class="lang-bash">mkdir email-validation
<span class="hljs-built_in">cd</span> email-validation
</code></pre>
<p>Create a virtual environment named <code>env</code> using the following command:</p>
<pre><code class="lang-bash">python -m venv env
</code></pre>
<p>Python now ships with pre-installed <code>venv</code> library to create virtual environments.</p>
<p>Activate the virtual environment like this:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> env/bin/activate
</code></pre>
<p>Note: If you're on Windows, you'll need to use <code>source env/Scripts/activate</code> to activate the environment.</p>
<p>You should see <code>(env)</code> in your terminal prompt, indicating that the virtual environment has been activated.</p>
<h2 id="heading-how-email-validation-service-works">How Email Validation Service Works</h2>
<p>Email validation is an essential process for any web application that requires user authentication, and there are various ways to perform it. </p>
<p>One way is to use an email validation service such as <a target="_blank" href="https://emailvalidation.io/">emailvalidation.io</a>. This API allows developers to validate email addresses by checking whether they are syntactically correct, whether the domain exists, and whether the mailbox can receive messages.</p>
<p>The API offers a range of <a target="_blank" href="https://emailvalidation.io/pricing/">pricing plans</a> to suit different needs. The free plan allows developers to validate up to 100 emails, which should be sufficient for our testing purposes. The paid plans start at $9.99 per month and offer more requests, more features, and faster response times.</p>
<p>In this section, you'll write a Python function that sends a GET request to the API's endpoint and passes the email address to be validated as a parameter. </p>
<p>To authenticate the API request, you will also need to pass the API key with the request. Before proceeding, you must create an account on emailvalidation.io to obtain an API key. Once you've created your account, you will be redirected to a dashboard, similar to the one shown below. The API key is located in the black highlighted area.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/Screenshot-2023-03-29-112311.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>To make a GET request, you'll need to install the <code>requests</code> library in your virtual environment:</p>
<pre><code class="lang-bash">pip install requests
</code></pre>
<p>Next, create a <code>test.py</code> file and add the following code there:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> requests.structures <span class="hljs-keyword">import</span> CaseInsensitiveDict


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_valid</span>(<span class="hljs-params">email: str</span>):</span>
    url = <span class="hljs-string">f"https://api.emailvalidation.io/v1/info?email=<span class="hljs-subst">{email}</span>"</span>

    headers = CaseInsensitiveDict()
    headers[<span class="hljs-string">"apikey"</span>] = <span class="hljs-string">"your-api-key-here"</span>

    response = requests.get(url, headers=headers)

    <span class="hljs-keyword">return</span> response.json()


print(is_valid(<span class="hljs-string">"support@emailvalidation.io"</span>))
print(is_valid(<span class="hljs-string">"venip42579@jdsdhak.com"</span>))
</code></pre>
<p>The <code>is_valid</code> function takes an email address as an argument and constructs a URL with the email address to call the emailvalidation.io API. The <code>CaseInsensitiveDict</code> class from the <code>requests.structures</code> module is used to create a dictionary with case-insensitive keys to set the API key in the header of the request. You then return the JSON response from the function.</p>
<p>Finally, you call the <code>is_valid</code> function twice with different email addresses to demonstrate how the function can validate both a valid email address (<code>support@emailvalidation.io</code>) and an invalid email address (<code>venip42579@jdsdhak.com</code>).</p>
<p>Output:</p>
<pre><code class="lang-bash">{
   <span class="hljs-string">"email"</span>:<span class="hljs-string">"support@emailvalidation.io"</span>,
   <span class="hljs-string">"user"</span>:<span class="hljs-string">"support"</span>,
   <span class="hljs-string">"tag"</span>:<span class="hljs-string">""</span>,
   <span class="hljs-string">"domain"</span>:<span class="hljs-string">"emailvalidation.io"</span>,
   <span class="hljs-string">"smtp_check"</span>:<span class="hljs-literal">true</span>,
   <span class="hljs-string">"mx_found"</span>:<span class="hljs-literal">true</span>,
   <span class="hljs-string">"did_you_mean"</span>:<span class="hljs-string">""</span>,
   <span class="hljs-string">"role"</span>:<span class="hljs-literal">true</span>,
   <span class="hljs-string">"disposable"</span>:<span class="hljs-literal">false</span>,
   <span class="hljs-string">"score"</span>:0.64,
   <span class="hljs-string">"state"</span>:<span class="hljs-string">"deliverable"</span>,
   <span class="hljs-string">"reason"</span>:<span class="hljs-string">"valid_mailbox"</span>,
   <span class="hljs-string">"free"</span>:<span class="hljs-literal">false</span>,
   <span class="hljs-string">"format_valid"</span>:<span class="hljs-literal">true</span>,
   <span class="hljs-string">"catch_all"</span>:<span class="hljs-string">"None"</span>
}
{
   <span class="hljs-string">"email"</span>:<span class="hljs-string">"venip42579@jdsdhak.com"</span>,
   <span class="hljs-string">"user"</span>:<span class="hljs-string">"venip42579"</span>,
   <span class="hljs-string">"tag"</span>:<span class="hljs-string">""</span>,
   <span class="hljs-string">"domain"</span>:<span class="hljs-string">"jdsdhak.com"</span>,
   <span class="hljs-string">"smtp_check"</span>:<span class="hljs-literal">false</span>,
   <span class="hljs-string">"mx_found"</span>:<span class="hljs-literal">false</span>,
   <span class="hljs-string">"did_you_mean"</span>:<span class="hljs-string">""</span>,
   <span class="hljs-string">"role"</span>:<span class="hljs-literal">false</span>,
   <span class="hljs-string">"disposable"</span>:<span class="hljs-literal">false</span>,
   <span class="hljs-string">"score"</span>:0.64,
   <span class="hljs-string">"state"</span>:<span class="hljs-string">"undeliverable"</span>,
   <span class="hljs-string">"reason"</span>:<span class="hljs-string">"invalid_mx"</span>,
   <span class="hljs-string">"free"</span>:<span class="hljs-literal">false</span>,
   <span class="hljs-string">"format_valid"</span>:<span class="hljs-literal">true</span>,
   <span class="hljs-string">"catch_all"</span>:<span class="hljs-string">"None"</span>
}
</code></pre>
<p>You can learn about the different keys in the response <a target="_blank" href="https://emailvalidation.io/docs/info#sample-response">here</a>. To determine if an email address is valid or invalid based on the JSON response from emailvalidation.io, you should check the following fields:</p>
<ol>
<li><code>format_valid</code>: If <code>true</code>, the email address is properly formatted. If <code>false</code>, the email address is not valid.</li>
<li><code>mx_found</code>: If <code>true</code>, at least one MX record was found for the domain. If <code>false</code>, the domain is not valid.</li>
<li><code>smtp_check</code>: If <code>true</code>, the email address has a valid mailbox. If <code>false</code>, the mailbox is not valid.</li>
<li><code>state</code>: The current state of the email address. The values can be "deliverable" or "undeliverable".</li>
</ol>
<p>Thus, you can modify the <code>is_valid</code> function to return a Boolean response instead of a JSON object as below:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> requests.structures <span class="hljs-keyword">import</span> CaseInsensitiveDict


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_valid</span>(<span class="hljs-params">email: str</span>):</span>
    url = <span class="hljs-string">f"https://api.emailvalidation.io/v1/info?email=<span class="hljs-subst">{email}</span>"</span>

    headers = CaseInsensitiveDict()
    headers[<span class="hljs-string">"apikey"</span>] = <span class="hljs-string">"nUH1hmV24lEwX1TIXmsgRPRRZw0L0NuOeHrdMp78"</span>

    response = requests.get(url, headers=headers)
    <span class="hljs-keyword">if</span> response.status_code == <span class="hljs-number">200</span>:
        json_resp = response.json()
        format_valid = json_resp[<span class="hljs-string">"format_valid"</span>]
        mx_found = json_resp[<span class="hljs-string">"mx_found"</span>]
        smtp_check = json_resp[<span class="hljs-string">"smtp_check"</span>]
        state = json_resp[<span class="hljs-string">"state"</span>]

        <span class="hljs-keyword">return</span> format_valid <span class="hljs-keyword">and</span> mx_found <span class="hljs-keyword">and</span> smtp_check <span class="hljs-keyword">and</span> state == <span class="hljs-string">"deliverable"</span>

    <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>


print(is_valid(<span class="hljs-string">"support@emailvalidation.io"</span>))
print(is_valid(<span class="hljs-string">"venip42579@jdsdhak.com"</span>))
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">True
False
</code></pre>
<p>In the upcoming section, you'll use this function to validate emails during user registration.</p>
<h2 id="heading-how-to-set-up-basic-user-authentication-in-flask">How to Set Up Basic User Authentication in Flask</h2>
<p>In this section, you will go through the steps to set up basic user authentication in Flask. You will be using the code from <a target="_blank" href="https://blog.ashutoshkrris.in/how-to-set-up-basic-user-authentication-in-a-flask-app">one of my previous articles</a> where I had explained how to implement basic user authentication. </p>
<p>You can start by pulling the code from the GitHub repository to the <code>email-validation</code> folder:</p>
<pre><code class="lang-bash">git init
git remote add origin https://github.com/ashutoshkrris/Flask-User-Authentication.git
git pull origin main
</code></pre>
<p>Note: The command <code>git clone [https://github.com/ashutoshkrris/Flask-User-Authentication.git](https://github.com/ashutoshkrris/Flask-User-Authentication.git) .</code> won't run in this case because your directory is not empty.</p>
<p>Next, you'll see a <code>requirements.txt</code> file that contains the dependencies to run the the application in your system. Install the dependencies using the command:</p>
<pre><code class="lang-bash">pip install -r requirements.txt
</code></pre>
<p>Once all the dependencies are installed, you'll need to add the environment variables required for the project. The project contains a <code>.env</code> file which has all the environment variables. Run the following command to export all the environment variables from the <code>.env</code> file:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> .env
</code></pre>
<p>Next, you have to create the database. Since the project uses Flask-Migrate, creating the database is a fairly simple task using the following commands:</p>
<pre><code class="lang-bash">python manage.py db init
python manage.py db migrate
python manage.py db upgrade
</code></pre>
<p>Now, you can run the application using the command:</p>
<pre><code class="lang-bash">python manage.py run
</code></pre>
<p>The application will start running and you can go to <code>http://localhost:5000/login</code> in your web browser to see the application.</p>
<p>Here's a demo video that shows the application:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/XxSESg89xEI" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Inside your project <code>flask-validation</code>, you'll have a <code>src</code> folder containing your source code and a <code>tests</code> folder containing the unit tests. </p>
<p>In addition to these, you'll also have a <code>config.py</code> file that contains the configuration settings for your application and a <code>manage.py</code> file that uses Flask-CLI to add different commands for running and testing your application. You'll also find other files such as <code>.env</code> and <code>requirements.txt</code> which you already know about.</p>
<p>The <code>src</code> folder contains four subfolders – <code>accounts</code>, <code>core</code>, <code>templates</code>, and <code>static</code>. The <code>templates</code> and <code>static</code> folders contain the HTML files and static files such as CSS, images, and JavaScript files, respectively. The other two folders, <code>accounts</code> and <code>core</code>, use the concept of <a target="_blank" href="https://blog.ashutoshkrris.in/how-to-use-blueprints-to-organize-your-flask-apps">Flask Blueprints</a> and contain the respective codes for different parts of the application.</p>
<p>If you want to learn more about the implementation of your Flask application, you can refer to <a target="_blank" href="https://blog.ashutoshkrris.in/how-to-set-up-basic-user-authentication-in-a-flask-app">this tutorial</a>.</p>
<h2 id="heading-how-to-integrate-the-email-validation-service-in-your-flask-app">How to Integrate the Email Validation Service in Your Flask App</h2>
<p>Up until this point, it is possible to successfully register in the application using any email address, regardless of whether it is valid or not. </p>
<p>But it's not desirable to have random or incorrect email addresses cluttering up your database. So it's a good idea to validate the email address before registering the user. If the email address is valid, you can proceed with registering the user successfully.</p>
<p>Add your Email Validation API Key in the <code>.env</code> file to so that you can read it without exposing to the public:</p>
<pre><code><span class="hljs-keyword">export</span> SECRET_KEY=fdkjshfhjsdfdskfdsfdcbsjdkfdsdf
<span class="hljs-keyword">export</span> DEBUG=True
<span class="hljs-keyword">export</span> APP_SETTINGS=config.DevelopmentConfig
<span class="hljs-keyword">export</span> DATABASE_URL=sqlite:<span class="hljs-comment">///db.sqlite</span>
<span class="hljs-keyword">export</span> FLASK_APP=src
<span class="hljs-keyword">export</span> FLASK_DEBUG=<span class="hljs-number">1</span>
<span class="hljs-keyword">export</span> API_KEY=your-api-key-here
</code></pre><p>Replace the <code>your-api-key-here</code> with your correct API key. Next, you'll again need to run the following command to export the environment variables:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> .env
</code></pre>
<p>Now, create a <code>utils.py</code> file inside the <code>accounts</code> subfolder in the <code>src</code> folder. The file will contain the utility function to validate the email. Add the following code in the file:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> requests.structures <span class="hljs-keyword">import</span> CaseInsensitiveDict
<span class="hljs-keyword">from</span> decouple <span class="hljs-keyword">import</span> config


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_valid</span>(<span class="hljs-params">email: str</span>):</span>
    url = <span class="hljs-string">f"https://api.emailvalidation.io/v1/info?email=<span class="hljs-subst">{email}</span>"</span>

    headers = CaseInsensitiveDict()
    headers[<span class="hljs-string">"apikey"</span>] = config(<span class="hljs-string">"API_KEY"</span>)

    response = requests.get(url, headers=headers)
    <span class="hljs-keyword">if</span> response.status_code == <span class="hljs-number">200</span>:
        json_resp = response.json()
        format_valid = json_resp[<span class="hljs-string">"format_valid"</span>]
        mx_found = json_resp[<span class="hljs-string">"mx_found"</span>]
        smtp_check = json_resp[<span class="hljs-string">"smtp_check"</span>]
        state = json_resp[<span class="hljs-string">"state"</span>]

        <span class="hljs-keyword">return</span> format_valid <span class="hljs-keyword">and</span> mx_found <span class="hljs-keyword">and</span> smtp_check <span class="hljs-keyword">and</span> state == <span class="hljs-string">"deliverable"</span>

    <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
</code></pre>
<p>As previously mentioned, the <code>is_valid()</code> function returns a Boolean value indicating whether an email address is valid or not. It's important to note that the function doesn't hardcode the API key value, instead it retrieves it from the environment variables.</p>
<p>Next, in the <code>RegisterForm</code> class in the <code>forms.py</code> file, you have a <code>validate</code> method. This method is responsible for validating the input data submitted by the user during the registration process. </p>
<p>Previously, this method only checked if the email was already registered and if the passwords matched. But you can now add an additional validation to check if the email is valid. Thus the modified <code>validate</code> method looks like this:</p>
<pre><code class="lang-python">...

<span class="hljs-keyword">from</span> src.accounts.utils <span class="hljs-keyword">import</span> is_valid

...

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RegisterForm</span>(<span class="hljs-params">FlaskForm</span>):</span>
    ...

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">validate</span>(<span class="hljs-params">self</span>):</span>
        initial_validation = super(RegisterForm, self).validate()
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> initial_validation:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> is_valid(self.email.data):
            self.email.errors.append(<span class="hljs-string">"Email is invalid"</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
        user = User.query.filter_by(email=self.email.data).first()
        <span class="hljs-keyword">if</span> user:
            self.email.errors.append(<span class="hljs-string">"Email already registered"</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
        <span class="hljs-keyword">if</span> self.password.data != self.confirm.data:
            self.password.errors.append(<span class="hljs-string">"Passwords must match"</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre>
<p>In the <code>validate</code> method, if the <code>self.email.data</code> (that is the user's email address) is not valid, you append an error message to the <code>self.email.errors</code> list and return <code>False</code> which means the user data is not valid.</p>
<p>Now, when you run the application and try to register, you can see it live. Here's a demo showing both valid and invalid cases.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/Validation-Demo-Made-with-Clipchamp.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-other-use-cases-of-an-email-validation-service">Other Use Cases of an Email Validation Service</h2>
<p>Apart from validating a user's email during registration, there are several other use cases for Email Validation Services. Some of these are:</p>
<ol>
<li>Cleaning Email Lists: you can use email validation services to clean email lists by removing invalid, non-existent or risky email addresses. This can help to improve email deliverability and ensure that your emails reach the intended recipients.</li>
<li>Preventing Fraudulent Activities: you can also use email validation services to detect fraudulent activities such as fake account creation or fraudulent orders. By validating the email addresses associated with these activities, you can prevent such activities from happening.</li>
<li>Enhancing marketing campaigns: these services can also help improve the accuracy and effectiveness of email marketing campaigns. By ensuring that email addresses are valid and active, businesses can increase their email deliverability rates and improve their overall campaign performance.</li>
</ol>
<p>Overall, email validation services can be a powerful tool in ensuring the accuracy and validity of user data, preventing fraud, and improving the user experience.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Email validation services are a powerful tool for any application that requires verifying user email addresses. It is essential to ensure that email addresses are valid to prevent errors and to ensure that the user input data is correct. </p>
<p>In this article, you saw how to use the <a target="_blank" href="https://emailvalidation.io/">emailvalidation.io</a> API to validate an email address in Python. You also learned other potential use cases for email validation services, such as fraud detection and email marketing. </p>
<p>By implementing email validation services in your application, you can improve your user experience and ensure that your data is accurate and up-to-date.</p>
<h3 id="heading-additional-resources">Additional Resources</h3>
<ul>
<li><a target="_blank" href="https://blog.ashutoshkrris.in/how-to-use-blueprints-to-organize-your-flask-apps">How to Use Blueprints to Organize Your Flask Apps</a></li>
<li><a target="_blank" href="https://blog.ashutoshkrris.in/how-to-set-up-email-verification-in-a-flask-app">How to Set Up Email Verification in a Flask App</a></li>
<li><a target="_blank" href="https://emailvalidation.io/docs/">emailvalidation.io Documentation</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up AWS Simple Email Service ]]>
                </title>
                <description>
                    <![CDATA[ If you're looking for a reliable and cost-effective way to send emails, AWS Simple Email Service (SES) is a great option. It's a cloud-based email platform that helps you send and receive emails quickly and easily.  With SES, you don't have to worry ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/set-up-aws-simple-email-service/</link>
                <guid isPermaLink="false">66c4c64a26a77d9936ef0a6b</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Cloud ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sophia Iroegbu ]]>
                </dc:creator>
                <pubDate>Mon, 27 Mar 2023 15:44:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/Blog-Banner---Template--3-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you're looking for a reliable and cost-effective way to send emails, AWS Simple Email Service (SES) is a great option. It's a cloud-based email platform that helps you send and receive emails quickly and easily. </p>
<p>With SES, you don't have to worry about managing your mail server, and you can benefit from the scalability and reliability of Amazon's cloud infrastructure. </p>
<p>There are a few steps to setting up SES, such as verifying your domain, verifying your email address, and setting up MX records. This short guide will walk you through each step to get your SES up and running in no time.  </p>
<p><strong>Prerequisites:</strong> This tutorial will be a hands-on demonstration. To follow along, be sure you have an active <a target="_blank" href="https://aws.amazon.com/free/">AWS account</a>.</p>
<h2 id="heading-how-to-configure-aws-ses">How to Configure AWS SES</h2>
<h3 id="heading-step-1-verify-identities">Step 1 – Verify Identities</h3>
<p>First, login into your AWS Management Console account and search for Simple Email Service. Select the <strong>Amazon Simple Email Service.</strong></p>
<p><img src="https://i.imgur.com/8ZjaAKn.png" alt="Image" width="2397" height="1262" loading="lazy">
<em>Searching for AWS SES</em></p>
<p>This will lead you to an SES Console.</p>
<p>To start sending emails, you'll need to create an identity. This involves verifying the email address you would use to send emails. If you do not verify the email address, you can't use the email to perform any action on SES. </p>
<p>Note you can add a domain as an identity, but we'll use an email address for this guide. Click <strong>Create identity</strong> to verify an email address.</p>
<p><img src="https://i.imgur.com/8xrgwvL.png" alt="Image" width="2390" height="1158" loading="lazy">
<em>Creating an Identity</em></p>
<p>Next, select the <strong>Email address</strong> option and enter the email address you wish to use.</p>
<p>In Amazon SES, you can use a domain, subdomain, or email address as a <em>verified</em> identity. You may use whatever suits you best.</p>
<p><img src="https://i.imgur.com/apfMPNY.png" alt="Image" width="2321" height="1004" loading="lazy">
<em>Verifying an Identity</em></p>
<p>We use tags to manage identities on Amazon SES. We'll skip this here, but if you wish, you can define a tag. Once you're done, click <strong>Create identity</strong> to create an identity for your SES account.</p>
<p><img src="https://i.imgur.com/8e6swKE.png" alt="Image" width="1495" height="493" loading="lazy">
<em>Creating an Identity for Amazon SES</em></p>
<p>Now, an email will be sent to the email address you used to create the identity. Click the link in the email to verify your email.</p>
<p><img src="https://paper-attachments.dropboxusercontent.com/s_8C16BB81FDF5129198CC129A07A220ADD326C1D4AD8E16A42ED5864426B31F5B_1670344969240_6DeFvpt.png" alt="Image" width="1266" height="1008" loading="lazy">
<em>Verifying your email address</em></p>
<p>Once you've done that, you will see your email address on your SES account's list of verified identities.</p>
<p><img src="https://i.imgur.com/22Q4jrr.png" alt="Image" width="1838" height="1021" loading="lazy">
<em>List of verified identities</em></p>
<h2 id="heading-how-to-create-smtp-credentials">How to Create SMTP Credentials</h2>
<p>A Simple Mail Transfer Protocol (SMTP) sends and receives messages through a mail server. In this section, you will learn how to create credentials that grant you access to the SES mail server to send and receive mail. </p>
<p>First, log in to your <a target="_blank" href="https://us-east-1.console.aws.amazon.com/ses/home?region=us-east-1#/account">Amazon SES dashboard</a>. Click on <strong>SMTP settings.</strong></p>
<p><img src="https://i.imgur.com/1LsYmUe.png" alt="Image" width="2344" height="1142" loading="lazy">
<em>Amazon SES Dashboard</em></p>
<p>Then click on <strong>Create SMTP</strong> <strong>credentials</strong> to create login details to your SMTP account under Amazon SES.</p>
<p><img src="https://i.imgur.com/M4e6D2p.png" alt="Image" width="2344" height="1070" loading="lazy">
<em>Creating SMTP Credentials</em></p>
<p>You can choose to define an IAM username or use the default. Once you've done that, click <strong>Create</strong>.</p>
<p><img src="https://i.imgur.com/pI1OI2R.png" alt="Image" width="2381" height="1131" loading="lazy">
<em>Creating IAM user for SMTP</em></p>
<p>Once you create an IAM user, your SMTP details will be displayed alongside your IAM username.</p>
<p>A notification telling you your user has been created will be displayed at the top. Make sure you download the credentials since it is a One-Time display detail. You can download them by clicking on <strong>Download Credentials</strong>.</p>
<p><img src="https://i.imgur.com/uc8Pxta.png" alt="Image" width="2386" height="1141" loading="lazy">
<em>Created SMTP Credentials</em></p>
<p>Great! You have access to AWS Simple Email Service SMTP credentials. You can use the credentials to connect your backend to the Amazon SES server to send emails. </p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Amazon Simple Email Service (SES) is a powerful and reliable tool for quickly sending marketing, notification, and transactional emails. Setting up Amazon SES is straightforward and you can do it in just a few simple steps. </p>
<p>After signing up for an AWS account and accessing the Amazon SES console, you can verify and set a default email address and start sending emails using the service. </p>
<p>With Amazon SES, you can enjoy the benefits of cloud-based email sending, including improved deliverability, scalability, and security.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Schedule an Email in Gmail – a Step-by-Step Guide ]]>
                </title>
                <description>
                    <![CDATA[ Sometimes you might want to compose an email but send it later. Well, did you know that Gmail allows you to schedule up to 100 emails? In this article, you will learn how to schedule your emails using Gmail. There's no need to install any software or... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/schedule-email-in-gmail/</link>
                <guid isPermaLink="false">66d45de5182810487e0ce10e</guid>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gmail ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Benjamin Semah ]]>
                </dc:creator>
                <pubDate>Wed, 30 Nov 2022 22:23:40 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/11/email-gd2563c0fc_1280.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Sometimes you might want to compose an email but send it later. Well, did you know that Gmail allows you to schedule up to 100 emails?</p>
<p>In this article, you will learn how to schedule your emails using Gmail. There's no need to install any software or plugins.</p>
<h2 id="heading-what-you-will-learn">What you will learn</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-schedule-an-email-in-gmail">How to schedule an email in Gmail</a></p>
</li>
<li><p><a class="post-section-overview" href="#how-to-view-or-edit-a-scheduled-email-in-gmail">How to view or edit a scheduled email in Gmail</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-cancel-a-scheduled-email-in-gmail">How to cancel a scheduled email in Gmail</a></p>
</li>
</ul>
<h2 id="heading-how-to-schedule-an-email-in-gmail">How to Schedule an Email in Gmail</h2>
<p><strong>Step 1:</strong> Log in to your Gmail account.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/1.-login.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2:</strong> Click compose to create your email.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/2.-click-compose.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3:</strong> Create the email you want to schedule.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/3.-create-email.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4:</strong> Click the Down arrow on the <code>Send</code> button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/4.-click-arrow.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 5:</strong> Click <code>Schedule send</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/5.-schedule-send.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 6:</strong> The popup modal give you a few options. You can choose one. Or you can create a custom date/time by clicking <code>Select date and time</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/6.-select-date-time.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 7:</strong> Click the <code>Schedule send</code> button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/7.-schedule-send2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>That's it! Your email is now scheduled. You will see a notification from Gmail (like the one below) confirming a successful schedule.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/8.-success-schedule.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, let's see how you can edit a scheduled mail in Gmail. This can be either editing the content of the mail or changing the scheduled time.</p>
<h2 id="heading-how-to-edit-a-scheduled-email-in-gmail">How to Edit a Scheduled Email in Gmail</h2>
<p>Assuming you are already logged in to your Gmail, continue with the steps below. If not, first login and then continue with the steps below.</p>
<p><strong>Step 1:</strong> To edit a scheduled email, click <code>Scheduled</code> on the left panel.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/scheduled.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2:</strong> You will be presented with a list of your scheduled emails. Select the email you want to edit.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/schedule-list.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3:</strong> Click <code>Cancel send</code> at the top right of your email.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/cancel-send.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4:</strong> Make the changes if you want to edit the content of your email. If you only want to change the scheduled time, move to Step 5.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/edit-schedule.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 5:</strong> Next, you use the same process you used for the initial schedule.</p>
<ul>
<li><p>Click the down arrow next to the <code>Send</code> button.</p>
</li>
<li><p>And then click <code>Schedule send</code>.</p>
</li>
<li><p>Choose a new date and time.</p>
</li>
</ul>
<p>That's it! You've successfully edited the scheduled email.</p>
<h2 id="heading-how-to-cancel-a-scheduled-email-in-gmail">How to Cancel a Scheduled Email in Gmail</h2>
<p>Assuming you are already logged in to your Gmail, continue with the steps below. If not, first login and then continue with the steps below.</p>
<p><strong>Step 1:</strong> To cancel a scheduled email, click <code>Scheduled</code> on the left panel.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/scheduled-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2:</strong> You will be presented with a list of your scheduled emails. Select the email you want to cancel.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/schedule-list-1.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3:</strong> Click <code>Cancel send</code> at the top right of your email.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/cancel-send-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Note that cancelling a scheduled email in Gmail does not delete it. Gmail treats it as a draft and adds it to the drafts folder. See the Gmail notification below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/msg-revert.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You now know how to do the following.</p>
<ul>
<li><p>Schedule an email in Gmail.</p>
</li>
<li><p>Edit or change the date/time for a scheduled email.</p>
</li>
<li><p>Cancel a scheduled email.</p>
</li>
</ul>
<p>You can also check out this <a target="_blank" href="https://www.freecodecamp.org/news/how-to-batch-delete-emails-in-gmail-delete-multiple-email-messages/">freeCodeCamp article on how to batch delete Emails</a>.</p>
<p>Thanks for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Email Alias – How to Set Up a Professional Email for Free ]]>
                </title>
                <description>
                    <![CDATA[ I needed to log in to AWS. But my main email address was rejected. Apparently I'd done this in the past and the account had been irreversibly deleted.  No reset option – just a message saying the account was permanently deleted: There are about a mi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/email-alias-set-up-a-professional-email-for-free/</link>
                <guid isPermaLink="false">66b8dddeb745d15a90afe346</guid>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gmail ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eamonn Cottrell ]]>
                </dc:creator>
                <pubDate>Wed, 12 Oct 2022 22:26:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/Email-Alias-with-Gmail.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I needed to log in to AWS. But my main email address was rejected. Apparently I'd done this in the past and the account had been irreversibly deleted. </p>
<p>No reset option – just a message saying the account was permanently deleted:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-2.17.29-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>There are about a million ways to get a new email address, but I wanted to set up one of the domains I own with email. </p>
<p>And I figured there would probably be a way to have that forwarded to my Gmail.</p>
<p>I was right!</p>
<p>In this quick guide, I'll walk you through:</p>
<ul>
<li>How to create an email alias</li>
<li>Forwarding mail from the alias to a Gmail account</li>
<li>Sending mail as the Email Alias</li>
</ul>
<h2 id="heading-how-to-create-an-email-alias">How to Create an Email Alias</h2>
<p>I'm using Google products: <a target="_blank" href="https://domains.google.com/registrar/">Google Domains</a> and <a target="_blank" href="https://gmail.com/">Gmail</a>. All these steps should apply generally to other Domain and Email services.</p>
<p>First, login to your domain provider and select the <strong>Email</strong> menu. You will be able to select "<strong>Add email alias</strong>" from the menu options. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-2.37.40-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-forward-email-to-another-address">How to Forward Email to Another Address</h2>
<p>Note: if you add the asterisk (*) symbol, this will create a wildcard alias that forwards any email to the specified address. We'll be adding a specific alias in this tutorial.</p>
<p>Add whatever email you choose and enter where you'd like it to be forwarded to. I'll have <strong>hi@sieis.com</strong> forwarded to my main Gmail address.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-2.41.16-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you are using Google Name servers, then Google Domains will automatically set up the correct mail records (MX).</p>
<p>Otherwise, you'll need to set up these MX records. The process is exactly like setting up name servers if you've ever done that to host your website somewhere different than where you purchased the domain.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Name/Host/Alias</td><td>Type</td><td>Time-to-live (TTL)</td><td>Priority</td><td>Value/Answer/Destination</td></tr>
</thead>
<tbody>
<tr>
<td>Blank or @</td><td>MX</td><td>1H</td><td>5</td><td>gmr-smtp-in.l.google.com</td></tr>
<tr>
<td>Blank or @</td><td>MX</td><td>1H</td><td>10</td><td>alt1.gmr-smtp-in.l.google.com</td></tr>
<tr>
<td>Blank or @</td><td>MX</td><td>1H</td><td>20</td><td>alt2.gmr-smtp-in.l.google.com</td></tr>
<tr>
<td>Blank or @</td><td>MX</td><td>1H</td><td>30</td><td>alt3.gmr-smtp-in.l.google.com</td></tr>
<tr>
<td>Blank or @</td><td>MX</td><td>1H</td><td>40</td><td>alt4.gmr-smtp-in.l.google.com</td></tr>
</tbody>
</table>
</div><p>Bonus: I've done this for a site hosted on Netlify, and it is very straightforward. From the Netlify dashboard, select <strong>Options</strong>, <strong>Go to DNS panel</strong>, and then enter the MX records:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.42.25-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>👇</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.42.53-PM-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Google will send a one time verification email here, but if you've previously done this verification it may not send another one.</p>
<p>Send yourself an email from a different address and check it out!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.02.53-PM-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Email sent to Alias and forwarded to main Gmail</em></p>
<p>Note: sending from your main Gmail address doesn't show up as an unread message like it normally would when you email yourself. Send it from a different address at this point. After the rest of the steps, it will behave as normal when we complete the "send email as alias" part.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.04.35-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-send-email-as-the-alias">How to Send Email as the Alias</h2>
<p>If you reply from your main Gmail currently, the recipient will see that address when you reply instead of the alias. That may not be a big deal depending on the use case, but we can certainly set it up so that sent mail acts like it's coming from the custom domain as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.08.37-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You'll need to go to your <a target="_blank" href="https://myaccount.google.com/security"><strong>Google Account Security</strong></a> and click <strong>App passwords</strong>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.12.46-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Select <strong>Mail</strong> for the app dropdown and <strong>Other</strong> for the device dropdown.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.14.18-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Enter the name of your domain and click <strong>Generate</strong>. It will give you a 16 digit password. Save this for use over in Gmail...</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.15.34-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In Gmail, go to settings -&gt; <strong>Accounts and Import</strong> and click <strong>Add another email address</strong>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.17.49-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This will pop up a new small window where you will enter in the details of the alias. Enter the <strong>name</strong> you want recipients to view and the <strong>address</strong> of the alias. Make sure the "<strong>Treat as an alias</strong>" box is checked.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.21.46-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the next screen, you'll need to change the <strong>SMTP server</strong> to smtp.gmail.com, the <strong>username</strong> to your Gmail username, and then paste in the <strong>16 digit password</strong> you generated from Google Security in the steps above.</p>
<p>The <strong>port</strong> should be 587, and the <strong>TLS</strong> radial button should be checked.</p>
<p>Click <strong>Add Account</strong>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.23.33-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This will prompt a verification code being sent to the email alias...which should in turn go to the Gmail account. Enter that in, and you'll now be good to go!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.27.09-PM-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Back in our email thread in Gmail, you'll have the dropdown option when composing new messages to select which account you would like it to send from.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.29.10-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now we can see from our full thread that our email forwards to and sends from our Gmail account using the email alias and display name we selected.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Screen-Shot-2022-10-12-at-3.35.15-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-thanks-for-reading">Thanks for reading!</h2>
<p>This was enlightening for me, and I hope it's helpful for you too.</p>
<p>Come say hey on Twitter: <a target="_blank" href="https://twitter.com/EamonnCottrell">https://twitter.com/EamonnCottrell</a></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/goodtogo.gif" alt="Image" width="600" height="400" loading="lazy"></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Batch Delete Emails in Gmail – Delete Multiple Email Messages ]]>
                </title>
                <description>
                    <![CDATA[ I hear some of my co-workers talk about getting to inbox zero. So I started thinking of a way to clear out my over over 4000 unread messages. And after days of searching around, I found a way. I even went on to delete 20,000 email messages from the t... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-batch-delete-emails-in-gmail-delete-multiple-email-messages/</link>
                <guid isPermaLink="false">66adf0f9f452caf50fb1fdee</guid>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gmail ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Tue, 19 Jul 2022 16:03:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/batchDeleteGmailMessages.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I hear some of my co-workers talk about getting to inbox zero. So I started thinking of a way to clear out my over over 4000 unread messages. And after days of searching around, I found a way.</p>
<p>I even went on to delete 20,000 email messages from the trash – and saved just over 1 gigabyte of disk space in the process.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/inbox0.png" alt="inbox0" width="600" height="400" loading="lazy"></p>
<p>Today, I want to show you how you can batch delete emails in the Gmail app – no matter the thousands of messages you have there.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-delete-all-unread-emails-in-gmail">How to Delete All Unread Emails in Gmail</a></li>
<li><a class="post-section-overview" href="#heading-how-to-clear-gmail-trash">How to Clear Gmail Trash</a></li>
<li><a class="post-section-overview" href="#heading-how-do-i-delete-emails-from-the-promotion-list">How do I Delete Emails from the Promotion List?</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-how-to-delete-all-unread-emails-in-gmail">How to Delete All Unread Emails in Gmail</h2>
<p><strong>Step 1</strong>: Log in to your Gmail account </p>
<p><strong>Step 2</strong>: In the search bar, type <code>in:unread</code> and hit <code>ENTER</code>. This will show you 50 unread messages.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss4-2.png" alt="ss4-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3</strong>: Select the checkbox in the top-right corner to select 50 of the unread emails.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss5-2.png" alt="ss5-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4</strong>: Click the message that says “select all conversations that match this search”. This will select all your unread messages.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss6-2.png" alt="ss6-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 5</strong>: Click the delete icon at the top.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss7-3.png" alt="ss7-3" width="600" height="400" loading="lazy"></p>
<p><strong>Step 6</strong>: A pop up will appear asking if you want to bulk delete the messages. Click “Ok”.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss8-2.png" alt="ss8-2" width="600" height="400" loading="lazy"> </p>
<p>That’s how you can bulk delete messages in Gmail.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss9-2.png" alt="ss9-2" width="600" height="400" loading="lazy"> </p>
<h2 id="heading-how-to-clear-gmail-trash">How to Clear Gmail Trash</h2>
<p><strong>Step 1</strong>: To clear the messages from your Trash, click “More” on the left and select Trash.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss10-2.png" alt="ss10-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: Click the checkbox in the top-right corner to select the messages in the trash.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss11-2.png" alt="ss11-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 3</strong>: Select all the messages in Trash and click “Delete forever”.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss12-2.png" alt="ss12-2" width="600" height="400" loading="lazy"></p>
<p><strong>Step 4</strong>: Click Ok to confirm that you want to delete all the messages. 
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss13-1.png" alt="ss13-1" width="600" height="400" loading="lazy"></p>
<p>You should get a message that x number of emails have been deleted forever. If you don’t get the message even if everything appears clear, refresh the page.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss14-1.png" alt="ss14-1" width="600" height="400" loading="lazy"></p>
<p>You can also delete messages in the promotion or social tab.</p>
<h2 id="heading-how-do-i-delete-emails-from-the-promotion-list">How do I Delete Emails from the Promotion List?</h2>
<p>To delete email messages in the promotion tab, follow the steps below.</p>
<p><strong>Step 1</strong>: Click More on the right and select Categories.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss15.png" alt="ss15" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: Click Promotions.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss16.png" alt="ss16" width="600" height="400" loading="lazy"></p>
<p><strong>Step 2</strong>: Click the checkbox on the top-right corner to select all 50 messages in the promotion tab.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss17.png" alt="ss17" width="600" height="400" loading="lazy"> </p>
<p><strong>Step 3</strong>: Click select all conversations in the promotion tab.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss18.png" alt="ss18" width="600" height="400" loading="lazy"> </p>
<p><strong>Step 4</strong>: Click the delete icon at the top.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss19.png" alt="ss19" width="600" height="400" loading="lazy"> </p>
<p><strong>Step 5</strong>: Confirm you want to delete all messages in the promotion tab.<br><img src="https://www.freecodecamp.org/news/content/images/2022/07/ss20.png" alt="ss20" width="600" height="400" loading="lazy"> </p>
<p>You should get a message that the conversations have been moved to trash.
<img src="https://www.freecodecamp.org/news/content/images/2022/07/ss21.png" alt="ss21" width="600" height="400" loading="lazy"> </p>
<p>If you want to delete messages in other tabs such as social, or forum, repeat the process you went through to delete all messages in the promotion tab.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope this article helps you delete the unwanted messages in your Gmail app so you can also get to inbox zero.</p>
<p>There are other ways you can use search operators to query the Gmail app and reveal messages received over the years so you can do what you want with them. You can find those <a target="_blank" href="https://support.google.com/mail/answer/7190?hl=en">search operators</a> in Google Support.</p>
<p>Thanks for reading.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Send Large Video Files – Share a Big File with Email ]]>
                </title>
                <description>
                    <![CDATA[ Sending large files through email can be quite challenging. This is because each email client has a size limit for file sharing. Gmail and Yahoo limit file size to 25MB, while outlook and iCloud limit files to 20MB. So, if you decide to send, for exa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-send-large-video-files-share-a-big-file-with-email/</link>
                <guid isPermaLink="false">66adf1476f5e63db3fc4361e</guid>
                
                    <category>
                        <![CDATA[ dropbox ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ File sharing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Docs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ videos ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Wed, 27 Apr 2022 19:51:49 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/technology-2125547_1280.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Sending large files through email can be quite challenging. This is because each email client has a size limit for file sharing.</p>
<p>Gmail and Yahoo limit file size to 25MB, while outlook and iCloud limit files to 20MB.</p>
<p>So, if you decide to send, for example, a video file larger than 25MB, you might get an error that the message was rejected by the server because it’s too large.</p>
<p>Some email clients won’t show an error, but instead, suggest how you should send the large video file. </p>
<p>For example, Gmail will suggest that you upload the video to Google Drive: 
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss1-7.png" alt="ss1-7" width="600" height="400" loading="lazy"></p>
<p>And Outlook will suggest that you upload the video to Microsoft OneDrive:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss2-8.png" alt="ss2-8" width="600" height="400" loading="lazy"></p>
<p>How then do you send a large video file through email? That’s what I’m going to show you in this article.</p>
<h2 id="heading-how-to-send-large-video-files-through-email-using-google-drive">How to Send Large Video Files through Email Using Google Drive</h2>
<p>Google Drive is a cloud-based storage service provided by Google for sharing files.</p>
<p>As already shown in this article, Gmail prompts you to upload a video file larger than 25MB to Google Drive and then convert the video to an accessible link.</p>
<p>If you are using another email client like Outlook, or Yahoo, you can still send the large video using Google Drive.</p>
<p>Upload the video to your Google Drive and click the “Get link” button:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss3-7.png" alt="ss3-7" width="600" height="400" loading="lazy"></p>
<p>Change the access from restricted to “Anyone with the link”:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss4-5.png" alt="ss4-5" width="600" height="400" loading="lazy"></p>
<p>Click “Copy link”, and then “Done”:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss5-5.png" alt="ss5-5" width="600" height="400" loading="lazy"></p>
<p>Click “Compose” and paste the link to your email editor. Provide every other necessary detail and click the “Send” button:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss6-5.png" alt="ss6-5" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-send-large-video-files-through-email-using-dropbox">How to Send Large Video Files through Email Using Dropbox</h2>
<p>Dropbox is another cloud-based storage service that lets you back up and sync files on multiple devices. You can upload up to 50GB file size to your Dropbox account if you have one.</p>
<p>To send large video files through email by using Dropbox, upload the video to your Dropbox account and copy the link:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss7-4.png" alt="ss7-4" width="600" height="400" loading="lazy"></p>
<p>Compose your email and paste the link in to send the large video file:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss8-4.png" alt="ss8-4" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-send-large-video-files-through-email-using-video-sharing-services">How to Send Large Video Files through Email Using Video Sharing Services</h2>
<p>You can send large video files through email by using video-sharing services like YouTube and Vimeo.</p>
<p>And yes, you can upload videos to YouTube without having a YouTube channel. As long as you have a Gmail account, you have access to Google services, including YouTube. So if you have a Google account, technically you can have a YouTube channel.</p>
<p>To upload videos to YouTube, click the Create button on the top-right corner and select “Upload video”:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss9-4.png" alt="ss9-4" width="600" height="400" loading="lazy"></p>
<p>Click on “SELECT FILES” to choose the file on your device:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss10-4.png" alt="ss10-4" width="600" height="400" loading="lazy"></p>
<p>Give the video a name and description, copy the link, and click “Next”:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss11-3.png" alt="ss11-3" width="600" height="400" loading="lazy"></p>
<p>Follow other prompts and choose whether you want to make the video public or private, then click “Save”:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss12-2.png" alt="ss12-2" width="600" height="400" loading="lazy"></p>
<p>Head over to your email client composer and paste in the link so you can send the large video file:
<img src="https://www.freecodecamp.org/news/content/images/2022/04/ss13-1.png" alt="ss13-1" width="600" height="400" loading="lazy"></p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>You can’t send a large video file directly through email clients, but you can take advantage of the methods discussed in this article to send large video files.</p>
<p>Another way you can send a large video file through email is to compress the video through your native compressor or third-party file compressors. As long as the file is less than 20-25MB, you can send it through email.</p>
<p>But if you compress the video and it is still not less than 20-25MB, then you should use any of the methods pointed out in this article.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Mailto Link – How to Make an HTML Email Link [Example Code] ]]>
                </title>
                <description>
                    <![CDATA[ A mailto link allows users to send emails straight from a website using the user's default email client. But how do you create a mailto link in HTML? In this article, I will walk you through how to create a mailto link in HTML using example code. Bas... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/mailto-link-how-to-make-an-html-email-link-example-code/</link>
                <guid isPermaLink="false">66b8da101fe28dd01992d67e</guid>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jessica Wilkins ]]>
                </dc:creator>
                <pubDate>Tue, 16 Nov 2021 22:58:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/11/brett-jordan-LPZy4da9aRo-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>A mailto link allows users to send emails straight from a website using the user's default email client. But how do you create a mailto link in HTML?</p>
<p>In this article, I will walk you through how to create a mailto link in HTML using example code.</p>
<h2 id="heading-basic-mailto-link-syntax">Basic <code>mailto</code> link Syntax</h2>
<p>Here is the basic syntax for the mailto link:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"mailto:johndoe@fakeemail.com"</span>&gt;</span>Example mailto link<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>In the browser, the user can click on the link and it will open up their default email client. </p>
<p>In this example, when I click on the link it opens up my Mail app and the email address is already populated in the <code>to</code> field. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-14-at-12.07.32-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-14-at-12.05.15-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Using this method, I would be able to send a quick email and return to the website. </p>
<h2 id="heading-how-to-add-multiple-email-addresses-to-the-mailto-link">How to add multiple email addresses to the mailto link</h2>
<p>You can add multiple email addresses to the mailto link using this syntax: </p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"mailto:johndoe@fakeemail.com, janedoe@fakeemail.com"</span>&gt;</span>
    Multiple email addresses
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>It is important to separate the multiple email addresses using commas. </p>
<p>When I click on the link in the browser, it will open up the <code>Mail</code> app and populate the email addresses in the <code>to</code> field.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-14-at-12.18.17-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-14-at-12.18.42-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-add-a-subject-line-to-the-mailto-link">How to add a subject line to the mailto link</h2>
<p>Here is some example code that shows you how to add a subject line to the mailto link.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"mailto:johndoe@fakeemail.com, janedoe@fakeemail.com?subject=this is how to use the mailto link"</span>&gt;</span>
    Using the subject parameter
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>After the email addresses, you need to add an <code>?</code> to separate the emails and the <code>subject</code> parameter. If you omit that <code>?</code>, then the subject link will not work.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-14-at-12.32.41-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-14-at-12.34.08-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-add-cc-and-bcc-to-the-mailto-link">How to add CC and BCC to the mailto link</h2>
<p>This is an example that shows you how to add CC (carbon copy) and BCC (blind carbon copy) recipients to the mailto link.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">a</span>
    <span class="hljs-attr">href</span>=<span class="hljs-string">"mailto:johndoe@fakeemail.com, janedoe@fakeemail.com?cc=jackdoe@fakeemail.com &amp;bcc=jennydoe@fakeemail.com &amp;subject=this is how to use the mailto link"</span>&gt;</span>
    Using the CC and BCC parameters
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>After the email addresses, you need to add a <code>?</code> to separate the emails and the <code>CC</code> parameter. You also need to add an <code>&amp;</code> before the <code>BCC</code> and <code>subject</code> parameters. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-14-at-12.44.29-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-14-at-12.45.03-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-add-the-body-parameter-to-the-mailto-link">How to add the body parameter to the mailto link</h2>
<p>This is an example that shows you how to use the body parameter with the mailto link. This lets you add text to the body of your email.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">a</span>
   <span class="hljs-attr">href</span>=<span class="hljs-string">"mailto:johndoe@fakeemail.com, janedoe@fakeemail.com?cc=jackdoe@fakeemail.com &amp;bcc=jennydoe@fakeemail.com &amp;subject=this is how to use the mailto link &amp;body=this is an article on how to use the mailto link"</span>&gt;</span>
    Using the body parameter
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>You need to add an <code>&amp;</code> before the <code>body</code> parameter.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-14-at-12.57.00-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/Screen-Shot-2021-11-14-at-12.57.17-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-are-there-downsides-to-using-mailto-links">Are there downsides to using mailto links?</h2>
<p>One of the downsides to using a mailto link is that it does often come across as spam by users. Unfortunately, a lot of spammers will use this option to send emails to users. So just keep that in mind when you're using it.</p>
<h2 id="heading-advantages-of-using-mailto-links">Advantages of using mailto links</h2>
<p>A good reason to use a mailto link is if you are sending emails to a group of people that you know. If that entire group is using a default email client, then using a mailto link would be a good option over a contact form. </p>
<p>## </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Contact Form with SendGrid and Next.js ]]>
                </title>
                <description>
                    <![CDATA[ By Manu Arora Contact forms are useful on websites if you want your users to be able to interact with you over email. And there are lots of ways to build them. Traditionally you'd have either used PHP for sending emails over the server or some third ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-working-contact-form-with-sendgrid-and-next-js/</link>
                <guid isPermaLink="false">66d46017d14641365a050915</guid>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Next.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ sendgrid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 30 Aug 2021 15:24:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/08/Blue-and-White-Modern-Corporate-Travel-YouTube-Thumbnail--5-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Manu Arora</p>
<p>Contact forms are useful on websites if you want your users to be able to interact with you over email. And there are lots of ways to build them.</p>
<p>Traditionally you'd have either used PHP for sending emails over the server or some third party service that would take care of the email logic. </p>
<p>But in this article, we are going to talk about how to send emails from your Next.js application with the SendGrid API.</p>
<p>We are going to create a simple page – a contact form built with React – that has input fields which we'll validate before sending. We'll connect the form to the SendGrid API which will take care of sending the emails to you. Then, at the end of the day, all you have to do is check your email to find those queries.</p>
<p>However, if you don't have a Next.js project yet, you can easily create one and integrate it with Vercel by following the below mentioned steps:</p>
<ol>
<li>Create an account on <a target="_blank" href="https://vercel.com">Vercel</a> and click on <code>New Project</code></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-30-at-9.41.17-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="2">
<li>Choose the template as <code>Next.js</code>:</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-30-at-9.37.17-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="3">
<li>Name your repository anything you would like and click on create project. (Choose GitHub, GitLab or BitBucket for your remote code versioning)</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-30-at-9.37.34-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Following the above three points, you'll have a repository on your versioning account.</p>
<h2 id="heading-the-tech-stack-well-use">The Tech Stack We'll Use</h2>
<ul>
<li><a target="_blank" href="https://nextjs.org">Next.js</a> for creating a contact form landing page</li>
<li><a target="_blank" href="https://tailwindcss.com">TailwindCSS</a> for styling the components</li>
<li><a target="_blank" href="https://sendgrid.com">SendGrid</a> for sending emails using their APIs</li>
<li><a target="_blank" href="https://vercel.com">Vercel</a> for hosting our application and CI/CD</li>
</ul>
<p>We are going to use Nextjs' API routes to handle form events. The API modules provide a flexible way to handle backend logic in our Next.js application. </p>
<p>Whatever code we write in the API folder will get deployed as a Serverless function onto Vercel for hosting. You can read more about Next.js API routes <a target="_blank" href="https://nextjs.org/docs/api-routes/introduction">here</a></p>
<p>If you already have a Next.js project where you want to set up a working contact form, that's great. In that case, it'll be easy for you to create pages and get started right away. </p>
<p>But if you don't have a project set up yet, that's ok – go to Vercel and create a Next.js starter project and clone the repository.</p>
<h2 id="heading-application-flow">Application Flow</h2>
<p>Let's take a look at the application flow – or how the sending of emails actually works:</p>
<ul>
<li>The end-user fills in the mandotary 4 fields and clicks on submit.</li>
<li>On submit, the <code>handleSubmit</code> function gets triggered.</li>
<li><code>handleSubmit</code> validates the form for input fields and checks if they are not empty.</li>
<li>If the form fields are not empty, an API call is made to <code>api/sendgrid</code> where the logic of sending emails lives.</li>
<li>In <code>api/sendgrid</code>, the <code>@sendgrid/mail</code> module initializes a <code>send</code> function that takes it your application's API keys and sends the email with the required fields.</li>
<li>If email is successfully delivered, a <code>200</code> response is sent to the client, else a <code>400</code> response is sent to the client.</li>
<li>Responses are handled at the frontend and the appropriate messages are displayed. </li>
</ul>
<h2 id="heading-how-to-set-up-tailwindcss">How to Set Up TailwindCSS</h2>
<p>Setting up TailwindCSS is quite easy, and you can do it in two simple ways.</p>
<ol>
<li>Install TailwindCSS as a dependency in your project:</li>
</ol>
<pre><code class="lang-bash">npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
</code></pre>
<ol start="2">
<li>Initialize a TailwindCSS configuration file for your project. This will create a <code>tailwind.config.js</code> file in the root directory:</li>
</ol>
<pre><code class="lang-bash">npx tailwindcss init
</code></pre>
<p>Then you'll need to edit the configuration file, include <code>purge</code> paths, and enable <code>jit</code> mode:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
   <span class="hljs-attr">purge</span>: [],
   <span class="hljs-attr">mode</span>: <span class="hljs-string">'jit'</span>,
   <span class="hljs-attr">purge</span>: [<span class="hljs-string">'./pages/**/*.{js,ts,jsx,tsx}'</span>, <span class="hljs-string">'./components/**/*.{js,ts,jsx,tsx}'</span>],
    <span class="hljs-attr">darkMode</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">// or 'media' or 'class'</span>
    <span class="hljs-attr">theme</span>: {
      <span class="hljs-attr">extend</span>: {},
    },
    <span class="hljs-attr">variants</span>: {
      <span class="hljs-attr">extend</span>: {},
    },
    <span class="hljs-attr">plugins</span>: [],
  }
</code></pre>
<p>You use <code>purge</code> to remove unwanted styles from your project at build time. It is helpful if you want to reduce the CSS bundle size. </p>
<p><code>jit</code> is the new TailwindCSS mode where you can specify dynamic classnames in the code itself. </p>
<p>For example, if you want to have your text size be <code>10px</code> (which is not already there in the TailwindCSS modules), you can write <code>text-[10px]</code> in your class names and it will reflect automatically. No need to write custom style attributes anymore. 💯</p>
<p>Next, import Tailwind styles in your root <code>_app.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-comment">// pages/_app.js</span>
 <span class="hljs-keyword">import</span> <span class="hljs-string">'../styles/globals.css'</span>
 <span class="hljs-keyword">import</span> <span class="hljs-string">'tailwindcss/tailwind.css'</span>

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyApp</span>(<span class="hljs-params">{ Component, pageProps }</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Component</span> {<span class="hljs-attr">...pageProps</span>} /&gt;</span></span>
  }

  <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> MyApp
</code></pre>
<p>Then include Tailwind's core CSS in your root level stylesheet like this:</p>
<pre><code class="lang-js"><span class="hljs-comment">/* ./styles/globals.css */</span>
@tailwind base;
@tailwind components;
@tailwind utilities;
</code></pre>
<p>With this, you have successfully setup TailwindCSS for your project.</p>
<h2 id="heading-the-markup-and-styling-for-the-contact-page">The Markup and Styling for the Contact Page</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-12.08.53-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We'll build the webpage completely with Tailwind. I got the page itself directly from the <a target="_blank" href="https://tailwindmasterkit.com">Tailwind Master Kit</a> which is a components and templates library for Tailwind web projects.</p>
<p>Let's go through the HTML of the page (essentially the contact form) to understand how everything's implemented:</p>
<pre><code class="lang-js">&lt;form <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"rounded-lg shadow-xl flex flex-col px-8 py-8 bg-white dark:bg-blue-500"</span>&gt;
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-2xl font-bold dark:text-gray-50"</span>&gt;</span>Send a message<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>

      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"fullname"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-500 font-light mt-8 dark:text-gray-50"</span>&gt;</span>Full name<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-red-500 dark:text-gray-50"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span></span>
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"fullname"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"</span> /&gt;</span></span>

      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-500 font-light mt-4 dark:text-gray-50"</span>&gt;</span>E-mail<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-red-500"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span></span>
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"</span> /&gt;</span></span>

      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"subject"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-500 font-light mt-4 dark:text-gray-50"</span>&gt;</span>Subject<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-red-500"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span></span>
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"subject"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"</span> /&gt;</span></span>

      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-500 font-light mt-4 dark:text-gray-50"</span>&gt;</span>Message<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-red-500"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span></span>
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span></span>
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex flex-row items-center justify-start"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"px-10 mt-8 py-2 bg-[#130F49] text-gray-50 font-light rounded-md text-lg flex flex-row items-center"</span>&gt;</span>
          Send
          <span class="hljs-tag">&lt;<span class="hljs-name">svg</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"24"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"24"</span> <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 24 24"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-cyan-500 ml-2"</span> <span class="hljs-attr">fill</span>=<span class="hljs-string">"currentColor"</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"M9.00967 5.12761H11.0097C12.1142 5.12761 13.468 5.89682 14.0335 6.8457L16.5089 11H21.0097C21.562 11 22.0097 11.4477 22.0097 12C22.0097 12.5523 21.562 13 21.0097 13H16.4138L13.9383 17.1543C13.3729 18.1032 12.0191 18.8724 10.9145 18.8724H8.91454L12.4138 13H5.42485L3.99036 15.4529H1.99036L4.00967 12L4.00967 11.967L2.00967 8.54712H4.00967L5.44417 11H12.5089L9.00967 5.12761Z"</span> <span class="hljs-attr">fill</span>=<span class="hljs-string">"currentColor"</span> /&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    &lt;/form&gt;
</code></pre>
<p>The form has 4 fields:</p>
<ul>
<li>Full Name</li>
<li>Email</li>
<li>Subject</li>
<li>Message</li>
</ul>
<p>All the fields are mandatory – and we'll validate them too later on. You'll expect your user to provide you with all their details while sending the email.</p>
<p>To capture the fields, we are going to use React's <a target="_blank" href="https://reactjs.org/docs/hooks-state.html">useState()</a> hook to ensure that our data is persisted in the application.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ContactUs</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [fullname, setFullname] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [email, setEmail] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [subject, setSubject] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [message, setMessage] = useState(<span class="hljs-string">""</span>);

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>
          <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>
          <span class="hljs-attr">className</span>=<span class="hljs-string">"rounded-lg shadow-xl flex flex-col px-8 py-8 bg-white dark:bg-blue-500"</span>
        &gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-2xl font-bold dark:text-gray-50"</span>&gt;</span>
            Send a message
          <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
            <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"fullname"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"text-gray-500 font-light mt-8 dark:text-gray-50"</span>
          &gt;</span>
            Full name<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-red-500 dark:text-gray-50"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{fullname}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> {
              setFullname(e.target.value);
            }}
            name="fullname"
            className="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"
          /&gt;


          <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
            <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"email"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"text-gray-500 font-light mt-4 dark:text-gray-50"</span>
          &gt;</span>
            E-mail<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-red-500"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span>
            <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{email}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> {
              setEmail(e.target.value);
            }}
            className="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"
          /&gt;


          <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
            <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"subject"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"text-gray-500 font-light mt-4 dark:text-gray-50"</span>
          &gt;</span>
            Subject<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-red-500"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
            <span class="hljs-attr">name</span>=<span class="hljs-string">"subject"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{subject}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> {
              setSubject(e.target.value);
            }}
            className="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"
          /&gt;

          <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
            <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"message"</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"text-gray-500 font-light mt-4 dark:text-gray-50"</span>
          &gt;</span>
            Message<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-red-500"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span>
            <span class="hljs-attr">name</span>=<span class="hljs-string">"message"</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{message}</span>
            <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> {
              setMessage(e.target.value);
            }}
            className="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"
          &gt;<span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-row items-center justify-start"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
              <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>
              <span class="hljs-attr">className</span>=<span class="hljs-string">"px-10 mt-8 py-2 bg-[#130F49] text-gray-50 font-light rounded-md text-lg flex flex-row items-center"</span>
            &gt;</span>
              Submit
              <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
                <span class="hljs-attr">width</span>=<span class="hljs-string">"24"</span>
                <span class="hljs-attr">height</span>=<span class="hljs-string">"24"</span>
                <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 24 24"</span>
                <span class="hljs-attr">className</span>=<span class="hljs-string">"text-cyan-500 ml-2"</span>
                <span class="hljs-attr">fill</span>=<span class="hljs-string">"currentColor"</span>
                <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
              &gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">path</span>
                  <span class="hljs-attr">d</span>=<span class="hljs-string">"M9.00967 5.12761H11.0097C12.1142 5.12761 13.468 5.89682 14.0335 6.8457L16.5089 11H21.0097C21.562 11 22.0097 11.4477 22.0097 12C22.0097 12.5523 21.562 13 21.0097 13H16.4138L13.9383 17.1543C13.3729 18.1032 12.0191 18.8724 10.9145 18.8724H8.91454L12.4138 13H5.42485L3.99036 15.4529H1.99036L4.00967 12L4.00967 11.967L2.00967 8.54712H4.00967L5.44417 11H12.5089L9.00967 5.12761Z"</span>
                  <span class="hljs-attr">fill</span>=<span class="hljs-string">"currentColor"</span>
                /&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
    )
}
</code></pre>
<p>Notice the form attribute <code>onSubmit={handleSubmit}</code>. This is the function where we are going to actually send the email through SendGrid. But before that, let's create a SendGrid Project and retrieve the <code>API keys</code>.</p>
<h2 id="heading-how-to-set-up-a-sendgrid-project">How to Set Up a SendGrid Project</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-1.10.59-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>First, you just need to head over to SendGrid's <a target="_blank" href="https://signup.sendgrid.com/">homepage</a> and signup for an account (if you don't have one already).</p>
<p>After successfully creating an account, register for an API Key. You can do it <a target="_blank" href="https://app.sendgrid.com/guide/integrate/langs/nodejs">here</a>.</p>
<p>Sendgrid requires you to create a Sender Identity to protect against spam and malicious mails. To do so, go to the <a target="_blank" href="https://app.sendgrid.com/settings/sender_auth">Sendgrid Identity page</a> and click on <code>Create New Sender</code> to create a sender identity.</p>
<p>You'll be rqeuired to fill out a detailed form. Just complete the form and hit submit. Finally, just verify your email address and you're done.</p>
<p>Once you've retrieved the <code>API keys</code>, create a <code>.env.local</code> file in your local environment and paste the following code:</p>
<pre><code class="lang-js">SENDGRID_API_KEY= YOUR_API_KEY_HERE
</code></pre>
<p>Replace <code>YOUR_API_KEY_HERE</code> with the API key you just retrieved.</p>
<h2 id="heading-how-to-create-a-serverless-api-route">How to Create a Serverless API Route</h2>
<p>Creating a serverless API route is quite easy with Next.js.</p>
<p>Go to <code>/pages/api</code> and inside the <code>api</code> folder create a file called <code>sendgrid.js</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> sendgrid <span class="hljs-keyword">from</span> <span class="hljs-string">"@sendgrid/mail"</span>;

sendgrid.setApiKey(process.env.SENDGRID_API_KEY);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendEmail</span>(<span class="hljs-params">req, res</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// console.log("REQ.BODY", req.body);</span>
    <span class="hljs-keyword">await</span> sendgrid.send({
      <span class="hljs-attr">to</span>: <span class="hljs-string">"mannuarora7000@gmail.com"</span>, <span class="hljs-comment">// Your email where you'll receive emails</span>
      <span class="hljs-attr">from</span>: <span class="hljs-string">"manuarorawork@gmail.com"</span>, <span class="hljs-comment">// your website email address here</span>
      <span class="hljs-attr">subject</span>: <span class="hljs-string">`<span class="hljs-subst">${req.body.subject}</span>`</span>,
      <span class="hljs-attr">html</span>: <span class="hljs-string">`&lt;div&gt;You've got a mail&lt;/div&gt;`</span>,
    });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-comment">// console.log(error);</span>
    <span class="hljs-keyword">return</span> res.status(error.statusCode || <span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: error.message });
  }

  <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">""</span> });
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> sendEmail;
</code></pre>
<p>SendGrid requires us to initialize a <code>sendgrid</code> object with the API keys with the <code>setApiKey()</code> method. Initialize the object with your API key and you can send emails with the <code>send()</code> method.</p>
<p>There are essentially four fields that are required in the <code>send()</code> method's body:</p>
<ul>
<li><code>to</code> – The email address where you want your email to get delivered</li>
<li><code>from</code> – Your SendGrid Email that you used for Sender Identity Verification. Your emails will be sent from this email.</li>
<li><code>subject</code> – The subject line of the email</li>
<li><code>message</code> – the message body of the email</li>
</ul>
<p>We are going to construct these four parameters ourselves so that we can understand our emails better. Here is the updated code from the same snippet above:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> sendgrid <span class="hljs-keyword">from</span> <span class="hljs-string">"@sendgrid/mail"</span>;

sendgrid.setApiKey(process.env.SENDGRID_API_KEY);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendEmail</span>(<span class="hljs-params">req, res</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">await</span> sendgrid.send({
      <span class="hljs-attr">to</span>: <span class="hljs-string">"youremail@gmail.com"</span>, <span class="hljs-comment">// Your email where you'll receive emails</span>
      <span class="hljs-attr">from</span>: <span class="hljs-string">"youremail@gmail.com"</span>, <span class="hljs-comment">// your website email address here</span>
      <span class="hljs-attr">subject</span>: <span class="hljs-string">`[Lead from website] : <span class="hljs-subst">${req.body.subject}</span>`</span>,
      <span class="hljs-attr">html</span>: <span class="hljs-string">`&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
      &lt;html lang="en"&gt;
      &lt;head&gt;
        &lt;meta charset="utf-8"&gt;

        &lt;title&gt;The HTML5 Herald&lt;/title&gt;
        &lt;meta name="description" content="The HTML5 Herald"&gt;
        &lt;meta name="author" content="SitePoint"&gt;
      &lt;meta http-equiv="Content-Type" content="text/html charset=UTF-8" /&gt;

        &lt;link rel="stylesheet" href="css/styles.css?v=1.0"&gt;

      &lt;/head&gt;

      &lt;body&gt;
        &lt;div class="img-container" style="display: flex;justify-content: center;align-items: center;border-radius: 5px;overflow: hidden; font-family: 'helvetica', 'ui-sans';"&gt;              
              &lt;/div&gt;
              &lt;div class="container" style="margin-left: 20px;margin-right: 20px;"&gt;
              &lt;h3&gt;You've got a new mail from <span class="hljs-subst">${req.body.fullname}</span>, their email is: ✉️<span class="hljs-subst">${req.body.email}</span> &lt;/h3&gt;
              &lt;div style="font-size: 16px;"&gt;
              &lt;p&gt;Message:&lt;/p&gt;
              &lt;p&gt;<span class="hljs-subst">${req.body.message}</span>&lt;/p&gt;
              &lt;br&gt;
              &lt;/div&gt;
              &lt;img src="https://manuarora.in/logo.png" class="logo-image" style="height: 50px;width: 50px;border-radius: 5px;overflow: hidden;"&gt;
              &lt;p class="footer" style="font-size: 16px;padding-bottom: 20px;border-bottom: 1px solid #D1D5DB;"&gt;Regards&lt;br&gt;Manu Arora&lt;br&gt;Software Developer&lt;br&gt;+91 9587738861&lt;/p&gt;
              &lt;div class="footer-links" style="display: flex;justify-content: center;align-items: center;"&gt;
                &lt;a href="https://manuarora.in/" style="text-decoration: none;margin: 8px;color: #9CA3AF;"&gt;Website&lt;/a&gt;
                &lt;a href="https://manuarora.in/blog/" style="text-decoration: none;margin: 8px;color: #9CA3AF;"&gt;Blog&lt;/a&gt;
                &lt;a href="https://github.com/manuarora700/" style="text-decoration: none;margin: 8px;color: #9CA3AF;"&gt;GitHub&lt;/a&gt;
                &lt;a href="https://instagram.com/maninthere/" style="text-decoration: none;margin: 8px;color: #9CA3AF;"&gt;Instagram&lt;/a&gt;
                &lt;a href="https://linkedin.com/in/manuarora28/" style="text-decoration: none;margin: 8px;color: #9CA3AF;"&gt;LinkedIn&lt;/a&gt;
                &lt;a href="https://twitter.com/mannupaaji/" style="text-decoration: none;margin: 8px;color: #9CA3AF;"&gt;Twitter&lt;/a&gt;

              &lt;/div&gt;
              &lt;/div&gt;
      &lt;/body&gt;
      &lt;/html&gt;`</span>,
    });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-comment">// console.log(error);</span>
    <span class="hljs-keyword">return</span> res.status(error.statusCode || <span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: error.message });
  }

  <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">""</span> });
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> sendEmail;
</code></pre>
<p>If you want to send <code>html</code> in the email body, you will have to use inline styles which are there in the example as well.</p>
<p>Here, we are essentially using SendGrid's <code>send()</code> method provided by the SendGrid API to send emails. We use the <code>send()</code> method with the <code>sendgrid</code> object which we initialized with the API key. This makes sure that our emails are secure and delivered only by our permission.</p>
<p>Also, we've wrapped the code in a <code>try - catch</code> block. This ensures that our application can handle exceptions and errors correctly. If by any change the email sending fails, then the code immediately falls into the <code>catch()</code> block and we return an <code>error</code> object. This signifies that there has been some problem on the back-end.</p>
<p>Looking at the API response from the back-end, the front-end responds accordingly and the UI changes.</p>
<p>The styling goes into the <code>html</code> attribute inside of the <code>send()</code> method body. How you want to style your email completely depends on you. Here, I've included a simple template with a footer to my Twitter, Instagram, GitHub and website, along with the original message body that the end-user sends.</p>
<p>Now our API route is setup, so let's move on to the front end and learn how to handle the response correctly.</p>
<h2 id="heading-how-to-call-the-api-and-handle-responses">How to Call the API and Handle Responses</h2>
<p>Since our API route is setup, we are now going to call our serverless API and fetch the response.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ContactUs</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [fullname, setFullname] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [email, setEmail] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [subject, setSubject] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [message, setMessage] = useState(<span class="hljs-string">""</span>);



  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-keyword">async</span> (e) =&gt; {
    e.preventDefault();

    <span class="hljs-keyword">let</span> isValidForm = handleValidation();


      <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/sendgrid"</span>, {
        <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
          <span class="hljs-attr">email</span>: email,
          <span class="hljs-attr">fullname</span>: fullname,
          <span class="hljs-attr">subject</span>: subject,
          <span class="hljs-attr">message</span>: message,
        }),
        <span class="hljs-attr">headers</span>: {
          <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
        },
        <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
      });

      <span class="hljs-keyword">const</span> { error } = <span class="hljs-keyword">await</span> res.json();
      <span class="hljs-keyword">if</span> (error) {
        <span class="hljs-built_in">console</span>.log(error);
        <span class="hljs-keyword">return</span>;
      }
    <span class="hljs-built_in">console</span>.log(fullname, email, subject, message);
  };
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"rounded-lg shadow-xl flex flex-col px-8 py-8 bg-white dark:bg-blue-500"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-2xl font-bold dark:text-gray-50"</span>&gt;</span>Send a message<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"fullname"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-500 font-light mt-8 dark:text-gray-50"</span>&gt;</span>Full name<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-red-500 dark:text-gray-50"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"fullname"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"</span> /&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-500 font-light mt-4 dark:text-gray-50"</span>&gt;</span>E-mail<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-red-500"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"</span> /&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"subject"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-500 font-light mt-4 dark:text-gray-50"</span>&gt;</span>Subject<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-red-500"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"subject"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"</span> /&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-gray-500 font-light mt-4 dark:text-gray-50"</span>&gt;</span>Message<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-red-500"</span>&gt;</span>*<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex flex-row items-center justify-start"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"px-10 mt-8 py-2 bg-[#130F49] text-gray-50 font-light rounded-md text-lg flex flex-row items-center"</span>&gt;</span>
          Send
          <span class="hljs-tag">&lt;<span class="hljs-name">svg</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"24"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"24"</span> <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 24 24"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-cyan-500 ml-2"</span> <span class="hljs-attr">fill</span>=<span class="hljs-string">"currentColor"</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"M9.00967 5.12761H11.0097C12.1142 5.12761 13.468 5.89682 14.0335 6.8457L16.5089 11H21.0097C21.562 11 22.0097 11.4477 22.0097 12C22.0097 12.5523 21.562 13 21.0097 13H16.4138L13.9383 17.1543C13.3729 18.1032 12.0191 18.8724 10.9145 18.8724H8.91454L12.4138 13H5.42485L3.99036 15.4529H1.99036L4.00967 12L4.00967 11.967L2.00967 8.54712H4.00967L5.44417 11H12.5089L9.00967 5.12761Z"</span> <span class="hljs-attr">fill</span>=<span class="hljs-string">"currentColor"</span> /&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
  );
}
</code></pre>
<p>Here we are calling the API we just created with <code>fetch</code>, which is provided by React.</p>
<p>Fetch calls the serverless API with the body like this:</p>
<pre><code class="lang-js">body: <span class="hljs-built_in">JSON</span>.stringify({
          <span class="hljs-attr">email</span>: email,
          <span class="hljs-attr">fullname</span>: fullname,
          <span class="hljs-attr">subject</span>: subject,
          <span class="hljs-attr">message</span>: message,
        })
</code></pre>
<p>These are our form fields with the form data filled in already (remember <code>useState()</code>?) which are now available to us.</p>
<p>The API responds with either success or failure. If it is a success, the email gets delivered – otherwise, the mail doesn't get delivered. </p>
<p>For the end-user to know the form status, we need to show some UI elements. But before that, we need to handle what happens if there are empty fields.</p>
<h2 id="heading-how-to-handle-form-validation-and-make-the-ui-respond-to-the-api-response">How to Handle Form Validation and Make the UI Respond to the API Response</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-1.31.42-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We need to ensure 3 things here:</p>
<ol>
<li>All the fields should be filled in – that is, we can't submit the form if any of the fields are empty. Also, the user must know why the form is not submitting. For that, we are going to display error messages.</li>
<li>While the form is being submitted, the user must know that some processing is going on. For that, we are going to change the button text when the form is in the process of submitting.</li>
<li>When the form is successfully submitted or if it fails, we are going to show the final status at the bottom of the form.</li>
</ol>
<p>Let's create a method <code>handleValidation()</code> to check for validation:</p>
<pre><code class="lang-js">
  <span class="hljs-keyword">const</span> handleValidation = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">let</span> tempErrors = {};
    <span class="hljs-keyword">let</span> isValid = <span class="hljs-literal">true</span>;

    <span class="hljs-keyword">if</span> (fullname.length &lt;= <span class="hljs-number">0</span>) {
      tempErrors[<span class="hljs-string">"fullname"</span>] = <span class="hljs-literal">true</span>;
      isValid = <span class="hljs-literal">false</span>;
    }
    <span class="hljs-keyword">if</span> (email.length &lt;= <span class="hljs-number">0</span>) {
      tempErrors[<span class="hljs-string">"email"</span>] = <span class="hljs-literal">true</span>;
      isValid = <span class="hljs-literal">false</span>;
    }
    <span class="hljs-keyword">if</span> (subject.length &lt;= <span class="hljs-number">0</span>) {
      tempErrors[<span class="hljs-string">"subject"</span>] = <span class="hljs-literal">true</span>;
      isValid = <span class="hljs-literal">false</span>;
    }
    <span class="hljs-keyword">if</span> (message.length &lt;= <span class="hljs-number">0</span>) {
      tempErrors[<span class="hljs-string">"message"</span>] = <span class="hljs-literal">true</span>;
      isValid = <span class="hljs-literal">false</span>;
    }

    setErrors({ ...tempErrors });
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"errors"</span>, errors);
    <span class="hljs-keyword">return</span> isValid;
  };
</code></pre>
<p>The function is pretty straightforward: it checks for all the fields and returns a boolean <code>isValid</code> if the form is valid. </p>
<p>Also, we are maintaining state for all the fields to display error messages at the end – essentially, we are saving the fields that contain errors.</p>
<p>The final code looks something like this, with button text, error messages, and form validations:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ContactUs</span>(<span class="hljs-params"></span>) </span>{
   <span class="hljs-comment">// States for contact form fields</span>
  <span class="hljs-keyword">const</span> [fullname, setFullname] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [email, setEmail] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [subject, setSubject] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [message, setMessage] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-comment">//   Form validation state</span>
  <span class="hljs-keyword">const</span> [errors, setErrors] = useState({});

  <span class="hljs-comment">//   Setting button text on form submission</span>
  <span class="hljs-keyword">const</span> [buttonText, setButtonText] = useState(<span class="hljs-string">"Send"</span>);

  <span class="hljs-comment">// Setting success or failure messages states</span>
  <span class="hljs-keyword">const</span> [showSuccessMessage, setShowSuccessMessage] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [showFailureMessage, setShowFailureMessage] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-comment">// Validation check method</span>
  <span class="hljs-keyword">const</span> handleValidation = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">let</span> tempErrors = {};
    <span class="hljs-keyword">let</span> isValid = <span class="hljs-literal">true</span>;

    <span class="hljs-keyword">if</span> (fullname.length &lt;= <span class="hljs-number">0</span>) {
      tempErrors[<span class="hljs-string">"fullname"</span>] = <span class="hljs-literal">true</span>;
      isValid = <span class="hljs-literal">false</span>;
    }
    <span class="hljs-keyword">if</span> (email.length &lt;= <span class="hljs-number">0</span>) {
      tempErrors[<span class="hljs-string">"email"</span>] = <span class="hljs-literal">true</span>;
      isValid = <span class="hljs-literal">false</span>;
    }
    <span class="hljs-keyword">if</span> (subject.length &lt;= <span class="hljs-number">0</span>) {
      tempErrors[<span class="hljs-string">"subject"</span>] = <span class="hljs-literal">true</span>;
      isValid = <span class="hljs-literal">false</span>;
    }
    <span class="hljs-keyword">if</span> (message.length &lt;= <span class="hljs-number">0</span>) {
      tempErrors[<span class="hljs-string">"message"</span>] = <span class="hljs-literal">true</span>;
      isValid = <span class="hljs-literal">false</span>;
    }

    setErrors({ ...tempErrors });
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"errors"</span>, errors);
    <span class="hljs-keyword">return</span> isValid;
  };

  <span class="hljs-comment">//   Handling form submit</span>

  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-keyword">async</span> (e) =&gt; {
    e.preventDefault();

    <span class="hljs-keyword">let</span> isValidForm = handleValidation();

    <span class="hljs-keyword">if</span> (isValidForm) {
      setButtonText(<span class="hljs-string">"Sending"</span>);
      <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/sendgrid"</span>, {
        <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
          <span class="hljs-attr">email</span>: email,
          <span class="hljs-attr">fullname</span>: fullname,
          <span class="hljs-attr">subject</span>: subject,
          <span class="hljs-attr">message</span>: message,
        }),
        <span class="hljs-attr">headers</span>: {
          <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
        },
        <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
      });

      <span class="hljs-keyword">const</span> { error } = <span class="hljs-keyword">await</span> res.json();
      <span class="hljs-keyword">if</span> (error) {
        <span class="hljs-built_in">console</span>.log(error);
        setShowSuccessMessage(<span class="hljs-literal">false</span>);
        setShowFailureMessage(<span class="hljs-literal">true</span>);
        setButtonText(<span class="hljs-string">"Send"</span>);
        <span class="hljs-keyword">return</span>;
      }
      setShowSuccessMessage(<span class="hljs-literal">true</span>);
      setShowFailureMessage(<span class="hljs-literal">false</span>);
      setButtonText(<span class="hljs-string">"Send"</span>);
    }
    <span class="hljs-built_in">console</span>.log(fullname, email, subject, message);
  };
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
      // Rest of the JSX code goes here. (With form fields)
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
  );
}
</code></pre>
<p>When the form is delivered successfully, we get a nice response at the UI. To deliver that response, we have <code>showSuccessMessage</code> and <code>showFailureMessage</code> states. If the response from the back-end API route does NOT contain the property <code>error</code>, that means the form submission was successful and the email has been sent.</p>
<p>In that case, <code>showSuccessMessage</code> is set to True, which shows the corresponding markup just beneath the Form box. If the response body contains the property of <code>error</code>, the <code>showFailureMessage</code> is set to True and the corresponding message is displayed on the screen.</p>
<p>In both success and failure scenarios, we have to reset the button text to <code>send</code> instead of <code>sending...</code>. For that, we are using the state <code>setButtonText('send')</code> that sets the button text in case of failure or success. We set the button text to <code>sending...</code> when the Send button is clicked.</p>
<h2 id="heading-how-to-receive-emails-and-ui-responses">How to Receive Emails and UI Responses</h2>
<p>When the email is successfully delivered, we get a success message in the contact form itself.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-1.37.32-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And you will successfully receive an email with the template that we just created, securely delivered by SendGrid 💯</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot-2021-08-25-at-1.38.54-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-environment-variables">Environment Variables</h2>
<p>Please note that we are using the API keys and the keys are sensitive. This means that we should always store secret or API keys in environment variables. </p>
<p>As we already have <code>.env.local</code> for our local environment, the hosting provider needs to know about the API keys too.</p>
<p>Vercel provides an easy way to store API keys on the hosting panel itself.</p>
<p>To store the API keys securely in your Vercel account, do the following:</p>
<ul>
<li>Go to your projects page</li>
<li>Go to settings</li>
<li>Go to Environment variables</li>
<li>Add the name of the environment variable, in our case it is <code>SENDGRID_API_KEY</code>, and add the corresponding API key in the value field.</li>
<li>Re-deploy your application and your project will work in a production environment.</li>
</ul>
<h2 id="heading-live-demo-and-source-code">Live Demo and Source Code</h2>
<p>Here are the source code and a live demo of the application:</p>
<p><a target="_blank" href="https://sendgrid-contact-form.vercel.app/">Live Demo</a>
<a target="_blank" href="https://github.com/manuarora700/sendgrid-contact-form">Source Code</a></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>SendGrid is an excellent option to use to send emails from a website. When you integrate it with Next.js and their serverless API routes, it becomes extremely easy to integrate forms in any part of your website. </p>
<p>SendGrid also gives you an option to integrate templates where you can have custom themes for your emails.</p>
<p>There are other options too for sending emails like <a target="_blank" href="https://nodemailer.com/about/">Nodemailer</a> that I've used in the past and still use for some of my projects.</p>
<p>It took me around an hour to build this application from the ground up – all thanks to Next.js, TailwindCSS, and SendGrid for their extremely intuitive workflow and API semantics. Also thanks to the <a target="_blank" href="https://tailwindmasterkit.com">Tailwind Master Kit</a> for the beautiful Contact Page UI.</p>
<p>If you liked this blog, try implementing it in your own website so you can reach out to your end-users. </p>
<p>If you'd like to give any feedback, reach out to me at my <a target="_blank" href="https://twitter.com/mannupaaji">Twitter handle</a> or visit my <a target="_blank" href="https://manuarora.in">Website</a></p>
<p>Happy coding. :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is SendGrid? SMTP Email Newsletter Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ You may have heard of the term SMTP before, and wondered what it is. SMTP is a common method for handling email messages. Today I am going to explain what SMTP is, and how to use an SMTP provider such as SendGrid to send emails from your address. Wha... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-sendgrid-smpt-email-newsletter-tutorial/</link>
                <guid isPermaLink="false">66ac7f74ed08c5b0125be191</guid>
                
                    <category>
                        <![CDATA[ communication ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ newsletters ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Naomi Carrigan ]]>
                </dc:creator>
                <pubDate>Fri, 14 May 2021 20:31:30 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/05/pexels-rakicevic-nenad-1262304.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You may have heard of the term SMTP before, and wondered what it is. SMTP is a common method for handling email messages.</p>
<p>Today I am going to explain what SMTP is, and how to use an SMTP provider such as <a target="_blank" href="https://sendgrid.com">SendGrid</a> to send emails from your address.</p>
<h2 id="heading-what-is-smtp">What Is SMTP?</h2>
<p>SMTP, or Simple Mail Transfer Protocol, is the method through which internet servers send email messages. When you send an email through your Gmail account, for example, your mail client uses SMTP to send that message to the server. The server then also uses SMTP to send it to the receiving server.</p>
<p>Without diving too much into the technical details, the easiest way to think of it is that SMTP is an email server. </p>
<h2 id="heading-what-is-sendgrid">What is SendGrid?</h2>
<p>SendGrid is an SMTP service provider – in fact, it's the provider freeCodeCamp uses to send out Quincy's weekly newsletter. </p>
<p>Like many SMTP providers, SendGrid offers the use of their mail servers to send your emails. This is an excellent option for sending large volumes of emails, where having to do so manually would take a significant amount of time and effort.</p>
<h3 id="heading-how-to-create-a-sendgrid-account">How to Create a SendGrid Account</h3>
<p>The first step in using SendGrid's services is to create your account. Head on over to the <a target="_blank" href="https://sendgrid.com">SendGrid website</a> to get signed up. They offer multiple pricing models, but the free level will be sufficient at least for this tutorial. </p>
<p>As you scale up your email list, however, you may need additional features from a higher subscription tier.</p>
<p>Once you are signed in, you should see a default dashboard view:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/image-4.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image depicting the default SendGrid dashboard view.</em></p>
<h3 id="heading-how-to-set-up-your-domain-or-email-with-sendgrid">How to Set up Your Domain or Email with SendGrid</h3>
<p>From that dashboard view, select "Settings", then choose "Sender Authentication" from the dropdown menu. The Sender Authentication settings are where you tell SendGrid which email accounts to allow emails to be sent from.</p>
<p>There are two approaches here – if you have a custom domain for your emails, you can set up Domain Authentication. If you are using a personal email address, such as a Gmail address, then you will need to set up Single Sender Authentication.</p>
<p>Choose whichever option works best for you, and follow SendGrid's prompts to set it up. Your end result should look similar to this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/image-5.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image depicting Sender Authentication settings.</em></p>
<h3 id="heading-how-to-send-emails-via-sendgrids-api">How to Send Emails Via SendGrid's API</h3>
<p>The actual process of sending the emails is done through <a target="_blank" href="https://sendgrid.com/docs/api-reference/">SendGrid's API</a>. But before you can use the API, you'll need to set up an API key. </p>
<p>From your dashboard view, select "Settings", then select "API Keys". Choose "Create API Key" and select the permissions you want the key to have (I gave mine full permissions, just to avoid issues). </p>
<p>Once you have the key, save it somewhere safe as you will not be able to access it again.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/image-6.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image depicting the API Keys settings page.</em></p>
<p>Now that you have the API key, you'll need to set up the code to use the <code>/mail/send</code> endpoint. You can write the code manually, or use one of the helper libraries such as SendGrid's <a target="_blank" href="https://github.com/sendgrid/sendgrid-nodejs">Node.js package</a>. </p>
<p>When using the Node.js package, you set the values for your email as follows:</p>
<ul>
<li><code>to</code>: The address to send the email to.</li>
<li><code>from</code>: The address to send the email from. This should match your settings in the Sender Authentication.</li>
<li><code>subject</code>: The subject of your email.</li>
<li><code>text</code>: The content of your email, if you are sending a plain text email.</li>
<li><code>html</code>: The content of your email, if you are sending an HTML email.</li>
</ul>
<p>The properties in a raw API call are different, as are the properties in the other helper libraries. Be sure to refer to the documentation for your specific approach.</p>
<h3 id="heading-how-to-use-dynamic-templates-in-sendgrid">How to Use Dynamic Templates in SendGrid</h3>
<p>As an alternative option, instead of sending the email content in your API call, you can use a Dynamic Template to generate the content. </p>
<p>A Dynamic Template lets you set the content for emails to send out, and offers Handlebars functionality to replace specific data fields.</p>
<p>To create a Dynamic Template, from your dashboard select "Email API" and then "Dynamic Templates". Then click "Create a Dynamic Template" – you should see your template appear below. </p>
<p>Click on it, then select "Add Version" to open the template selection. Choose the blank template, then select the type of editor you would like to use (I use the code editor).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/image-7.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image depicting the editor.</em></p>
<p>You can write the content of your email, and use placeholders such as <code>{{name}}</code> for the dynamic data. These placeholders would be given values through your API calls when you send the emails. </p>
<p>If you want to see how it would render, you can use the "Test Data" tab to add sample data for the placeholders.</p>
<h3 id="heading-how-to-get-blocksbouncesspams-via-sendgrids-api">How to Get Blocks/Bounces/Spams via SendGrid's API</h3>
<p>It's important to track undeliverable emails. SendGrid offers tooling to help track this for you, and that data is available through three different dashboard views (or API endpoints, if you want to parse the data programmatically).</p>
<ul>
<li><code>Blocked</code> emails are emails that were rejected by the receiving email provider's policies, such as university emails that don't accept external traffic, or emails that could not be resolved (the mail server was not found).</li>
<li><code>Bounced</code> emails are emails that were received by the server but returned. This occurs in cases where the email server exists, but the specific user does not, or the email inbox is at capacity.</li>
<li><code>Spam</code> emails are arguably the most important to monitor, as these are generated when a user receives your email and reports to their provider that your email is spam. These directly impact your reputation as a sender, so it is imperative that you do not send an email to someone who has marked your previous emails as spam.</li>
</ul>
<h3 id="heading-other-concerns">Other Concerns</h3>
<p>Speaking of your reputation as a sender, SendGrid offers a top-level metric called "Sender Reputation". This metric is an aggregation of your activity through their platform, and helps give a general idea of the way email providers are likely to handle your emails. </p>
<p>A lower reputation will result in your emails being marked as spam automatically, or even your IP addresses being blocked.</p>
<p>If you are on the free tier for SendGrid, you will be using shared IP addresses. This means that other customers will also be sending emails through that same IP, and their actions can negatively impact your reputation. </p>
<p>If you intend to send large volumes of emails, I recommend that you purchase dedicated IP addresses to ensure that your reputation is protected.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope this article has helped you become more familiar with SendGrid and the services they offer. You should now be ready to start sending your own emails. </p>
<p>If you are planning to start an email newsletter, I wrote an article about <a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-an-email-newsletter-design-layout-send/">creating effective email newsletters</a> that might help.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create an Email Newsletter – Design, Layout, Send ]]>
                </title>
                <description>
                    <![CDATA[ If you manage a large community, chances are you need a way to communicate updates to your members quickly and efficiently. An email newsletter can be a very effective way to do so. In this article, I am going to provide some tips and suggestions for... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-an-email-newsletter-design-layout-send/</link>
                <guid isPermaLink="false">66ac7f3423cc28a03a55e084</guid>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email marketing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ newsletters ]]>
                    </category>
                
                    <category>
                        <![CDATA[ writing tips ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Naomi Carrigan ]]>
                </dc:creator>
                <pubDate>Thu, 13 May 2021 21:19:40 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/05/pexels-anthony-shkraba-5206271.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you manage a large community, chances are you need a way to communicate updates to your members quickly and efficiently. An email newsletter can be a very effective way to do so.</p>
<p>In this article, I am going to provide some tips and suggestions for maximizing the impact of your email newsletter: open rates, click-through rate, and not irritating your recipients.</p>
<p>I will also share some technical details and configurations you can use to maximize the deliverability of your email newsletter.</p>
<h2 id="heading-how-to-write-an-impactful-subject-line">How to Write an Impactful Subject Line</h2>
<p>Your subject line is the first thing your readers will see when the email appears in their inbox. It's important, then, that you use something eye catching that encourages them to read the message.</p>
<h3 id="heading-what-to-include-in-the-subject-line">What to Include in the Subject Line</h3>
<p>Your subject line should provide a brief summary of the email content or highlight the key information. Some examples would be:</p>
<blockquote>
<p>Learn Data Structures and Algorithms [free 6-hour coding course]</p>
</blockquote>
<p>This headline comes from one of Quincy's email newsletters, and calls out the first article out of a weekly curated list of five articles.</p>
<blockquote>
<p>Our Community Reached 3,000 Members - Here's What's Next</p>
</blockquote>
<p>Here the headline provides a clear summary of the email's content – an update on the community's success and future plans.</p>
<blockquote>
<p>The Observatory #4: Gravity is the key to community growth</p>
</blockquote>
<p>Pulled from an <a target="_blank" href="https://orbit.love">Orbit</a> newsletter, this subject line has two benefits: Like the others, it summarizes the content of the email. It also helps readers recognize this email as a serial newsletter, and track the number to ensure they have not missed one.</p>
<h3 id="heading-what-to-exclude-from-the-subject-line">What to Exclude from the Subject Line</h3>
<p>You want to avoid headlines which are vague, uninformative, or may seem like spam.</p>
<blockquote>
<p>Click Here! Important Information Within!</p>
</blockquote>
<p>Avoid words and phrases such as <code>click here</code>, <code>urgent</code>, <code>important</code>, and <code>priority</code>. These types of subject lines are often used in spam emails, and can cause your readers to disengage.</p>
<blockquote>
<p>April 2020 Community Update</p>
</blockquote>
<p>While this subject is not going to seem like spam, it is also vague and uninformative. You want your subject to catch the reader's attention and be unique.</p>
<blockquote>
<p>Top Picks Just For You</p>
</blockquote>
<p>Another vague subject line, this one also gives off a "click-bait" vibe. This type of subject line doesn't hook your readers or entice them in to reading your full email.</p>
<h2 id="heading-how-to-craft-an-effective-email-body">How to Craft an Effective Email Body</h2>
<p>The body of your email is where your core content will go. Having a well written and effective email body is essential.</p>
<h3 id="heading-html-vs-plain-text-in-emails">HTML vs. Plain Text in Emails</h3>
<p>Using HTML in your email can make it look nice, certainly. However, HTML emails are more likely to be flagged as spam by the receiving providers.</p>
<p>Plain text emails are generally safer, though they offer less functionality. Additionally, a plain text email will ensure maximum compatibility with all devices, and ensure that your email can be viewed even over slower internet connections.</p>
<p>HTML, on the other hand, offers a much higher level of customization in terms of layout, content, and functionality. You can even implement things like interaction tracking to see who is opening (open rate), reading, and clicking on links in your email (click-through rate). Whether these features are worth the potential impact to delivery is or not is up to you.</p>
<h3 id="heading-how-to-handle-links-in-emails">How to Handle Links in Emails</h3>
<p>Speaking of links, there are some special considerations when it comes to handling links in your email. The key idea is to keep your links easily readable and verifiable.</p>
<p>One important aspect is the transparency of your links. You want to avoid using things like URL shorteners that hide the domain the link points to. Keeping your link's target clear ensures that your readers can trust the safety of the link.</p>
<p>Many sending providers offer click-tracking features, where they will provide metrics on how many of your readers click the links within your email.</p>
<p>While these metrics may seem useful, they do come at a cost – usually the links are obfuscated through a redirect via the provider's domain. This decreases the chance that your readers will click the link.</p>
<h3 id="heading-unsubscribe-links">Unsubscribe Links</h3>
<p>If your email is considered commercial material (marketing, advertisements, and so on.), having an unsubscribe link is <em>required</em>. If it is a transactional (receipt, account updates) or relationship (communicating with existing contacts) email, then an unsubscribe link is not necessarily required but is still strongly recommended.</p>
<p>Having an unsubscribe link allows your recipients to quickly and easily opt-out of receiving future communications. While it may not seem ideal to lose your reader base, it is much better than having your emails flagged as spam (which can impact your sender reputation and cause future emails to anyone with that email provider to be blocked).</p>
<p>Your unsubscribe link does not need to be prominent or featured – a simple link with the text "Unsubscribe" at the bottom of your email is often sufficient.</p>
<h3 id="heading-content-and-layout-of-your-emails">Content and Layout of Your Emails</h3>
<p>The content and layout of your email body are also very important. If you are using plain text to send your email, then your biggest consideration will be the length of your paragraphs. In general, shorter paragraphs are easier to read than a "wall of text", and will help your readers stay engaged with the content.</p>
<p>If you are using HTML, then you have some additional obstacles to consider.</p>
<p>For example, including images may seem very tempting as they can make the email look more visually appealing. But each image increases the time it takes for the email to render on the reader's device, and images aren't as accessible for those who use screen readers as plain text is.</p>
<p>Remember that images should add to the content, not detract from the information.</p>
<p>Another aspect to consider when using HTML is the semantic structure. To avoid any rendering errors or accessibility concerns, you will want to keep your HTML semantically correct. I recommend using an <a target="_blank" href="https://validator.w3.org/">HTML Validator</a> before sending the email to ensure you don't have any errors.</p>
<p>Content length itself is also important. You don't want to overwhelm your readers with too much information in a single email. If you have a lot of content you want to share, consider making a blog post or news article – then, link that article in your email with a brief summary of the content.</p>
<h3 id="heading-how-to-sign-off-in-an-email">How to Sign Off in an Email</h3>
<p>The signature of your email is just as important as the main content. Signing off your email lets your readers know who sent it, and gives you the opportunity to close out the content.</p>
<p>You should include your name and your role within your organization, so that your readers see that the email came from a person. This creates the impression that it is a more personal communication and not an automatically generated email.</p>
<p>Finally, the signature and conclusion also give you the chance to thank your readers for their time. It is good to recognize that your readers took time out of their day to read your content. Time is valuable, and your readers have given you theirs.</p>
<h2 id="heading-technical-aspects-of-email-newsletters">Technical Aspects of Email Newsletters</h2>
<p>Now that you've drafted your first newsletter, you need to address the technical concerns. Namely, you'll need to figure out how you'll send this newsletter.</p>
<h3 id="heading-choose-a-sending-provider">Choose a Sending Provider</h3>
<p>The first question to answer is what will you use to send this email? It is entirely possible to set up and run your own Secure Mail Transfer Protocol (SMTP) server, but that can be a significant investment of time and resources.</p>
<p>Instead, there are a number of providers that will handle sending the emails for you. Here at freeCodeCamp we use <a target="_blank" href="https://www.sendgrid.com">SendGrid</a>. Most providers will offer an API to request that emails be sent, or a UI to prepare your emails. Then they will handle the actual send process for you.</p>
<p>While these providers can get expensive at higher volumes, often times the cost is worth the access to additional features such as email validation and bounce report tracking.</p>
<h3 id="heading-set-up-email-authentication">Set up Email Authentication</h3>
<p>Another important technical aspect is email verification and authentication, especially if you are using a custom domain.</p>
<p>How does a provider such as Gmail confirm that the email has legitimately come from your organization and not someone pretending to be you?</p>
<p>There are a couple of security steps you can take to ensure that your emails are delivered while spoofed emails are not.</p>
<ul>
<li><p><strong>Sender Policy Framework (SPF):</strong> You can use an SPF setting to validate that the mail server is authorized to send emails from your email domain. SPF is enabled via a <code>TXT</code> record in your domain settings. The content of that record will depend on the system you are using to send those emails.</p>
</li>
<li><p><strong>DomainKeys Identified Mail (DKIM):</strong> You can use DKIM to assert that the email message has not been modified in transit from the sending server to the receiving server. DKIM records are set up in your domain settings either as a <code>TXT</code> record or a <code>CNAME</code> record, depending on your provider. These records will indicate the public encryption/decryption keys.</p>
</li>
<li><p><strong>Domain Message Authentication, Reporting, and Conformance (DMARC):</strong> The final step, after enabling SPF and DKIM, is to set up a DMARC record. The DMARC record tells email providers what to do if an email from your domain fails SPF or DKIM, where to send delivery reports, and how often to apply the DMARC policy. A DMARC record is added as a <code>TXT</code> record to your domain settings, as <code>_dmarc.yourdomain.tld</code>.</p>
</li>
</ul>
<p>Congratulations. Now that you have read this article, you should have a basic understanding of how to create and send your first email newsletter. I hope you found this article helpful.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Receive Emails from Your Site's "Contact Us" form Using AWS SES, Lambda, & API Gateway ]]>
                </title>
                <description>
                    <![CDATA[ By Adham El Banhawy I was recently building a simple landing page website for a client who wanted to receive emails through their website without sharing their email.  Honestly, I had never tried to implement that functionality myself before. I was a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-receive-emails-via-your-sites-contact-us-form-with-aws-ses-lambda-api-gateway/</link>
                <guid isPermaLink="false">66d45d5fbd438296f45cd383</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ aws lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ email ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 24 Mar 2021 19:26:52 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/605b0cfb687d62084bf6bd50.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adham El Banhawy</p>
<p>I was recently building a simple landing page website for a client who wanted to receive emails through their website without sharing their email. </p>
<p>Honestly, I had never tried to implement that functionality myself before. I was always used to having a simple "Contact Us" button with an anchor tag and a <code>mailto</code> in the <em>href</em> attribute like this:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"mailto:myemail@example.com"</span>&gt;</span>Contact Me<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>But this approach has two inconveniences:</p>
<ol>
<li>It forces both parties, the user who wants to send the message and the site owner who receives it, to share their emails with one another. While this is OK for some, it is not ideal for privacy-minded individuals.</li>
<li>For the site visitor, clicking the link forces them to open their default mail program on their device, and that can be frustrating. What if they're using a public computer? What if they're not logged in? What if they simply don't want to use their mail program?<br>Yes, technically they can just grab the recipient's email address and send the message via their browser or wherever they're logged in. But those are all extra steps and hurdles that can discourage users from sending their messages and the business might lose potential feedback or opportunities.</li>
</ol>
<p>For this reason, we chose to go with an email form from which the user can simply write in their message and click submit, sending an email to the site's owner without ever leaving the website.</p>
<p>A quick Google search shows that there are third party tools/widgets that you could embed in a website, but most of them are branded and require paid subscription for full customization. </p>
<p>And unless you are using a CMS like WordPress that has a built-in plugin that can do that, that's an inconvenient recurring cost. </p>
<p>I instead chose to code that feature myself so I would have full control.</p>
<p>For the purposes of this guide I will recreate the steps I took to implement that functionality using HTML and AWS services.</p>
<h2 id="heading-the-html-form">The HTML Form</h2>
<p>I'll keep it super simple here and go with a basic HTML form with no CSS, just to test our desired functionality.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Contact Us<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"name"</span>&gt;</span>Name:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>/&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span>/&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"name"</span>&gt;</span>Message:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"message"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>/&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"result-text"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-61.png" alt="Image" width="600" height="400" loading="lazy">
<em>Nothing fancy to see here...</em></p>
<p>Now we want to handle the submit functionality with JavaScript.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'form'</span>)
form.addEventListener(<span class="hljs-string">'submit'</span>, <span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
  <span class="hljs-comment">// prevent the form submit from refreshing the page</span>
  event.preventDefault()

  <span class="hljs-keyword">const</span> { name, email, message } = event.target
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Name: '</span>, name.value)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'email: '</span>, email.value)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Message: '</span>, message.value)

})
</code></pre>
<p>At this point, we have a form that gets input from the user and JavaScript code that just displays the results to the console. </p>
<p>We can leave it at that for now and start working on the backend services that will receive the form data and send an email with that data.</p>
<h2 id="heading-the-backend-overview">The Backend Overview</h2>
<p>Let's dive into AWS and what services we are going to use and how. </p>
<p>As mentioned in the title, we will use <strong>AWS Lambda</strong> and <strong>Simple Email Service</strong> (SES). SES is a serverless messaging service that allows you to send email messages when invoked. AWS Lambda allows you to write server-side code to execute in response to events. </p>
<p>We will also use <strong>API Gateway</strong> which enables us to invoke Lambda functions via HTTP.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-62.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In this case, when our form is submitted, the following workflow will happen:</p>
<ol>
<li>Our browser (JavaScript) will make a post request, with the form data in the request body, to an endpoint URL specified by AWS API Gateway</li>
<li>The API Gateway will validate this request. Then it will trigger the Lambda function which accepts an event parameter. API Gateway will put the form data in the body property of the event parameter.</li>
<li>Our Lambda function will extract the data from the event body and we will then use this data to build the body of the email we want to send as well as its recipients. Our function will then use the AWS SDK to invoke SES with the email data.</li>
<li>Once SES gets the <em>sendMail</em> request, it turns the email data into an actual text email and sends it to the recipient via AWS's own mail servers.</li>
</ol>
<p>Once the email is sent, our browser will receive a response with status code 200 and a success message. If any step in the AWS cloud fails, the response will have a 500 status code.</p>
<h2 id="heading-step-1-how-to-set-up-ses">Step 1: How to Set Up SES</h2>
<p>We're actually going to set up each one of these steps in the reverse order, beginning with SES, which is going to be easier.</p>
<p>First in your AWS console, go to the SES service —&gt; then click on Email Addresses in the side menu —&gt; then click on the "Verify a New Email Address" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-63.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the dialogue that opens up, enter the email address that you want the SES service to put as the <em>sender</em> when it sends the email.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-64.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This will send an email to the email address you put with a link to click to verify. This is how AWS knows that the owner of the email consents to having their email address used as the sender address.</p>
<p>Until you verify the email, the SES email dashboard will keep the verification status as pending.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-65.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once the email owner opens the email they received from AWS and clicks the verification link in it, the verification status should change to verified (refresh the page to see the change).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-66.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And that's all you have to do for SES. You can optionally test the service by selecting your verified email in the list and clicking the "Send a Test Email" button. This will let you put in a recipient's email address, a subject, and a message and send it.</p>
<p>The email sent is going to be signed by AWS servers and your verified address should be the sender. It should look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-67.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-step-2-how-to-set-up-lambda">Step 2: How to Set Up Lambda</h2>
<p>Now this is the most fun part. We are going to create a function that is going to receive the form data and call SES. </p>
<p>The beauty of Lambda functions is that you don't have to worry about running your backend code on a server 24/7 and maintaining that server. It's <em>serverless</em>. </p>
<p>But that doesn't mean there are no servers involved. AWS is going to take care of that under the hood so you can only focus on writing code, not maintaining servers. Additionally, you only get billed for the number of times your function gets called and the amount of time it takes to execute, and it's <a target="_blank" href="https://aws.amazon.com/lambda/pricing/">incredibly cheap</a>!</p>
<h3 id="heading-create-an-iam-role-and-configure-it">Create an IAM Role and Configure it</h3>
<p>Before we start writing our lambda function, we need to create an IAM <em>role</em> to attach it to the function and grant it permissions (referred to as policies in AWS) to invoke the SES service.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-68.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>From your AWS console, go to the IAM service —&gt; click on Policies in the side menu —&gt; then click on the "Create Policy" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-69.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the policy creation page, go to the JSON tab and paste the following permissions, then click Next.</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
    <span class="hljs-attr">"Statement"</span>: [
        {
            <span class="hljs-attr">"Sid"</span>: <span class="hljs-string">"VisualEditor0"</span>,
            <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
            <span class="hljs-attr">"Action"</span>: [
                <span class="hljs-string">"ses:SendEmail"</span>,
                <span class="hljs-string">"ses:SendRawEmail"</span>
            ],
            <span class="hljs-attr">"Resource"</span>: <span class="hljs-string">"*"</span>
        }
    ]
}
</code></pre>
<p>In the third screen, name the policy and click the "Create Policy" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-70.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now we create an IAM <em>role</em> which will be attached to the lambda and link it to the permissions policy which we just created.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-71.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>From the IAM side menu, click Roles then click the "Create role" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-72.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the role creation screen, make sure the type selected is "AWS service" and select the Lambda case then click on the "Next:Permissions" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-73.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the next screen, search for the policy we created earlier by its name and select it, then click next.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-74.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On the review screen, give the role a name you can remember then click on "Create role".</p>
<p>Now we can create a new lambda function. Go to the Lambda service dashboard and click the "Create Function" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-75.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the function creation screen, name your function, select the "Author from scratch" option, and choose Node.js as the runtime. </p>
<p>Under "Change default execution role" choose the "Use an existing role" option then choose the name of the role you created in the previous step from the "Existing role" drop down. </p>
<p>Finally, click the "Create function" button to create the function.</p>
<h3 id="heading-write-the-code-and-test-it">Write the Code and Test it</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-76.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the editor, open the index.js file (this is the file that will be executed when your lambda is called), and replace its content with the following code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> aws = <span class="hljs-built_in">require</span>(<span class="hljs-string">"aws-sdk"</span>);
<span class="hljs-keyword">const</span> ses = <span class="hljs-keyword">new</span> aws.SES({ <span class="hljs-attr">region</span>: <span class="hljs-string">"us-east-1"</span> });
<span class="hljs-built_in">exports</span>.handler = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event</span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'EVENT: '</span>, event)
  <span class="hljs-keyword">const</span> params = {
    <span class="hljs-attr">Destination</span>: {
      <span class="hljs-attr">ToAddresses</span>: [<span class="hljs-string">"your@email.com"</span>],
    },
    <span class="hljs-attr">Message</span>: {
      <span class="hljs-attr">Body</span>: {
        <span class="hljs-attr">Text</span>: { 
            <span class="hljs-attr">Data</span>: <span class="hljs-string">`Hello from Lambda!`</span> 
        },
      },
      <span class="hljs-attr">Subject</span>: { <span class="hljs-attr">Data</span>: <span class="hljs-string">`Message from AWS Lambda`</span> },
    },
    <span class="hljs-attr">Source</span>: <span class="hljs-string">"your@email.com"</span>,
  };

  <span class="hljs-keyword">return</span> ses.sendEmail(params).promise()
};
</code></pre>
<p>Notice that on line 2 we are using the AWS SDK and creating an SES instance. The reason I chose <strong>us-east-1</strong> as the region is because that's <em>where I registered &amp; verified my email</em>. Be sure to replace the email and use the AWS region where you registered your email.</p>
<p>Now to test this function, click on the "Deploy" button. Then click on the Test button —&gt; Configure test event which should open up a test configuration dialogue where you can create a new test event.  </p>
<p>In the test event body editor, enter the following JSON which mimics what will eventually come from our browser request. Then click create.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"body"</span>: {
        <span class="hljs-attr">"senderName"</span>: <span class="hljs-string">"Namo"</span>,
        <span class="hljs-attr">"senderEmail"</span>: <span class="hljs-string">"namo@trains.com"</span>,
        <span class="hljs-attr">"message"</span>: <span class="hljs-string">"I love trains!"</span>
    }
}
</code></pre>
<p>Now clicking the test button will run the test we just created. It should open a new tab in the editor to show us the logs created from running the function, which should look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-77.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Notice the event object we logged out shows here under Function logs with the body data we used in the test event.</p>
<p>This test should have sent an email to my inbox as well – let's see if that happened.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-78.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Yep, just as expected. And that happened almost immediately after running the test.</p>
<p>Now let's modify our function code to get a more meaningful message from the test data.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> aws = <span class="hljs-built_in">require</span>(<span class="hljs-string">"aws-sdk"</span>);
<span class="hljs-keyword">const</span> ses = <span class="hljs-keyword">new</span> aws.SES({ <span class="hljs-attr">region</span>: <span class="hljs-string">"us-east-1"</span> });
<span class="hljs-built_in">exports</span>.handler = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event</span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'EVENT: '</span>, event)
    <span class="hljs-comment">// Extract the properties from the event body</span>
  <span class="hljs-keyword">const</span> { senderEmail, senderName, message } = <span class="hljs-built_in">JSON</span>.parse(event.body)
  <span class="hljs-keyword">const</span> params = {
    <span class="hljs-attr">Destination</span>: {
      <span class="hljs-attr">ToAddresses</span>: [<span class="hljs-string">"the.benhawy@gmail.com"</span>],
    },
        <span class="hljs-comment">// Interpolate the data in the strings to send</span>
    <span class="hljs-attr">Message</span>: {
      <span class="hljs-attr">Body</span>: {
        <span class="hljs-attr">Text</span>: { 
            <span class="hljs-attr">Data</span>: <span class="hljs-string">`You just got a message from <span class="hljs-subst">${senderName}</span> - <span class="hljs-subst">${senderEmail}</span>:
            <span class="hljs-subst">${message}</span>`</span> 
        },
      },
      <span class="hljs-attr">Subject</span>: { <span class="hljs-attr">Data</span>: <span class="hljs-string">`Message from <span class="hljs-subst">${senderName}</span>`</span> },
    },
    <span class="hljs-attr">Source</span>: <span class="hljs-string">"the.benhawy@gmail.com"</span>,
  };

  <span class="hljs-keyword">return</span> ses.sendEmail(params).promise();
};
</code></pre>
<p>It's important to note that when API Gateway calls our function it will pass a string to the event body. This is why I use <code>JSON.parse</code> on event.body, to turn it into JSON and extract our sender's email, name, and message. Then I use those variables in the email body text and subject using string interpolation.</p>
<p>If you try the test it, the code will return an error. This is because the test is passing a JSON object to event.body and we are using JSON.parse on JSON, which causes an error in JavaScript. </p>
<p>Sadly, the test editor doesn't allow us to pass strings to the event, so we'll have to test that later from somewhere else.</p>
<h2 id="heading-step-3-how-to-set-up-api-gateway">Step 3: How to Set Up API Gateway</h2>
<p>Next, the last AWS service we are going to use is API Gateway, which will enable our browser to send HTTP requests to the Lambda function we created.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-79.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Without leaving your lambda function page, expand the "Function overview" section and click on "Add trigger".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-80.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, choose API Gateway from the dropdown, HTTP API as the API type, "Open" as the security mechanism, and check the CORS checkbox option. Then click "Add".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-81.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You should be redirected to the "Configuration" tab of your function, showing you the new API Gateway trigger you just created. From there, note the <strong>API endpoint</strong>. This is the URL we are going to be calling from our browser with the form data.</p>
<h2 id="heading-back-to-the-html">Back to the HTML</h2>
<p>We can finally test the form to see if it sends emails or not.</p>
<p>Let's modify our JavaScript to handle sending the request when the form is submitted.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"form"</span>);
form.addEventListener(<span class="hljs-string">"submit"</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-comment">// prevent the form submit from refreshing the page</span>
  event.preventDefault();

  <span class="hljs-keyword">const</span> { name, email, message } = event.target;

    <span class="hljs-comment">// Use your API endpoint URL you copied from the previous step</span>
  <span class="hljs-keyword">const</span> endpoint =
    <span class="hljs-string">"&lt;https://5ntvcwwmec.execute-api.us-east-1.amazonaws.com/default/sendContactEmail&gt;"</span>;
  <span class="hljs-comment">// We use JSON.stringify here so the data can be sent as a string via HTTP</span>
    <span class="hljs-keyword">const</span> body = <span class="hljs-built_in">JSON</span>.stringify({
    <span class="hljs-attr">senderName</span>: name.value,
    <span class="hljs-attr">senderEmail</span>: email.value,
    <span class="hljs-attr">message</span>: message.value
  });
  <span class="hljs-keyword">const</span> requestOptions = {
    <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
    body
  };

  fetch(endpoint, requestOptions)
    .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (!response.ok) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Error in fetch"</span>);
      <span class="hljs-keyword">return</span> response.json();
    })
    .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"result-text"</span>).innerText =
        <span class="hljs-string">"Email sent successfully!"</span>;
    })
    .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
      <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"result-text"</span>).innerText =
        <span class="hljs-string">"An unkown error occured."</span>;
    });
});
</code></pre>
<p>Now, the moment of truth: fill in the form and click submit. If you see the success message, that means the email was sent.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-82.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Since I own the email the message was sent to, I take a quick look at my inbox to see that I received an email from myself with the details I used in the form!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-83.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you've followed along, you now have a functioning "Contact Us" form that you can plug into any website. And you'll only get billed for when it is actually used. </p>
<p>I don't know about you, but I think this is pretty awesome and almost magical! And it's a nice, practical way to use cloud computing/services in your workflow. </p>
<p>Of course you can customize this flow in terms of using a framework on the frontend like React or Vue or a different programming language for the Lambda like Python or Go.</p>
<h2 id="heading-before-you-go">Before you go...</h2>
<p>Thank you for reading this far! I write posts about JavaScript, cloud development, and my personal educational &amp; professional experiences as a self-taught developer. So feel free to follow me on twitter <a target="_blank" href="https://twitter.com/adham_benhawy">@adham_benhawy</a> where I tweet about them too!</p>
<h3 id="heading-resources">Resources</h3>
<ul>
<li><a target="_blank" href="https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/">https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/</a></li>
<li><a target="_blank" href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html">https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html</a></li>
<li><a target="_blank" href="https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html?icmpid=docs_lambda_console">https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html?icmpid=docs_lambda_console</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
