<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Duncan Teege</title>
    <description>The latest articles on DEV Community by Duncan Teege (@duncanteege).</description>
    <link>https://dev.to/duncanteege</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F422393%2F430c4dc9-44a2-4976-8a5a-dc2051d5f33d.jpeg</url>
      <title>DEV Community: Duncan Teege</title>
      <link>https://dev.to/duncanteege</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/duncanteege"/>
    <language>en</language>
    <item>
      <title>CSS Specificity Explained</title>
      <dc:creator>Duncan Teege</dc:creator>
      <pubDate>Fri, 17 Mar 2023 16:42:02 +0000</pubDate>
      <link>https://dev.to/duncanteege/css-specificity-explained-43ja</link>
      <guid>https://dev.to/duncanteege/css-specificity-explained-43ja</guid>
      <description>&lt;p&gt;If you've ever run into weird, "unexplainable" styling issues, there's a high chance it was something regarding specificity. Specifi-what-ty? Specificity. Let's dive into it.&lt;/p&gt;

&lt;p&gt;Note: For the entirety of this tutorial, we will use CSS. If you use something else, I'm assuming you can translate this article into your preferred language of styling yourself. If not, let me know by asking your question in the comment or emailing me if you are reading this on &lt;a href="https://www.duncanteege.com/blog"&gt;my own website&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is specificity?
&lt;/h2&gt;

&lt;p&gt;Let's be specific about it. Jokes aside, it can be quite difficult to understand at first. Specificity is a calculation being made to determine which CSS rules should be applied. This doesn't make it a lot clearer, so let's look at the selectors we use in CSS to define our styles: &lt;em&gt;ID&lt;/em&gt;, &lt;em&gt;CLASS&lt;/em&gt;, and &lt;em&gt;TYPE&lt;/em&gt;. Notice the order of these, as it is important to understand specificity. First, let's refresh and look at examples of each of these selectors.&lt;/p&gt;

&lt;h3&gt;
  
  
  ID
&lt;/h3&gt;

&lt;p&gt;This one is relatively simple. It's used to style something that shouldn't be reused throughout the entire application. It's extremely specific. An example of this would be &lt;code&gt;#gallery&lt;/code&gt;. The HTML would be &lt;code&gt;&amp;lt;div id="gallery"&amp;gt;...&amp;lt;/div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  CLASS
&lt;/h3&gt;

&lt;p&gt;The first example of this type of selector would be the obvious class selector &lt;code&gt;.blogpost&lt;/code&gt;. You would use a class selector to define something a little less specific, something that might be used in multiple places or at multiple times. In HTML, this would be defined as &lt;code&gt;&amp;lt;div class="blogpost"&amp;gt;...&amp;lt;/div&amp;gt;&lt;/code&gt;. Another example of what would fall under the class column of specificity are attribute selectors. These are selectors that target based on the attributes of an element. For example, &lt;code&gt;[type="checkbox"]&lt;/code&gt;. Another example are pseudo-class selectors like &lt;code&gt;:hover&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  TYPE
&lt;/h3&gt;

&lt;p&gt;Type selectors are selectors where you directly refer to the type of HTML element. Think of the paragraph, h1, or even table elements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Okay... let's talk specificity now
&lt;/h2&gt;

&lt;p&gt;We just looked at examples of selectors we can use while styling. The specific selector we use is important as it determines what the specificity is. Specificity is basically a little list with counters. Each type of selector (&lt;em&gt;ID&lt;/em&gt;, &lt;em&gt;CLASS&lt;/em&gt;, or &lt;em&gt;TYPE&lt;/em&gt;) has its own column in the list. If we would write it out, we could say it like this: "&lt;em&gt;ID&lt;/em&gt; - &lt;em&gt;CLASS&lt;/em&gt; - &lt;em&gt;TYPE&lt;/em&gt;". The CSS styling with the highest numbers, starting from the left, will get applied. This is all quite dry and might be hard to understand, so let's look at some examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples to start with
&lt;/h3&gt;

&lt;p&gt;Let's say we define the following CSS selectors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nf"&gt;#gallery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="err"&gt;styling&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would have a specificity of "1-0-0". Why? Well, &lt;code&gt;#gallery&lt;/code&gt; is an ID selector, so that value will be increased to 1. Let's look at another example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.blogpost&lt;/span&gt; &lt;span class="nc"&gt;.heading&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="err"&gt;styling&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What do you think? I see two classes... classes are in the middle column. If you thought this would have a specificity of "0-2-0", you would be correct! Let's look at one more relatively simple example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="err"&gt;styling&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just a simple type selector. This applies to all paragraphs, so it's not that specific. What would the calculation for this be? If you thought "0-0-1", you're correct!&lt;/p&gt;

&lt;p&gt;Okay, let's look at one more "simple" example before we dive head first into the more difficult calculations to see which styling would be applied.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nc"&gt;.blue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;...styling&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What do you think the specificity is here? I think you got this by now... because it's "0-1-1"!&lt;/p&gt;

&lt;h3&gt;
  
  
  Intermediate examples
&lt;/h3&gt;

&lt;p&gt;We covered the basics so now let's look at some more realistic examples of how we would have written our rule sets and see what styling would be applied in the end. This can get quite difficult the more selectors you have, but you got this!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="nf"&gt;#title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="nf"&gt;#title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, which one would get applied? Try it yourself and see if you're right. Here's a &lt;a href="https://codepen.io/duncanteege/pen/BaOVeep"&gt;codepen&lt;/a&gt; to see the result. SPOILER ALERT: The specificity is "1-0-2" vs. "1-0-1". So the header &lt;code&gt;h1#title&lt;/code&gt; styling would be applied.&lt;/p&gt;

&lt;p&gt;This is pretty fun; let's look at one more example before wrapping it up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;fieldset&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="nf"&gt;#max&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nf"&gt;#max&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, would the text be red or blue? I'm not going to give you the answer this time... I will give you the link to a codepen, though! But before clicking on it and seeing the result, try to figure it out yourself! This is the &lt;a href="https://codepen.io/duncanteege/pen/WNgyqeZ"&gt;codepen&lt;/a&gt; for the example above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Specificity is quite difficult once you have loads of selectors in your production application. We didn't cover all the different types of examples, but if you follow the explanation given, you should get very far! There are certain tools out there that calculate the specificity for you, but I recommend getting the hang of this yourself. Practice it a bit more if you need to. It's definitely a decent skill to have in your toolbelt!&lt;/p&gt;

&lt;p&gt;Did you enjoy this article and want to read more from me? Follow me on dev.to or subscribe to my newsletter at &lt;a href="//duncanteege.com/#newsletter"&gt;my website&lt;/a&gt;! &lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to create a free email subscription form in NextJS, Netlify and MailerLite</title>
      <dc:creator>Duncan Teege</dc:creator>
      <pubDate>Wed, 08 Mar 2023 21:53:42 +0000</pubDate>
      <link>https://dev.to/duncanteege/how-to-create-an-email-subscription-form-in-nextjs-netlify-and-mailerlite-41mc</link>
      <guid>https://dev.to/duncanteege/how-to-create-an-email-subscription-form-in-nextjs-netlify-and-mailerlite-41mc</guid>
      <description>&lt;p&gt;For the past months I have thought multiple times about starting my own blog and creating content for social media. Something which always bothered me was the fact that I did not know how to create an emailing list even though I knew having one is very valuable! I will share with you the end result of what I am currently using on my blog, &lt;a href="//duncanteege.com"&gt;duncanteege.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Important money saving tip
&lt;/h2&gt;

&lt;p&gt;There are many ways to go about creating an email subscription list using a form. One of those ways is by using the functionality of writing your own endpoints in NextJS and using that to communicate to an email service like MailerLite. The downside is that this will make use of Node because of you defining an API route. This in itself definitely is not a downside, however having to host this might be a potential downside as it could bring extra costs. I first chose to go this route and hosted my website on DigitalOcean on an app platform. They gave me estimated costs of $5 a month just for hosting a static website with an endpoint! I thought “Nah, gotta be a different way right?”... and there is!&lt;/p&gt;

&lt;h2&gt;
  
  
  Netlify Forms
&lt;/h2&gt;

&lt;p&gt;It’s free! Netlify proudly presents the Netlify Forms functionality. They allow you up to 100 form submissions per site per month in their free “starter” tier. This is very generous and this is one of the many things why I love Netlify. (I am not sponsored, just amazed at what they offer 🙂) It must be hard to implement the form if it is free… right?&lt;/p&gt;

&lt;p&gt;Nope. It is ridiculously easy. All you have to do is add a simple attribute &lt;code&gt;netlify&lt;/code&gt; to your form. Yes it is that simple! What happens is that Netlify bots find the attribute by inspecting the HTML of your site before it is published. This means there is no other API call needed! Something to note is that using Netlify Forms means you have to host your website on Netlify.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the form look like in NextJS
&lt;/h2&gt;

&lt;p&gt;Let’s get dirty with some code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"subscribe"&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt;
  &lt;span class="na"&gt;data-netlify&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
  &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formContainer&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputGroup&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;htmlFor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;subscriberName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;
        &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"What is your first name?"&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setSubscriberName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputContainer&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;htmlFor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;subscriberEmail&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"On what email can I reach you?"&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setSubscriberEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SubmitButton&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Subscribe"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the form I use on my blog duncanteege.com. Note how there’s just a simple data attribute to notify Netlify bots that I want to make use of Netlify Forms? Besides that, the form just looks like a normal HTML form in React.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not reload or navigate to a new page
&lt;/h2&gt;

&lt;p&gt;Standard behaviour of using Netlify Forms is that it navigates you to a different page when submitting. I did not want this on my website. I wanted users to submit and then see the subscribe block change, but not a whole page refresh. Luckily they had a very nice example in their documentation where they explain how to use &lt;code&gt;fetch&lt;/code&gt; to POST to the website so you could change based on the response of the request. This code looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/x-www-form-urlencoded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;URLSearchParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="nx"&gt;setFormState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FormState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SUCCESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;setFormState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FormState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is not super exciting, but this cancels the page refresh and enables me to act on state changes based on the response of the request! This code runs on the &lt;code&gt;onSubmit&lt;/code&gt; of my form. I handle the form status in my own state so I can act upon changes of this state.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do in MailerLite
&lt;/h2&gt;

&lt;p&gt;There are many email services out there. I did some research and it looked like MailerLite was the best option for me. It offered, just like Netlify, a very generous free tier. It is free for up to 1000 subscribers. Next to this, you can send up to 12.000 emails a month in the free tier! That’s… like 12.000 emails a month! Holy smokes.&lt;/p&gt;

&lt;p&gt;Before we look at how to hook it all together, let us prepare the necessary keys we need to create a successful request to our email service. I will show you what you need to do in MailerLite, but feel free to skip the next paragraph if you do not use MailerLite.&lt;/p&gt;

&lt;p&gt;In MailerLite there is a menu item called “Integrations”. When you click on this item, you will see a page with possible integrations you could use with MailerLite. Quite an impressive list, but we’re interested in the “API” functionality as we want to call the API from our Netlify functions. More about Netlify functions later. Click on “use” and generate an API token. Make sure to save this token (but don’t commit it to your repo, store it in your .env file). Something you should also take note of is the header they want you to send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content-Type: application/json
Accept: application/json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the base url is &lt;code&gt;https://connect.mailerlite.com/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Cool, but how do we actually make use of this api? This is where Netlify Functions comes in clutch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Netlify Functions
&lt;/h2&gt;

&lt;p&gt;So we use Netlify Forms to submit our forms. Our submits end up in Netlify form submissions. We could manually type these submissions into MailerLite… but we’re developers right? Manual work is not for us. Luckily Netlify also offers Netlify Functions! Again Netlify is generous by offering 125.000 invocations per month in the “starter” tier. I mean… what? That’s an insane amount. But how do we use it with our form submissions?&lt;/p&gt;

&lt;p&gt;This sounds like we should listen to some kind of event or trigger. If we look at the documentation, it states that there are a couple of events we could listen to… including &lt;code&gt;submission-created&lt;/code&gt;. Hold up! That’s what we need! So how do we use this?&lt;/p&gt;

&lt;p&gt;Netlify wants you to create a specific folder for serverless functions. This folder lives in the root level of your project, the same level as &lt;code&gt;src&lt;/code&gt; if you are also doing this in NextJS. This folder is called &lt;code&gt;netlify&lt;/code&gt;. In this folder you create another folder called &lt;code&gt;functions&lt;/code&gt;. This is where your serverless functions will live. In order to listen to the &lt;code&gt;submission-created&lt;/code&gt; event, we create a file called &lt;code&gt;submission-created.ts&lt;/code&gt; (to use TypeScript) in the &lt;code&gt;functions&lt;/code&gt; folder. In this folder they expect an async function called &lt;code&gt;handler&lt;/code&gt;. In this function you can get the body of the POST request from the form and handle it the way you need it to handle. This is what the handler could look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MAILERLITE_PRODUCTION_API_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MAILERLITE_PRODUCTION_BASE_API_URL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GROUP_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MAILERLITE_PRODUCTION_NEWSLETTER_GROUP_ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/subscribers`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;GROUP_ID&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;


  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;


  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Subscriber successfully created and added to group&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: as you can see I make use of environment variables. These environment variables should be added to your website in Netlify to make sure that the handler works. You can use environment variables in a .env file. They are defined like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MAILERLITE_PRODUCTION_API_KEY = “your-api-key-here”
MAILERLITE_PRODUCTION_BASE_API_URL = https://connect.mailerlite.com/api
MAILERLITE_PRODUCTION_NEWSLETTER_GROUP_ID = “your-group-id-here”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above of the handler you can also see I create a data object with all the data I want to send to MailerLite. Since I also directly want to add the new subscribers to a specific newsletter group, I add that to my data object as well. It is important to remember that in order for the serverless function to work, the project actually needs to be deployed as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This turned out to be quite a long blog post, but all in all it is relatively easy to set up. There are a couple of steps you need to take in order to successfully create your own form without paying for a Node server with an API route if you are just starting out. Netlify offers a lot of features and we made use of the very generous starter tier of their plans! Oh and… I’m not sponsored by Netlify or MailerLite. Just a big fan of their services.&lt;/p&gt;

&lt;p&gt;If this post helped you and you want more of these posts, consider subscribing to &lt;a href="https://duncanteege.com/blog/how-to-create-an-email-subscription-form-in-nextjs-netlify-and-mailerlite#newsletter"&gt;my newsletter&lt;/a&gt;! I'll share quality content once a month, no spam.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>nextjs</category>
      <category>netlify</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why I am building in public</title>
      <dc:creator>Duncan Teege</dc:creator>
      <pubDate>Wed, 08 Mar 2023 18:59:00 +0000</pubDate>
      <link>https://dev.to/duncanteege/why-i-am-building-in-public-3mbo</link>
      <guid>https://dev.to/duncanteege/why-i-am-building-in-public-3mbo</guid>
      <description>&lt;p&gt;Before you read the entire blog post, I want you to know that this is mostly a brain dump. Alright, let’s get into it. I’ve been talking to my friends about building my own blog and using it as my own learning platform to dive into new challenges head first. While doing this, I want to share my thoughts, learnings and adventure in said blog posts. But… why would anyone be vulnerable and share their progress to the world?&lt;/p&gt;

&lt;p&gt;Well, for me there are many reasons. The first thing is that it’s a personal learning goal for me to stop waiting around until things are perfect before it can be shared. What is perfect anyways? Maybe that’s worth another blog post. The thing is that I tried creating projects perfectly. It had to start with a perfect schedule. It had to have a specific goal. It had to have absolutely zero bugs whatsoever. If you are familiar with programming, we all know that bug free code is something we all wish to achieve or even see in real life, but it’s a myth. Nothing can be perfect and neither will my blog (or even this blog post) be! I have to deal with this imperfect thing in my own way and one of those ways is writing this!&lt;/p&gt;

&lt;p&gt;Next to this, building in public allows for instant communication regarding the subjects that are being shared. If I’m writing a blog post on a particular subject and someone else has a different view on it, it can be discussed. This is a very interesting thing to me because it also allows a community to be built around the subjects I’m talking about. Let’s take the &lt;a href="https://duncanteege.com/blog/what-tech-stack-is-this-blog-using"&gt;blogpost&lt;/a&gt; I wrote about how I built my own blog. If someone took a different approach for building their blog and wants to share that, I’d totally encourage that! I love hearing about other people’s procedures and it almost always has a hidden lesson in it somewhere for you to take along.&lt;/p&gt;

&lt;p&gt;Another thing is that I’m planning to also be active on several social media accounts. By actively sharing my learnings on my own website, I always have a place to direct people too. I already mentioned the community part, but building a community is something I aspire to do as well. I think it would be a lot of fun to help each other get better at programming and build awesome things (in public!). If you want to get updated on my latest blogpost, feel free to subscribe to my newsletter. I send this email monthly and it consists of a couple blog post which you might find interesting. When I start posting videos on social media, I'll make sure that these will be included in the newsletter as well!&lt;/p&gt;

&lt;p&gt;By writing about my process and my goals (alongside of the many programming / development blog posts), I’m hoping to inspire those who’ve been waiting on the sidelines for too long too. Those who are afraid of taking steps for the sake of failing, being too successful (yes I’ve said that I'm afraid of it being too successful too!) or just the unknown in general. Let’s start doing what we want to do and start doing it now. I’m building my blog in public and writing about my progress. Why? Because starting is already difficult… but starting with an audience looking at what you’re doing? Now you’re committed and you have the ability to improve because of feedback!&lt;/p&gt;

&lt;p&gt;However let's not get ahead of ourselves. The best thing about starting is that you've just taken the hardest step. The only thing you need to do now is... keep going at it! As long as you're having fun, I don't think continuing will be very difficult.&lt;/p&gt;

&lt;p&gt;That's it for now. I will be writing a lot more posts and I can't wait to publish my next articles, but for now... feel free to view &lt;a href="https://duncanteege.com/"&gt;my website&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>motivation</category>
      <category>watercooler</category>
      <category>writing</category>
      <category>devjournal</category>
    </item>
  </channel>
</rss>
